From ff36f5e409707ada66506eefd4ac0a396cb28055 Mon Sep 17 00:00:00 2001 From: Christian Mauderer Date: Wed, 30 May 2018 14:27:35 +0200 Subject: Import ipsec-tools 0.8.2. Import unchanged ipsec-tools sources in the release version 0.8.2. The homepage of ipsec-tools is http://ipsec-tools.sourceforge.net/. The sources can be obtained from there. --- ipsec-tools/ChangeLog | 1931 +++ ipsec-tools/ChangeLog.old | 2626 +++ ipsec-tools/Makefile.am | 18 + ipsec-tools/Makefile.in | 836 + ipsec-tools/NEWS | 173 + ipsec-tools/README | 38 + ipsec-tools/aclocal.m4 | 9755 +++++++++++ ipsec-tools/acracoon.m4 | 195 + ipsec-tools/bootstrap | 21 + ipsec-tools/compile | 347 + ipsec-tools/config.guess | 1522 ++ ipsec-tools/config.h.in | 270 + ipsec-tools/config.sub | 1766 ++ ipsec-tools/configure | 17373 +++++++++++++++++++ ipsec-tools/configure.ac | 825 + ipsec-tools/depcomp | 688 + ipsec-tools/install-sh | 527 + ipsec-tools/ltmain.sh | 9655 +++++++++++ ipsec-tools/missing | 331 + ipsec-tools/package_version.h.in | 5 + ipsec-tools/rpm/Makefile.am | 18 + ipsec-tools/rpm/Makefile.in | 632 + ipsec-tools/rpm/ipsec-tools.spec.in | 60 + ipsec-tools/rpm/suse/Makefile.am | 1 + ipsec-tools/rpm/suse/Makefile.in | 442 + ipsec-tools/rpm/suse/ipsec-tools.spec | 110 + ipsec-tools/rpm/suse/ipsec-tools.spec.in | 110 + ipsec-tools/rpm/suse/racoon.init | 168 + ipsec-tools/rpm/suse/sysconfig.racoon | 24 + ipsec-tools/src/Makefile.am | 3 + ipsec-tools/src/Makefile.in | 619 + ipsec-tools/src/include-glibc/Makefile.am | 14 + ipsec-tools/src/include-glibc/Makefile.in | 452 + ipsec-tools/src/include-glibc/glibc-bugs.h | 12 + ipsec-tools/src/include-glibc/net/pfkeyv2.h | 75 + ipsec-tools/src/include-glibc/netinet/ipsec.h | 4 + ipsec-tools/src/include-glibc/sys/queue.h | 454 + ipsec-tools/src/libipsec/Makefile.am | 39 + ipsec-tools/src/libipsec/Makefile.in | 794 + ipsec-tools/src/libipsec/ipsec_dump_policy.c | 421 + ipsec-tools/src/libipsec/ipsec_get_policylen.c | 54 + ipsec-tools/src/libipsec/ipsec_set_policy.3 | 310 + ipsec-tools/src/libipsec/ipsec_strerror.3 | 88 + ipsec-tools/src/libipsec/ipsec_strerror.c | 96 + ipsec-tools/src/libipsec/ipsec_strerror.h | 73 + ipsec-tools/src/libipsec/key_debug.c | 899 + ipsec-tools/src/libipsec/libpfkey.h | 238 + ipsec-tools/src/libipsec/pfkey.c | 2674 +++ ipsec-tools/src/libipsec/pfkey_dump.c | 825 + ipsec-tools/src/libipsec/policy_parse.c | 2279 +++ ipsec-tools/src/libipsec/policy_parse.h | 125 + ipsec-tools/src/libipsec/policy_parse.y | 634 + ipsec-tools/src/libipsec/policy_token.c | 2075 +++ ipsec-tools/src/libipsec/policy_token.l | 192 + ipsec-tools/src/libipsec/test-policy.c | 332 + ipsec-tools/src/racoon/Makefile.am | 129 + ipsec-tools/src/racoon/Makefile.in | 1494 ++ ipsec-tools/src/racoon/TODO | 131 + ipsec-tools/src/racoon/admin.c | 775 + ipsec-tools/src/racoon/admin.h | 129 + ipsec-tools/src/racoon/admin_var.h | 40 + ipsec-tools/src/racoon/algorithm.c | 957 + ipsec-tools/src/racoon/algorithm.h | 216 + ipsec-tools/src/racoon/backupsa.c | 469 + ipsec-tools/src/racoon/backupsa.h | 41 + ipsec-tools/src/racoon/cfparse.c | 5871 +++++++ ipsec-tools/src/racoon/cfparse.h | 434 + ipsec-tools/src/racoon/cfparse.y | 2841 +++ ipsec-tools/src/racoon/cfparse_proto.h | 42 + ipsec-tools/src/racoon/cftoken.c | 4836 ++++++ ipsec-tools/src/racoon/cftoken.l | 807 + ipsec-tools/src/racoon/cftoken_proto.h | 48 + ipsec-tools/src/racoon/contrib/sp.pl | 21 + ipsec-tools/src/racoon/crypto_openssl.c | 2586 +++ ipsec-tools/src/racoon/crypto_openssl.h | 233 + ipsec-tools/src/racoon/debug.h | 42 + ipsec-tools/src/racoon/debugrm.h | 102 + ipsec-tools/src/racoon/dhgroup.h | 205 + ipsec-tools/src/racoon/dnssec.c | 137 + ipsec-tools/src/racoon/dnssec.h | 39 + ipsec-tools/src/racoon/doc/FAQ | 114 + ipsec-tools/src/racoon/doc/README.certificate | 1 + ipsec-tools/src/racoon/doc/README.gssapi | 106 + ipsec-tools/src/racoon/doc/README.plainrsa | 109 + ipsec-tools/src/racoon/doc/README.privsep | 152 + ipsec-tools/src/racoon/dump.h | 41 + ipsec-tools/src/racoon/eaytest.c | 1069 ++ ipsec-tools/src/racoon/evt.c | 399 + ipsec-tools/src/racoon/evt.h | 146 + ipsec-tools/src/racoon/gcmalloc.h | 127 + ipsec-tools/src/racoon/genlist.c | 174 + ipsec-tools/src/racoon/genlist.h | 82 + ipsec-tools/src/racoon/getcertsbyname.c | 418 + ipsec-tools/src/racoon/gnuc.h | 46 + ipsec-tools/src/racoon/grabmyaddr.c | 881 + ipsec-tools/src/racoon/grabmyaddr.h | 48 + ipsec-tools/src/racoon/gssapi.c | 749 + ipsec-tools/src/racoon/gssapi.h | 91 + ipsec-tools/src/racoon/handler.c | 1583 ++ ipsec-tools/src/racoon/handler.h | 538 + ipsec-tools/src/racoon/ipsec_doi.c | 4796 +++++ ipsec-tools/src/racoon/ipsec_doi.h | 255 + ipsec-tools/src/racoon/isakmp.c | 3698 ++++ ipsec-tools/src/racoon/isakmp.h | 425 + ipsec-tools/src/racoon/isakmp_agg.c | 1451 ++ ipsec-tools/src/racoon/isakmp_agg.h | 46 + ipsec-tools/src/racoon/isakmp_base.c | 1394 ++ ipsec-tools/src/racoon/isakmp_base.h | 48 + ipsec-tools/src/racoon/isakmp_cfg.c | 2193 +++ ipsec-tools/src/racoon/isakmp_cfg.h | 222 + ipsec-tools/src/racoon/isakmp_frag.c | 356 + ipsec-tools/src/racoon/isakmp_frag.h | 58 + ipsec-tools/src/racoon/isakmp_ident.c | 1900 ++ ipsec-tools/src/racoon/isakmp_ident.h | 52 + ipsec-tools/src/racoon/isakmp_inf.c | 1605 ++ ipsec-tools/src/racoon/isakmp_inf.h | 61 + ipsec-tools/src/racoon/isakmp_newg.c | 232 + ipsec-tools/src/racoon/isakmp_newg.h | 39 + ipsec-tools/src/racoon/isakmp_quick.c | 2605 +++ ipsec-tools/src/racoon/isakmp_quick.h | 50 + ipsec-tools/src/racoon/isakmp_unity.c | 422 + ipsec-tools/src/racoon/isakmp_unity.h | 74 + ipsec-tools/src/racoon/isakmp_var.h | 144 + ipsec-tools/src/racoon/isakmp_xauth.c | 1809 ++ ipsec-tools/src/racoon/isakmp_xauth.h | 182 + ipsec-tools/src/racoon/kmpstat.c | 233 + ipsec-tools/src/racoon/localconf.c | 358 + ipsec-tools/src/racoon/localconf.h | 132 + ipsec-tools/src/racoon/logger.c | 262 + ipsec-tools/src/racoon/logger.h | 53 + ipsec-tools/src/racoon/main.c | 349 + ipsec-tools/src/racoon/misc.c | 182 + ipsec-tools/src/racoon/misc.h | 78 + .../racoon/missing/crypto/rijndael/boxes-fst.dat | 957 + .../missing/crypto/rijndael/rijndael-alg-fst.c | 496 + .../missing/crypto/rijndael/rijndael-alg-fst.h | 35 + .../missing/crypto/rijndael/rijndael-api-fst.c | 494 + .../missing/crypto/rijndael/rijndael-api-fst.h | 105 + .../src/racoon/missing/crypto/rijndael/rijndael.h | 5 + .../missing/crypto/rijndael/rijndael_local.h | 12 + ipsec-tools/src/racoon/missing/crypto/sha2/sha2.c | 1199 ++ ipsec-tools/src/racoon/missing/crypto/sha2/sha2.h | 161 + ipsec-tools/src/racoon/nattraversal.c | 553 + ipsec-tools/src/racoon/nattraversal.h | 99 + ipsec-tools/src/racoon/netdb_dnssec.h | 74 + ipsec-tools/src/racoon/oakley.c | 3211 ++++ ipsec-tools/src/racoon/oakley.h | 218 + ipsec-tools/src/racoon/pfkey.c | 3993 +++++ ipsec-tools/src/racoon/pfkey.h | 75 + ipsec-tools/src/racoon/plainrsa-gen.8 | 138 + ipsec-tools/src/racoon/plainrsa-gen.c | 307 + ipsec-tools/src/racoon/plog.c | 295 + ipsec-tools/src/racoon/plog.h | 82 + ipsec-tools/src/racoon/policy.c | 498 + ipsec-tools/src/racoon/policy.h | 169 + ipsec-tools/src/racoon/privsep.c | 1807 ++ ipsec-tools/src/racoon/privsep.h | 76 + ipsec-tools/src/racoon/proposal.c | 1290 ++ ipsec-tools/src/racoon/proposal.h | 214 + ipsec-tools/src/racoon/prsa_par.c | 2062 +++ ipsec-tools/src/racoon/prsa_par.h | 134 + ipsec-tools/src/racoon/prsa_par.y | 363 + ipsec-tools/src/racoon/prsa_tok.c | 2139 +++ ipsec-tools/src/racoon/prsa_tok.l | 89 + ipsec-tools/src/racoon/racoon.8 | 157 + ipsec-tools/src/racoon/racoon.conf.5 | 1546 ++ ipsec-tools/src/racoon/racoonctl.8 | 228 + ipsec-tools/src/racoon/racoonctl.c | 1529 ++ ipsec-tools/src/racoon/racoonctl.h | 53 + ipsec-tools/src/racoon/remoteconf.c | 1248 ++ ipsec-tools/src/racoon/remoteconf.h | 243 + ipsec-tools/src/racoon/rsalist.c | 275 + ipsec-tools/src/racoon/rsalist.h | 67 + ipsec-tools/src/racoon/safefile.c | 93 + ipsec-tools/src/racoon/safefile.h | 39 + ipsec-tools/src/racoon/sainfo.c | 413 + ipsec-tools/src/racoon/sainfo.h | 92 + ipsec-tools/src/racoon/samples/psk.txt.in | 21 + ipsec-tools/src/racoon/samples/psk.txt.sample | 10 + ipsec-tools/src/racoon/samples/racoon.conf.in | 121 + ipsec-tools/src/racoon/samples/racoon.conf.sample | 61 + .../src/racoon/samples/racoon.conf.sample-gssapi | 43 + .../src/racoon/samples/racoon.conf.sample-inherit | 55 + .../src/racoon/samples/racoon.conf.sample-natt | 97 + .../src/racoon/samples/racoon.conf.sample-plainrsa | 46 + ipsec-tools/src/racoon/samples/roadwarrior/README | 67 + .../samples/roadwarrior/client/phase1-down.sh | 78 + .../racoon/samples/roadwarrior/client/phase1-up.sh | 80 + .../racoon/samples/roadwarrior/client/racoon.conf | 33 + .../racoon/samples/roadwarrior/server/racoon.conf | 42 + .../samples/roadwarrior/server/racoon.conf-radius | 42 + ipsec-tools/src/racoon/schedule.c | 311 + ipsec-tools/src/racoon/schedule.h | 99 + ipsec-tools/src/racoon/security.c | 265 + ipsec-tools/src/racoon/session.c | 540 + ipsec-tools/src/racoon/session.h | 43 + ipsec-tools/src/racoon/sockmisc.c | 1006 ++ ipsec-tools/src/racoon/sockmisc.h | 97 + ipsec-tools/src/racoon/stats.pl | 15 + ipsec-tools/src/racoon/str2val.c | 126 + ipsec-tools/src/racoon/str2val.h | 40 + ipsec-tools/src/racoon/strnames.c | 1036 ++ ipsec-tools/src/racoon/strnames.h | 80 + ipsec-tools/src/racoon/throttle.c | 149 + ipsec-tools/src/racoon/throttle.h | 53 + ipsec-tools/src/racoon/var.h | 107 + ipsec-tools/src/racoon/vendorid.c | 320 + ipsec-tools/src/racoon/vendorid.h | 105 + ipsec-tools/src/racoon/vmbuf.c | 137 + ipsec-tools/src/racoon/vmbuf.h | 73 + ipsec-tools/src/setkey/Makefile.am | 22 + ipsec-tools/src/setkey/Makefile.in | 760 + ipsec-tools/src/setkey/extern.h | 33 + ipsec-tools/src/setkey/parse.c | 3610 ++++ ipsec-tools/src/setkey/parse.h | 201 + ipsec-tools/src/setkey/parse.y | 1670 ++ ipsec-tools/src/setkey/sample-policy01.cf | 20 + ipsec-tools/src/setkey/sample-policy02.cf | 43 + ipsec-tools/src/setkey/sample.cf | 217 + ipsec-tools/src/setkey/scriptdump.pl | 55 + ipsec-tools/src/setkey/setkey.8 | 837 + ipsec-tools/src/setkey/setkey.c | 1062 ++ ipsec-tools/src/setkey/test-pfkey.c | 590 + ipsec-tools/src/setkey/token.c | 2910 ++++ ipsec-tools/src/setkey/token.l | 359 + ipsec-tools/src/setkey/vchar.h | 42 + ipsec-tools/test-driver | 127 + ipsec-tools/ylwrap | 226 + 228 files changed, 165026 insertions(+) create mode 100644 ipsec-tools/ChangeLog create mode 100644 ipsec-tools/ChangeLog.old create mode 100644 ipsec-tools/Makefile.am create mode 100644 ipsec-tools/Makefile.in create mode 100644 ipsec-tools/NEWS create mode 100644 ipsec-tools/README create mode 100644 ipsec-tools/aclocal.m4 create mode 100644 ipsec-tools/acracoon.m4 create mode 100755 ipsec-tools/bootstrap create mode 100755 ipsec-tools/compile create mode 100755 ipsec-tools/config.guess create mode 100644 ipsec-tools/config.h.in create mode 100755 ipsec-tools/config.sub create mode 100755 ipsec-tools/configure create mode 100644 ipsec-tools/configure.ac create mode 100755 ipsec-tools/depcomp create mode 100755 ipsec-tools/install-sh create mode 100644 ipsec-tools/ltmain.sh create mode 100755 ipsec-tools/missing create mode 100644 ipsec-tools/package_version.h.in create mode 100644 ipsec-tools/rpm/Makefile.am create mode 100644 ipsec-tools/rpm/Makefile.in create mode 100644 ipsec-tools/rpm/ipsec-tools.spec.in create mode 100644 ipsec-tools/rpm/suse/Makefile.am create mode 100644 ipsec-tools/rpm/suse/Makefile.in create mode 100644 ipsec-tools/rpm/suse/ipsec-tools.spec create mode 100644 ipsec-tools/rpm/suse/ipsec-tools.spec.in create mode 100644 ipsec-tools/rpm/suse/racoon.init create mode 100644 ipsec-tools/rpm/suse/sysconfig.racoon create mode 100644 ipsec-tools/src/Makefile.am create mode 100644 ipsec-tools/src/Makefile.in create mode 100644 ipsec-tools/src/include-glibc/Makefile.am create mode 100644 ipsec-tools/src/include-glibc/Makefile.in create mode 100644 ipsec-tools/src/include-glibc/glibc-bugs.h create mode 100644 ipsec-tools/src/include-glibc/net/pfkeyv2.h create mode 100644 ipsec-tools/src/include-glibc/netinet/ipsec.h create mode 100644 ipsec-tools/src/include-glibc/sys/queue.h create mode 100644 ipsec-tools/src/libipsec/Makefile.am create mode 100644 ipsec-tools/src/libipsec/Makefile.in create mode 100644 ipsec-tools/src/libipsec/ipsec_dump_policy.c create mode 100644 ipsec-tools/src/libipsec/ipsec_get_policylen.c create mode 100644 ipsec-tools/src/libipsec/ipsec_set_policy.3 create mode 100644 ipsec-tools/src/libipsec/ipsec_strerror.3 create mode 100644 ipsec-tools/src/libipsec/ipsec_strerror.c create mode 100644 ipsec-tools/src/libipsec/ipsec_strerror.h create mode 100644 ipsec-tools/src/libipsec/key_debug.c create mode 100644 ipsec-tools/src/libipsec/libpfkey.h create mode 100644 ipsec-tools/src/libipsec/pfkey.c create mode 100644 ipsec-tools/src/libipsec/pfkey_dump.c create mode 100644 ipsec-tools/src/libipsec/policy_parse.c create mode 100644 ipsec-tools/src/libipsec/policy_parse.h create mode 100644 ipsec-tools/src/libipsec/policy_parse.y create mode 100644 ipsec-tools/src/libipsec/policy_token.c create mode 100644 ipsec-tools/src/libipsec/policy_token.l create mode 100644 ipsec-tools/src/libipsec/test-policy.c create mode 100644 ipsec-tools/src/racoon/Makefile.am create mode 100644 ipsec-tools/src/racoon/Makefile.in create mode 100644 ipsec-tools/src/racoon/TODO create mode 100644 ipsec-tools/src/racoon/admin.c create mode 100644 ipsec-tools/src/racoon/admin.h create mode 100644 ipsec-tools/src/racoon/admin_var.h create mode 100644 ipsec-tools/src/racoon/algorithm.c create mode 100644 ipsec-tools/src/racoon/algorithm.h create mode 100644 ipsec-tools/src/racoon/backupsa.c create mode 100644 ipsec-tools/src/racoon/backupsa.h create mode 100644 ipsec-tools/src/racoon/cfparse.c create mode 100644 ipsec-tools/src/racoon/cfparse.h create mode 100644 ipsec-tools/src/racoon/cfparse.y create mode 100644 ipsec-tools/src/racoon/cfparse_proto.h create mode 100644 ipsec-tools/src/racoon/cftoken.c create mode 100644 ipsec-tools/src/racoon/cftoken.l create mode 100644 ipsec-tools/src/racoon/cftoken_proto.h create mode 100644 ipsec-tools/src/racoon/contrib/sp.pl create mode 100644 ipsec-tools/src/racoon/crypto_openssl.c create mode 100644 ipsec-tools/src/racoon/crypto_openssl.h create mode 100644 ipsec-tools/src/racoon/debug.h create mode 100644 ipsec-tools/src/racoon/debugrm.h create mode 100644 ipsec-tools/src/racoon/dhgroup.h create mode 100644 ipsec-tools/src/racoon/dnssec.c create mode 100644 ipsec-tools/src/racoon/dnssec.h create mode 100644 ipsec-tools/src/racoon/doc/FAQ create mode 100644 ipsec-tools/src/racoon/doc/README.certificate create mode 100644 ipsec-tools/src/racoon/doc/README.gssapi create mode 100644 ipsec-tools/src/racoon/doc/README.plainrsa create mode 100644 ipsec-tools/src/racoon/doc/README.privsep create mode 100644 ipsec-tools/src/racoon/dump.h create mode 100644 ipsec-tools/src/racoon/eaytest.c create mode 100644 ipsec-tools/src/racoon/evt.c create mode 100644 ipsec-tools/src/racoon/evt.h create mode 100644 ipsec-tools/src/racoon/gcmalloc.h create mode 100644 ipsec-tools/src/racoon/genlist.c create mode 100644 ipsec-tools/src/racoon/genlist.h create mode 100644 ipsec-tools/src/racoon/getcertsbyname.c create mode 100644 ipsec-tools/src/racoon/gnuc.h create mode 100644 ipsec-tools/src/racoon/grabmyaddr.c create mode 100644 ipsec-tools/src/racoon/grabmyaddr.h create mode 100644 ipsec-tools/src/racoon/gssapi.c create mode 100644 ipsec-tools/src/racoon/gssapi.h create mode 100644 ipsec-tools/src/racoon/handler.c create mode 100644 ipsec-tools/src/racoon/handler.h create mode 100644 ipsec-tools/src/racoon/ipsec_doi.c create mode 100644 ipsec-tools/src/racoon/ipsec_doi.h create mode 100644 ipsec-tools/src/racoon/isakmp.c create mode 100644 ipsec-tools/src/racoon/isakmp.h create mode 100644 ipsec-tools/src/racoon/isakmp_agg.c create mode 100644 ipsec-tools/src/racoon/isakmp_agg.h create mode 100644 ipsec-tools/src/racoon/isakmp_base.c create mode 100644 ipsec-tools/src/racoon/isakmp_base.h create mode 100644 ipsec-tools/src/racoon/isakmp_cfg.c create mode 100644 ipsec-tools/src/racoon/isakmp_cfg.h create mode 100644 ipsec-tools/src/racoon/isakmp_frag.c create mode 100644 ipsec-tools/src/racoon/isakmp_frag.h create mode 100644 ipsec-tools/src/racoon/isakmp_ident.c create mode 100644 ipsec-tools/src/racoon/isakmp_ident.h create mode 100644 ipsec-tools/src/racoon/isakmp_inf.c create mode 100644 ipsec-tools/src/racoon/isakmp_inf.h create mode 100644 ipsec-tools/src/racoon/isakmp_newg.c create mode 100644 ipsec-tools/src/racoon/isakmp_newg.h create mode 100644 ipsec-tools/src/racoon/isakmp_quick.c create mode 100644 ipsec-tools/src/racoon/isakmp_quick.h create mode 100644 ipsec-tools/src/racoon/isakmp_unity.c create mode 100644 ipsec-tools/src/racoon/isakmp_unity.h create mode 100644 ipsec-tools/src/racoon/isakmp_var.h create mode 100644 ipsec-tools/src/racoon/isakmp_xauth.c create mode 100644 ipsec-tools/src/racoon/isakmp_xauth.h create mode 100644 ipsec-tools/src/racoon/kmpstat.c create mode 100644 ipsec-tools/src/racoon/localconf.c create mode 100644 ipsec-tools/src/racoon/localconf.h create mode 100644 ipsec-tools/src/racoon/logger.c create mode 100644 ipsec-tools/src/racoon/logger.h create mode 100644 ipsec-tools/src/racoon/main.c create mode 100644 ipsec-tools/src/racoon/misc.c create mode 100644 ipsec-tools/src/racoon/misc.h create mode 100644 ipsec-tools/src/racoon/missing/crypto/rijndael/boxes-fst.dat create mode 100644 ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-alg-fst.c create mode 100644 ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-alg-fst.h create mode 100644 ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-api-fst.c create mode 100644 ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-api-fst.h create mode 100644 ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael.h create mode 100644 ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael_local.h create mode 100644 ipsec-tools/src/racoon/missing/crypto/sha2/sha2.c create mode 100644 ipsec-tools/src/racoon/missing/crypto/sha2/sha2.h create mode 100644 ipsec-tools/src/racoon/nattraversal.c create mode 100644 ipsec-tools/src/racoon/nattraversal.h create mode 100644 ipsec-tools/src/racoon/netdb_dnssec.h create mode 100644 ipsec-tools/src/racoon/oakley.c create mode 100644 ipsec-tools/src/racoon/oakley.h create mode 100644 ipsec-tools/src/racoon/pfkey.c create mode 100644 ipsec-tools/src/racoon/pfkey.h create mode 100644 ipsec-tools/src/racoon/plainrsa-gen.8 create mode 100644 ipsec-tools/src/racoon/plainrsa-gen.c create mode 100644 ipsec-tools/src/racoon/plog.c create mode 100644 ipsec-tools/src/racoon/plog.h create mode 100644 ipsec-tools/src/racoon/policy.c create mode 100644 ipsec-tools/src/racoon/policy.h create mode 100644 ipsec-tools/src/racoon/privsep.c create mode 100644 ipsec-tools/src/racoon/privsep.h create mode 100644 ipsec-tools/src/racoon/proposal.c create mode 100644 ipsec-tools/src/racoon/proposal.h create mode 100644 ipsec-tools/src/racoon/prsa_par.c create mode 100644 ipsec-tools/src/racoon/prsa_par.h create mode 100644 ipsec-tools/src/racoon/prsa_par.y create mode 100644 ipsec-tools/src/racoon/prsa_tok.c create mode 100644 ipsec-tools/src/racoon/prsa_tok.l create mode 100644 ipsec-tools/src/racoon/racoon.8 create mode 100644 ipsec-tools/src/racoon/racoon.conf.5 create mode 100644 ipsec-tools/src/racoon/racoonctl.8 create mode 100644 ipsec-tools/src/racoon/racoonctl.c create mode 100644 ipsec-tools/src/racoon/racoonctl.h create mode 100644 ipsec-tools/src/racoon/remoteconf.c create mode 100644 ipsec-tools/src/racoon/remoteconf.h create mode 100644 ipsec-tools/src/racoon/rsalist.c create mode 100644 ipsec-tools/src/racoon/rsalist.h create mode 100644 ipsec-tools/src/racoon/safefile.c create mode 100644 ipsec-tools/src/racoon/safefile.h create mode 100644 ipsec-tools/src/racoon/sainfo.c create mode 100644 ipsec-tools/src/racoon/sainfo.h create mode 100644 ipsec-tools/src/racoon/samples/psk.txt.in create mode 100644 ipsec-tools/src/racoon/samples/psk.txt.sample create mode 100644 ipsec-tools/src/racoon/samples/racoon.conf.in create mode 100644 ipsec-tools/src/racoon/samples/racoon.conf.sample create mode 100644 ipsec-tools/src/racoon/samples/racoon.conf.sample-gssapi create mode 100644 ipsec-tools/src/racoon/samples/racoon.conf.sample-inherit create mode 100644 ipsec-tools/src/racoon/samples/racoon.conf.sample-natt create mode 100644 ipsec-tools/src/racoon/samples/racoon.conf.sample-plainrsa create mode 100644 ipsec-tools/src/racoon/samples/roadwarrior/README create mode 100755 ipsec-tools/src/racoon/samples/roadwarrior/client/phase1-down.sh create mode 100755 ipsec-tools/src/racoon/samples/roadwarrior/client/phase1-up.sh create mode 100644 ipsec-tools/src/racoon/samples/roadwarrior/client/racoon.conf create mode 100644 ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf create mode 100644 ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf-radius create mode 100644 ipsec-tools/src/racoon/schedule.c create mode 100644 ipsec-tools/src/racoon/schedule.h create mode 100644 ipsec-tools/src/racoon/security.c create mode 100644 ipsec-tools/src/racoon/session.c create mode 100644 ipsec-tools/src/racoon/session.h create mode 100644 ipsec-tools/src/racoon/sockmisc.c create mode 100644 ipsec-tools/src/racoon/sockmisc.h create mode 100644 ipsec-tools/src/racoon/stats.pl create mode 100644 ipsec-tools/src/racoon/str2val.c create mode 100644 ipsec-tools/src/racoon/str2val.h create mode 100644 ipsec-tools/src/racoon/strnames.c create mode 100644 ipsec-tools/src/racoon/strnames.h create mode 100644 ipsec-tools/src/racoon/throttle.c create mode 100644 ipsec-tools/src/racoon/throttle.h create mode 100644 ipsec-tools/src/racoon/var.h create mode 100644 ipsec-tools/src/racoon/vendorid.c create mode 100644 ipsec-tools/src/racoon/vendorid.h create mode 100644 ipsec-tools/src/racoon/vmbuf.c create mode 100644 ipsec-tools/src/racoon/vmbuf.h create mode 100644 ipsec-tools/src/setkey/Makefile.am create mode 100644 ipsec-tools/src/setkey/Makefile.in create mode 100644 ipsec-tools/src/setkey/extern.h create mode 100644 ipsec-tools/src/setkey/parse.c create mode 100644 ipsec-tools/src/setkey/parse.h create mode 100644 ipsec-tools/src/setkey/parse.y create mode 100644 ipsec-tools/src/setkey/sample-policy01.cf create mode 100644 ipsec-tools/src/setkey/sample-policy02.cf create mode 100644 ipsec-tools/src/setkey/sample.cf create mode 100644 ipsec-tools/src/setkey/scriptdump.pl create mode 100644 ipsec-tools/src/setkey/setkey.8 create mode 100644 ipsec-tools/src/setkey/setkey.c create mode 100644 ipsec-tools/src/setkey/test-pfkey.c create mode 100644 ipsec-tools/src/setkey/token.c create mode 100644 ipsec-tools/src/setkey/token.l create mode 100644 ipsec-tools/src/setkey/vchar.h create mode 100755 ipsec-tools/test-driver create mode 100755 ipsec-tools/ylwrap (limited to 'ipsec-tools') diff --git a/ipsec-tools/ChangeLog b/ipsec-tools/ChangeLog new file mode 100644 index 00000000..c31fc5f1 --- /dev/null +++ b/ipsec-tools/ChangeLog @@ -0,0 +1,1931 @@ +2013-07-12 Timo Teras + + * src/racoon/main.c: From Sven Vermeulen + : Moves ploginit() up, allowing logging + events from init_avc() to show up as well. + +2013-06-18 Timo Teras + + * src/racoon/ipsec_doi.c: From Paul Barker: Remove redundant memset + after calloc that caused compile failures with gcc 4.8 due to error: + argument to 'sizeof' in 'memset' call is the same expression as the + destination; did you mean to dereference. + +2013-06-03 Timo Teras + + * src/racoon/admin.c: From Alexander Sbitnev + : fix admin port establish-sa for + tunnel mode SAs. + +2013-05-23 Timo Teras + + * src/include-glibc/net/pfkeyv2.h: From Rainer Weikusat + : Fix SADB_X_EALG_CASTCBC + definition to use system definition (which differs at least on + Linux). + +2013-04-12 Timo Teras + + * src/racoon/isakmp_cfg.c: From Rainer Weikusat + : Do not send out illegal zero + length MODE_CFG attributes. + + * src/racoon/: grabmyaddr.c, isakmp_inf.c: Some logging + improvements. + +2013-02-05 Timo Teras + + * src/racoon/grabmyaddr.c: Fix source port selection + + * src/racoon/isakmp_xauth.c: From Ian West : Fix + double free of the radius info on config reload. + +2013-01-24 Timo Teras + + * src/racoon/isakmp_inf.c: Fix handling of deletion notification. + +2013-01-08 tag ipsec-tools-0_8_1 + +2013-01-08 Timo Teras + + * NEWS, configure.ac: ipsec-tools-0.8.1 + + * configure.ac: Fix errors from automake 1.13 + + * src/include-glibc/Makefile.am: Don't derefence the directory + symlink which we might be recreating. + +2012-12-24 Timo Teras + + * src/racoon/crypto_openssl.c: From Götz Babin-Ebell + : Smarter X.509 subject name compare. + + * configure.ac, src/racoon/crypto_openssl.c, + src/racoon/missing/crypto/sha2/sha2.c: From Götz Babin-Ebell + : Require OpenSSL 0.9.8s or higher + +2012-08-29 Timo Teras + + * src/racoon/isakmp_inf.c: From Roman Hoog Antink : + Accept DPD messages with cookies also in reversed order for + compatiblity. At least Cisco 836 running IOS 12.3(8)T does this. + + * src/racoon/oakley.c: From Roman Hoog Antink : add + remote's IP address to the "certificate not verified" error message. + + * src/racoon/oakley.c: From Roman Hoog Antink : do not + print unnecessary warning about non-verified certificate when using + raw plain-rsa. + + * src/racoon/isakmp.c: From Rainer Weikusat + : Release unused phase2 of + passive remotes after acquire. + + * src/racoon/isakmp.c: From Wolfgang Schmieder + : setup phase1 port properly. + + * src/racoon/: cfparse.y, cftoken.l, racoon.conf.5: Allow inherited + remote blocks without additional remote statements to be specified + in a simpler way. patch by Roman Hoog Antink + +2012-08-23 Timo Teras + + * src/racoon/crypto_openssl.c: From Nakano Takaharu: Fix bignum + memory allocation. + +2012-01-01 Timo Teras + + * src/racoon/isakmp_unity.c: From Rainer Weikusat + : Fix one byte too short memory + allocation in isakmp_unity.c:splitnet_list_2str(). + +2011-11-17 Yvan Vanhullebus + + * src/racoon/handler.c: fixed some crashes in LIST_FOREACH where + current element could be removed during the loop + +2011-11-14 Timo Teras + + * src/libipsec/pfkey.c: From Marcelo Leitner : + do not shrink pfkey socket buffers (if system default is larger than + what we want as minimum) + +2011-08-12 Timo Teras + + * src/racoon/privsep.c: Have privilege separation child process + exit if the parent exits. + + * Makefile.am: Create ChangeLog for proper CVS branch. + +2011-03-18 tag ipsec-tools-0_8_0 + +2011-03-18 Yvan Vanhullebus + + * configure.ac: Yes: 0.8.0 is out !!! + + * NEWS: updated News for 0.8 branch + +2011-03-17 Yvan Vanhullebus + + * src/racoon/oakley.c: fixed a memory leak in + oakley_append_rmconf_cr() while generating plist. patch by Roman + Hoog Antink + + * src/racoon/oakley.c: free name later, to avoid a memory use after + free in oakley_check_certid(). also give iph1->remote to some plog() + calls. patch by Roman Hoog Antink + + * src/racoon/oakley.c: fixed a memory leak in + oakley_check_certid(). patch by Roman Hoog Antink + +2011-03-15 Yvan Vanhullebus + + * src/racoon/: isakmp.c, isakmp_inf.c, pfkey.c: directly call + isakmp_ph1delete() instead of scheduling isakmp_ph1delete_stub(), as + it is useless an can lead to memory access after free + +2011-03-14 Timo Teras + + * src/racoon/: grabmyaddr.c, handler.c, isakmp.c, isakmp_inf.c, + isakmp_quick.c, nattraversal.c, pfkey.c, policy.c, sockmisc.c, + sockmisc.h, throttle.c: Explicitly compare return value of + cmpsaddr() against a return value define to make it more obvious + what is the intended action. One more return value is also added, to + fix comparison of security policy descriptors. Namely, getsp() + should not allow wildcard matching (as the comment says, it does + exact matching) - otherwise we get problems when kernel has generic + policy with no ports, and a second similar policy with ports. + +2011-03-14 Yvan Vanhullebus + + * src/racoon/: cfparse.y, isakmp_xauth.c, isakmp_xauth.h, + remoteconf.c, remoteconf.h, rsalist.c, rsalist.h: avoid some + memory leaks / free memory access when reloading conf and have + inherited config. patch from Roman Hoog Antink + + * src/racoon/handler.c: removed an useless comment + + * src/racoon/handler.c: check if we got RMCONF_ERR_MULTIPLE from + getrmconf_by_ph1() in revalidate_ph1tree_rmconf() + +2011-03-11 Yvan Vanhullebus + + * src/racoon/: handler.c, isakmp.c: directly delete a ph1 in + remove_ph1-) instead of scheduling it, to avoid (completely ?) a + race condition when reloading configuration + +2011-03-06 Timo Teras + + * src/racoon/privsep.c: Quiet a gcc warning when strict-aliasing + checks are enabled. Reported by Stephen Clark. + +2011-03-02 Yvan Vanhullebus + + * src/racoon/session.c: flush sainfo list when closing session. + patch by Roman Hoog Antink + + * src/racoon/: remoteconf.c, rsalist.c, rsalist.h: free rsa + structures when deleting a struct rmconf. patch by Roman Hoog Antink + + + * src/racoon/: cfparse.y, remoteconf.c, remoteconf.h: free spspec + when deleting a rmconf struct. patch by Roman Hoog Antink + + + * src/racoon/: remoteconf.c, session.c: fixed some memory leaks in + remoteconf. patch by Roman Hoog Antink + + * src/racoon/: cfparse.y, prsa_par.y: fixed some memory leaks + during configuration parsing. patch by Roman Hoog Antink + + +2011-03-01 Yvan Vanhullebus + + * src/racoon/: isakmp.c, pfkey.c: plog text fixes, patch from M E + Andersson + + * src/racoon/cfparse.y: reset yyerrorcount before doing parse + stuff. patch by Roman Hoog Antink + +2011-02-20 Timo Teras + + * src/racoon/oakley.c: From Roman Hoog Antink : Fix + memory leak when using plain RSA key authentication. + +2011-02-11 Timo Teras + + * src/racoon/plainrsa-gen.c: From Mats E Andersson + : Fix fprintf format specifier usage from + previous patch. + +2011-02-10 Timo Teras + + * src/racoon/plainrsa-gen.c: From Mats Erik Andersson + : Implement importing of RSA keys from PEM + files. + + * src/racoon/prsa_par.y: From M E Andersson + : Fix parsing of restricted RSA key + addresses. + +2011-02-02 Yvan Vanhullebus + + * src/racoon/: cftoken.l, isakmp.c, remoteconf.h, sainfo.c, + sainfo.h: store ph1id in an u_int32_t instead of a (signed)int. + Patch from Christophe Carre + +2011-01-28 Timo Teras + + * src/racoon/: sainfo.c, sainfo.h, session.c: From Roman Hoog + Antink : Clean up sainfo reloading: rename the + functions, and remove unneeded global variable. + + * src/racoon/: remoteconf.c, remoteconf.h, session.c: From Roman + Hoog Antink : Clean up rmconf reloading: rename the + functions, and remove unneeded global variable. + + * src/racoon/plog.c: From Roman Hoog Antink : Log + remote IP address if available (slightly modified by tteras) + +2011-01-22 Timo Teras + + * src/racoon/isakmp_inf.c: From Roman Hoog Antink : + Fixes a null pointer dereference that might occur after removing + peers from the config and then reloading. + +2011-01-20 Yvan Vanhullebus + + * src/libipsec/pfkey.c: fixed a typo, it will now compile when + KMADDRESS is defined. reported by Roman Hoog Antink (rha (at) + open.ch) + +2010-12-28 Timo Teras + + * src/racoon/handler.c: From Roman Hoog Antink : Fix + config reload to not delete too many phase 2 handles, because wrong + chain field is used when enumerating the handles. + +2010-12-16 gdt + + * src/racoon/oakley.c: When encountering a certificate where "ID + mismatched with ASN1 SubjectName", and verify_identifier is off, + don't raise an error. This makes the behavior match the man page. + + Patch sent for review long ago: + http://mail-index.netbsd.org/tech-security/2006/03/24/0000.html + with no negative feedback received to date. + +2010-12-14 Timo Teras + + * src/racoon/ipsec_doi.c: From Roman Hoog Antink : Fix + possible null derefence. + +2010-12-08 Timo Teras + + * src/racoon/admin.c: Use separate SA addresses for phase2's + created by admin command. The phase2 startup overwrites src/dst with + ISAKMP ports if they are zero and we don't want that to happen for + the SA ports. + +2010-12-08 joerg + + * src/libipsec/pfkey.c: ANSIfy + +2010-12-07 Timo Teras + + * src/racoon/isakmp_quick.c: Fix spacing and improve wording in + some log messages. + +2010-12-03 Timo Teras + + * src/libipsec/ipsec_dump_policy.c: Recognize direction for Linux + per-socket policies. + + * src/: libipsec/libpfkey.h, libipsec/pfkey_dump.c, setkey/parse.y, + setkey/setkey.8: Support GRE key as upper layer protocol + specifier (will be supported in Linux kernel 2.6.38). + + * src/racoon/grabmyaddr.c: Netlink deletion notification does not + guarentee actual address deletion: it might still exist on some + other interface. Make sure we do not unbind unless the address is + really gone. + +2010-11-17 Timo Teras + + * src/racoon/: handler.c, handler.h, isakmp.c, isakmp_inf.c: Fix my + previous patch to not call purge_remote() twice. Change the place + where purge_remote() is called. This fixes also a possible crash + from the same patch since ph1->remote can be NULL (when we are + responder and config is not yet selected). + +2010-11-12 Timo Teras + + * src/racoon/: admin.c, isakmp.c, isakmp_var.h, pfkey.c: + isakmp_post_acquire is now called from admin commands too, add a + flag so admin commands can be used to establish even passive links + on demand. + + * src/racoon/isakmp.c: Purge all IPsec-SA's if the last main + ISAKMP-SA for the node is deleted by remote request and the phase1 + rekeying is enabled (this will also trigger the new phase1_dead + script hook). + + * src/racoon/: handler.h, isakmp_inf.c: Improve DPD sequence checks + to allow any reply within valid sequence window to be proof of + livelyness. This can improves things if there's random packet + delays, or if racoon is not getting enough CPU time. + + * src/racoon/: admin.c, admin.h, kmpstat.c, racoonctl.c: Extern + admin protocol to allow reply packets to exceed 64kb. E.g SA dumps + with many established SAs can be easily over the limit. + +2010-10-22 Timo Teras + + * src/racoon/grabmyaddr.c: Change Linux Netlink address monitoring + to monitor local route changes. This works around a kernel bug, and + slightly improves behaviour on some special cases. + +2010-10-21 Timo Teras + + * src/racoon/: admin.c, evt.c, grabmyaddr.c, isakmp.c, pfkey.c, + session.c, session.h: Introduce priorities for file descriptor + polling mechanism and give priority to admin port. If admin port is + used by ISAKMP-SA hook scripts they should be preferred, other wise + heavy traffic can delay admin port requests considerably. This in + turn may cause renegotiation loop for ISAKMP-SA. This is mostly + useful for OpenNHRP setup, but can benefit other setups too. + + * src/racoon/: admin.c, handler.c, handler.h: Remove + initial-contact entry when all ISAKMP-SA are purged via adminport. + This will avoid stale security associations if some of the delete + notifications happens to get lost. + +2010-10-20 Timo Teras + + * src/racoon/crypto_openssl.c: Use high-level openssl EVP and HMAC + functions when possible: this allows openssl to perform hardware + acceleration if available. + + * src/racoon/: isakmp.c, isakmp_quick.c: Various improvements to + error log messages and a few additional error log messages to + improve diagnosing an error condition. + + * src/racoon/grabmyaddr.c: Fix address comparison so we actually + close sockets which were bound to IP-address that got deconfigured. + +2010-10-11 Yvan Vanhullebus + + * src/racoon/ipsec_doi.c: report a higher encryption key length in + approval for OBEY / CLAIM / STRICT modes + +2010-09-27 Yvan Vanhullebus + + * src/racoon/isakmp_xauth.c: fixed some typos in logs (reported by + fazaeli (at) sepehrs.com) + +2010-09-24 Yvan Vanhullebus + + * src/racoon/cftoken.l: fixed a fd leak, patch by getlaser (at) + gmail.com + +2010-09-22 Yvan Vanhullebus + + * src/racoon/admin.c: get the correct length of username when + processing ADMIN_LOGOUT_USER, patch by rweikusat (at) mssgmbh.com + + * src/racoon/nattraversal.h: fixed a typo in macros, reported by + marisp (at) mt.lv + +2010-09-21 Yvan Vanhullebus + + * src/racoon/isakmp_cfg.c: moved from utmp.h to utmpx.h (patch + provided by marcin.cieslak (at) gmail.com) + +2010-09-08 Yvan Vanhullebus + + * src/racoon/remoteconf.c: fixed remoteconf selection when no ID + specified in configuration, and added some debug to remoteconf + selection + +2010-08-26 Yvan Vanhullebus + + * src/racoon/remoteconf.c: fix by Sergio.Gelato (at) astro.su.se: + duplicate some dynamic values in duprmconf() + +2010-08-04 Yvan Vanhullebus + + * src/racoon/isakmp_cfg.c: fixed answer for IP4_SUBNET request + +2010-07-30 Yvan Vanhullebus + + * src/racoon/doc/FAQ: updated link to NetBSD's documentation + +2010-06-22 Thomas Klausner + + * src/racoon/racoon.conf.5: Bump date for previous. + +2010-06-22 Yvan Vanhullebus + + * src/racoon/: cfparse.y, cftoken.l, isakmp.c, isakmp_inf.c, + racoon.conf.5, remoteconf.c, remoteconf.h: added a specific + script hook when a dead peer is detected + +2010-06-04 Thomas Klausner + + * src/setkey/setkey.8: New sentence, new line. Bump date for + previous. + +2010-06-04 Yvan Vanhullebus + + * src/setkey/: parse.y, setkey.8, token.l: Added support for + spdupdate command in setkey + +2010-04-07 Yvan Vanhullebus + + * src/libipsec/ipsec_strerror.c: by Eric Preston: fixed a typo + +2010-04-02 Christos Zoulas + + * src/: libipsec/pfkey_dump.c, racoon/backupsa.c: handle ctime + returning NULL. + +2010-03-11 Christos Zoulas + + * src/racoon/handler.c: PR/42363: Yasuoka Masahiko: Second part of + the patch: iterate only on the phase2 handles that are bound by the + given phase1 handle. + +2010-03-05 Timo Teras + + * src/: libipsec/ipsec_set_policy.3, racoon/privsep.c, + racoon/doc/FAQ, setkey/setkey.8: From Stefan Bauer: Fix multiple + typoes and manpage formatting errors. + +2010-03-04 Yvan Vanhullebus + + * src/racoon/session.c: From Pierre POMES: fixed admin port + initialization + +2010-02-28 snj + + * src/racoon/: sockmisc.c, sockmisc.h: Fight the ever-increasing + size of src checkouts by spelling "useful" without an extra l. + +2010-02-09 Thomas Klausner + + * src/racoon/: pfkey.c, proposal.h: Fix typo in comment. + +2010-01-17 Thomas Klausner + + * src/racoon/sainfo.c: Free strdeupped string after using it. Found + by cppcheck. + + * src/racoon/: eaytest.c, ipsec_doi.c: Close file handles after + using them. Found by cppcheck. + +2010-01-15 joerg + + * src/setkey/setkey.8: Use .%U instead of .%O for URLs. + +2009-12-11 Timo Teras + + * src/racoon/Makefile.am: From Paul Wernau: vmbuf.h was defined + twice in the headers. Remove the redundant entry so new install tool + does not complain about overwriting just installed file. + +2009-11-22 Christos Zoulas + + * src/racoon/handler.c: PR/42363: Yasuoka Masahiko: + + racoon uses a wrong IPsec-SA handle that is for other peer in case + it receives a ISAKMP message for IPsec-SA that has the same + message-id as the message-id that is received before. + + racoon uses message-id to find the handle of IPsec-SA. The + message-id is a unique number for each peer, but different peers may + use the same value. + + Different Windows Vista or Windows 7 peers seem to use the same + message-id. racoon can handle the first Windows's Phase-2, but it + cannot handle the second Windows. Because racoon misunderstands the + message for the second Windows as the message for the first Windows. + + >Category: bin >Synopsis: racoon uses a wrong IPsec-SA + that is for different peer >Confidential: no >Severity: + serious >Priority: medium >Responsible: bin-bug-people + >State: open >Class: sw-bug >Submitter-Id: net + >Arrival-Date: Sun Nov 22 18:25:00 +0000 2009 >Originator: + yasuoka@iij.ad.jp + +2009-10-29 Christos Zoulas + + * src/setkey/token.l: use %option noinput nounput + +2009-10-28 Christos Zoulas + + * src/setkey/token.l: no unput + +2009-10-14 joerg + + * src/libipsec/ipsec_set_policy.3: Do not use .Xo/.Xc to workaround + ancient groff limits. + + * src/setkey/setkey.8: Do not use .Xo/.Xc to work around ancient + groff limits. Fix markup. + + * src/racoon/racoon.conf.5: Don't use .Xo/.Xc to work around + ancient groff limits. Set only one list type. + +2009-09-18 Timo Teras + + * src/racoon/: isakmp_agg.c, isakmp_ident.c: From Tomas Mraz: Fix + gssapi error checking. + +2009-09-03 Timo Teras + + * src/racoon/: admin.c, handler.c, handler.h, isakmp.c, + isakmp_var.h, pfkey.c: When rekeying phase2 use phase1 used to + negotiate phase2 as a hint to select the phase1 for rekeying the new + phase2. + +2009-09-01 Timo Teras + + * src/racoon/: nattraversal.c, racoon.conf.5, vendorid.c: Check + nat_traversal configuration from remote configuration candidates + when acting as responder. Enable NAT-T if any of the remote + candidates have NAT-T enabled. + + * src/racoon/remoteconf.c: Change remote conf matching level to + matching score. This way one can override anonymous certificate + block config with more exact "inhereted" IP specific block. + + * src/racoon/: isakmp.c, racoon.conf.5: From Maik Broemme: export + ISAKMP SA identity as REMOTE_ID for phase1 up script (trac #313). + +2009-08-24 Yvan Vanhullebus + + * src/racoon/oakley.c: fixed typo: algoriym -> algorithm + +2009-08-19 Yvan Vanhullebus + + * src/racoon/remoteconf.c: fixed address check in + rmconf_match_type(), just check address with wildcard port + +2009-08-19 Timo Teras + + * src/racoon/remoteconf.c: Have an enum for rmconf_match_type() + return values to make the code a bit more readable. + +2009-08-18 Yvan Vanhullebus + + * src/racoon/oakley.c: typo: algoritym -> algorithm + +2009-08-17 Yvan Vanhullebus + + * src/libipsec/libpfkey.h: do not use SADB_X_NAT_T_NEW_MAPPING to + check system support for NAT-T, as at least FreeBSD doesn't have + this define anymore + + * src/racoon/schedule.h: include stddef.h so we have a chance to + get the system offsetof if present + + * src/racoon/crypto_openssl.h: removed a self include + +2009-08-13 Yvan Vanhullebus + + * src/racoon/oakley.c: fixed a potential DoS in + oakley_do_decrypt(), reported by Orange Labs + +2009-08-10 Timo Teras + + * src/racoon/pfkey.c: Don't print EAGAIN error from + pfkey_handler(), it can occur normally under some code paths and is + not a hard error in any case. + +2009-08-06 Timo Teras + + * src/setkey/setkey.c: From Paul Wenau: Check fgets return value in + setkey to make gcc happy. + +2009-08-05 Timo Teras + + * src/racoon/pfkey.c: From Paul Wernau: Fix transport mode per-port + security associations that got broke during NAT-T fixes. + +2009-07-07 Timo Teras + + * src/racoon/sockmisc.c: From Arnaud Ebalard: Fix possible usage of + uninitialized local variable (not sure if any code path triggers + this, but this makes compiler happy). + +2009-07-03 Timo Teras + + * src/racoon/: admin.c, grabmyaddr.c, handler.c, handler.h, + isakmp.c, isakmp_cfg.c, isakmp_inf.c, isakmp_quick.c, + nattraversal.c, pfkey.c, policy.c, remoteconf.c, remoteconf.h, + sockmisc.c, sockmisc.h, throttle.c: Get rid of the evil CMPSADDR + macro. Trac #295. + + * src/: libipsec/libpfkey.h, libipsec/pfkey.c, racoon/isakmp.c, + racoon/isakmp_inf.c, racoon/pfkey.c, racoon/pfkey.h: From Yvan + Vanhullebus: Use SADB_X_EXT_NAT_T_* consistently for passing the + NAT-T port information. This might break compatibility with some + kernels, but as discussed this is the proper way to pass NAT-T ports + and the broken kernels need to be fixed. + +2009-06-24 Timo Teras + + * src/racoon/session.c: Fix a call to null pointer: in some cases, + the unmonitor_fd can be called from another fd's callback. That + could lead to still have callback pending after unmonitoring the fd + resulting in a call to null pointer. This is fixed by making + unmonitor_fd now clear the pending fd_set too. Bug was introduced + by my commit in 2008-12-23. + +2009-05-20 Yvan Vanhullebus + + * src/racoon/isakmp.h: typo + +2009-05-19 Timo Teras + + * src/racoon/: ipsec_doi.c, isakmp.c: From Jukka Salmi: Fix couple + of typos from previous commit. + +2009-05-18 Timo Teras + + * src/racoon/: ipsec_doi.c, isakmp.c, sockmisc.c, sockmisc.h: From + Tomas Mraz: Introduce union sockaddr_any and use it to make code + more readable. Related to trac #293. + + * src/racoon/isakmp_inf.c: From Tomas Mraz: Remove variable that is + not really used; only referenced while uninitialized causing + valgrind error. + + * src/racoon/nattraversal.c: From Tomas Mraz: Fix natt_flags check. + +2009-05-04 Thomas Klausner + + * src/racoon/racoon.conf.5: Remove superfluous spaces around + parentheses. + +2009-04-29 Timo Teras + + * src/racoon/crypto_openssl.c: From Ross Meng: Fix a memory leak in + X509 certificate validation. + +2009-04-28 Timo Teras + + * src/racoon/handler.c: Reset nat_oa variables too when reusing + phase two handler. Otherwise phase2 rekeying might fail in some + scenarios. + +2009-04-22 Timo Teras + + * src/racoon/isakmp_frag.c: From Neil Kettle: Fix a possible null + pointer dereference in fragmentation code. + +2009-04-21 Timo Teras + + * src/racoon/: grabmyaddr.c, grabmyaddr.h, session.c: Fix + strict_address to work again. The lists needs to be initialized + before configuration is read, which happens before my_addr_init() + call. + +2009-04-20 Timo Teras + + * src/racoon/: isakmp.c, isakmp.h, isakmp_var.h: Fix a memory leak + in certificate request generation. + + * src/racoon/: isakmp_inf.c, isakmp_xauth.c, plog.c: Orignally from + Bin Li: Fix possible memory corruption in binsanitize(). + + * src/racoon/crypto_openssl.c: From Stephen Bevan: Fix a x509 + signature verification memory leak. + + * src/racoon/: admin.c, racoonctl.c: Originally from Bin Li: Fix a + crash with racoonctl logout user. + + * src/racoon/nattraversal.c: Fix a memory leak in nat-t keepalive + code. + + * src/racoon/handler.c: From Paul Moore: Phase2 message id's should + be unique wrt phase1, not globally. + +2009-03-13 Timo Teras + + * src/racoon/: pfkey.c, remoteconf.h: From Arnaud Ebalard: Fix + couple of problems with previous commit. + +2009-03-12 he + + * src/racoon/: isakmp.c, remoteconf.c: When casting to/from a + pointer to an integral type (a bad practice, if you ask me), you + need to cast via intptr_t for portability. + +2009-03-12 Thomas Klausner + + * src/racoon/racoon.conf.5: New sentence, new line. Avoid marking + up punctuation. + + * src/racoon/racoonctl.8: Bump date for previous. Sort options to + establish-sa. Stop using Xo/Xc. + +2009-03-12 Timo Teras + + * src/racoon/: admin.c, cfparse.y, cftoken.l, crypto_openssl.c, + crypto_openssl.h, dnssec.c, dnssec.h, handler.c, handler.h, + ipsec_doi.c, ipsec_doi.h, isakmp.c, isakmp.h, isakmp_agg.c, + isakmp_base.c, isakmp_ident.c, isakmp_inf.c, isakmp_quick.c, + isakmp_var.h, nattraversal.c, oakley.c, oakley.h, racoon.conf.5, + racoonctl.8, racoonctl.c, remoteconf.c, remoteconf.h, sockmisc.c, + vendorid.c: Support multiple anonymous remotes and decide + remoteconf based on identity, received certificates and other + information. General code clean up. + +2009-03-06 Timo Teras + + * src/setkey/: extern.h, parse.y, setkey.c: setkey: fix deleteall + in Linux + + Linux requires SADB_DELETE message to have SPI. So send a + SADB_DELETE message for each matching SA. Trac #284. + + From: Gabriel Somlo + +2009-02-16 Timo Teras + + * src/libipsec/policy_parse.y: From Paul Moore: Fix a heap + corruption bug (yacc return non-null terminated buffer and sprintf + writes over bounds). + +2009-02-11 Yvan Vanhullebus + + * src/racoon/: isakmp.c, sockmisc.c, sockmisc.h: trac#301: fixed + IPsec SAs flush in purge_remote() when NAT-T enabled but no NAT-T on + tunnel + +2009-02-03 Timo Teras + + * src/racoon/isakmp.c: From: Phil Sutter. Fix script environment + variables with IPv6 addresses. + +2009-01-26 Timo Teras + + * src/racoon/main.c: Argument parsing needs lcconf initialized. + +2009-01-24 Thomas Klausner + + * src/racoon/racoonctl.c: Sort options in usage. + + * src/racoon/racoonctl.8: Sort options. New sentence, new line. + + * src/racoon/racoon.8: Sort options. + +2009-01-23 Timo Teras + + * src/racoon/: racoonctl.8, racoonctl.c: Update usage and manpage + for racoonctl. + + * src/racoon/: main.c, racoon.8: Racoon -v to print version and + compilation information. Update usage message. + + * NEWS: Update NEWS with major changes since 0.7 release. + + * src/racoon/schedule.c: Fix monotonic scheduler change, to not + refresh 'now' before exit. Otherwise we can return negative timeout + after spending time handling other events. + + * src/racoon/: handler.c, pfkey.c: From Arnaud Ebalard: Handle + reception of MIGRATE message during Phase 1 and Phase 2 negotiation. + Also corrects some debugging statements. + + * src/racoon/pfkey.c: From Arnaud Ebalard: On the responder (for + instance), there is a need to not only migrate local and remote + addresses of Phase 1 that match previous addresses but also the + local and remote addresses of a Phase 1 *associated* with a migrated + Phase 2. For instance, we have that need when receiving the first + MIGRATE/KMADDRESS message because the old addresses are still the + HoA and the address of the HA (while the peer has contacted us using + the CoA and we have negotiated this address as src attribute in + Phase 2). The patch fixes that by having migrate_ph1_ike_addresses() + called from migrate_ph2_ike_addresses() callback. + + * src/racoon/isakmp_quick.c: From Arnaud Ebalard: Set phase2 spid + when acting as responder. + + * configure.ac, src/racoon/handler.c, src/racoon/handler.h, + src/racoon/isakmp_inf.c, src/racoon/isakmp_xauth.c, + src/racoon/schedule.c, src/racoon/schedule.h, + src/racoon/throttle.c, src/racoon/throttle.h: Detect if monotonic + system clock is available, and use it for relative time measurements + to avoid complite hang if time jumps backwards. + + * src/racoon/: cfparse.y, ipsec_doi.c, isakmp.c, isakmp_agg.c, + isakmp_base.c, isakmp_cfg.c, isakmp_ident.c, isakmp_xauth.c, + oakley.c, oakley.h: Fix authentication method ambiguity by + internally using unique ID and setting/interpreting the wire format + based on received vendor ID:s. Fixes trac #280. + + * src/racoon/: handler.h, isakmp_agg.c, isakmp_base.c, + isakmp_ident.c, vendorid.c, vendorid.h: Introduce vendorid + bitmask that can be used otherwhere to detect peer capabilities. + + * configure.ac, src/racoon/admin.c, src/racoon/evt.c, + src/racoon/grabmyaddr.c, src/racoon/isakmp.c, src/racoon/pfkey.c, + src/racoon/session.c, src/racoon/session.h: Remove "fastquit" + configure option and make it the default behaviour. The previous + normal behaviour is buggy, as after flush kernel can immediately + create larval SA:s which would prevent exit. + +2009-01-20 Timo Teras + + * Makefile.am, misc/cvs2cl.pl, misc/cvsusermap: Autogenerate + ChangeLog from NetBSD CVS. Put sourceforge.net changes to + ChangeLog.old. + +2009-01-10 Thomas Klausner + + * src/racoon/racoon.conf.5: Make ready for HTML output. Use proper + escape for backslash ('\e'). + +2009-01-10 Timo Teras + + * src/racoon/: crypto_openssl.c, racoon.conf.5: From Cyrus Rahman: + Accept RFC2253 compliant escaped special characters for asn1dn + identifier. + +2009-01-09 Timo Teras + + * configure.ac: Fix a CPPLAGS typo to CPPFLAGS which was intended + +2009-01-05 Timo Teras + + * src/racoon/: cfparse.y, cftoken.l, racoon.conf.5: Remove obsolete + configuration options, fix radius configuration block and add GRE as + recognized protocol. + + * src/racoon/session.c: Do not use counting in signal handling as + it was unsafe by not using atomic functions (post increment is not + necessarily atomic). Instead reap all children on SIGCHLD as that + was the only signal needing signal counting. + +2008-12-30 Timo Teras + + * src/racoon/session.c: schedular() call can now modify fd mask so + make the working copy just before calling select(); otherwise it can + contain bad file descriptors + +2008-12-29 Michael van Elst + + * src/setkey/parse.y: support icmp codes. Fixes PR 39056. + +2008-12-24 Christos Zoulas + + * src/racoon/grabmyaddr.c: remove sin{6,}_len linux does not have + it. From Timo Teras. + + * src/racoon/grabmyaddr.c: I was wrong. addr is actually set. + + * src/racoon/grabmyaddr.c: + - make this compile by zeroing out the whole structure not just + bogus fields. + - set length field of sockets appropriately. + - mark bogus no-op code (I don't understand what the author intended + here). + +2008-12-23 Thomas Klausner + + * src/racoon/racoon.conf.5: Bump date for identity configuration + option removal. + +2008-12-23 Timo Teras + + * src/racoon/: cfparse.y, cftoken.l, ipsec_doi.c, localconf.c, + localconf.h, racoon.conf.5: Remove the obsoleted global identity + configuration option. + + * src/racoon/: admin.c, admin_var.h, cfparse.y, debug.h, evt.c, + evt.h, grabmyaddr.c, grabmyaddr.h, handler.c, isakmp.c, + isakmp_inf.c, isakmp_var.h, localconf.c, localconf.h, main.c, + nattraversal.c, pfkey.c, pfkey.h, privsep.c, session.c, + session.h: rewrite local address detection make some functions + static that arr not needed globally rework how fd_set is + construction for the main loop select() + +2008-12-18 Timo Teras + + * src/racoon/pfkey.c: From Arnaud Ebalard: Delete larval ph2handles + when expire with hard lifetime received + +2008-12-16 Timo Teras + + * README: Update README + + * src/racoon/pfkey.c: Fix transport mode address selection in + acquire handling. Some earlier fixes got lost on 2008-12-05 commit. + +2008-12-11 Yvan Vanhullebus + + * src/racoon/grabmyaddr.c: Fixed compilation on FreeBSD (RTM_IFINFO + and RTM_OIFINFO stuff) + + * src/racoon/isakmp.c: Fixed compilation when DPD support is + disabled + +2008-12-08 Timo Teras + + * src/racoon/: pfkey.c, privsep.c, privsep.h: Do not cache pfkey + sockets: it might cause to not handle some pfkey events when + select() has marked pfkey socket readable, but a timer callback + first calls pfkey_dump_sadb(). + +2008-12-05 Timo Teras + + * src/: libipsec/key_debug.c, libipsec/libpfkey.h, + libipsec/pfkey.c, racoon/handler.c, racoon/handler.h, + racoon/ipsec_doi.c, racoon/isakmp.c, racoon/isakmp_quick.c, + racoon/pfkey.c, racoon/policy.c, racoon/policy.h: From Arnaud + Ebalard: Improved Mobile IPv6 support per + draft-ebalard-mext-pfkey-enhanced-migrate. + +2008-12-04 Christoph Badura + + * src/racoon/privsep.c: Fix typo in previous and use SIG_IGN as I + intended. + +2008-12-02 Timo Teras + + * src/racoon/session.c: Explicitly ignore SIGPIPE. Default action + on Linux is terminate. + +2008-11-28 Thomas Klausner + + * src/racoon/racoon.conf.5: Remove empty line. Fix typo. New + sentence, new line. + +2008-11-27 Yvan Vanhullebus + + * src/racoon/main.c: Set up a default value for Mode Config Pool + size if pool address specified but pool size not specified + + * src/racoon/isakmp_cfg.c: Fixed pool resizing + +2008-11-27 Timo Teras + + * src/racoon/pfkey.c: From Arnaud Ebalard: Remove MAXNESTEDSA + weirdness. It's probably meant for bundle support which is not done. + When someone actually writes bundle support, the nested SA stuff + would probably be reworked too anyway. + + * src/: libipsec/libpfkey.h, libipsec/pfkey.c, racoon/cfparse.y, + racoon/cftoken.l, racoon/localconf.c, racoon/localconf.h, + racoon/pfkey.c, racoon/racoon.conf.5: From: Matthew Krenzer + Ability to set pfkey socket buffer size via configuration file + directive. (Indentation and minor fixes by me.) + +2008-11-25 Christoph Badura + + * src/racoon/: evt.c, privsep.c, session.c: Avoid using + MSG_NOSIGNAL as it is not available everywhere. Ignore SIGPIPE + instead. + + * src/racoon/grabmyaddr.c: Ignore unspecified and looback + addresses. Ignoring unspecified addresses prevents racoon from + trying to bind to the wildcard address and specific addresses + simultaneously after e.g. dhclient has changed an interface's + address to 0.0.0.0. + + * src/racoon/grabmyaddr.c: RTM_DELETE and RTM_IFINFO don't carry + info for added or deleted addresses. Ignore them silently. + + * src/racoon/grabmyaddr.c: Ignoring an unsuitable address is not an + error. Therefore log it as informational. Make it clear from the + log message that a route message is not interesting. + + * src/racoon/grabmyaddr.c: Use insmyaddr() instead of open coding + it. + + * src/racoon/isakmp.c: Do not return erroneously from isakmp_open() + when setting IPV6_USE_MIN_MTU fails. + + * src/racoon/: grabmyaddr.c, isakmp.c: Keep myaddr.sock at -1 when + no socket is opened. + +2008-11-08 Christoph Badura + + * src/racoon/samples/roadwarrior/client/: phase1-down.sh, + phase1-up.sh: Preserve owner and permissions of original + /etc/resolv.conf. Ensure that new /etc/resolv.conf isn't group or + world writable. + + * src/racoon/samples/roadwarrior/client/: phase1-down.sh, + phase1-up.sh: Print and check INTERNAL_NETMASK4. + + * src/racoon/samples/roadwarrior/client/: phase1-down.sh, + phase1-up.sh: Make the handling of NAT-T SPD entries automatic. + + * src/racoon/samples/roadwarrior/client/: phase1-down.sh, + phase1-up.sh: Ensure that the determination of the default + gateway and the corresponding interface don't get confused by + multiple, possibly non-IPv4 default routes. Bring the NetBSD case + of deleting the VPN routes and address in line with the Linux case + and delete the address after deleting the VPN routes. + +2008-11-06 Yvan Vanhullebus + + * src/racoon/sainfo.c: fixed delsainfo() to avoid a crash when + iddst's value is SAINFO_CLIENTADDR + +2008-10-29 S.P.Zeidler + + * src/racoon/ipsec_doi.c: Changes to ipsecdoi_id2str(): + + struct sockaddr -> struct sockaddr_storage fixes a stack overflow + + For non-linklocal addresses the value in 'scope' is garbage and gets + set to zero instead. + +2008-10-27 Timo Teras + + * src/racoon/pfkey.c: From Arnaud Ebalard: Add missing return to + error path + + * src/racoon/grabmyaddr.c: From Francis Dupont (sent by Arnaud + Ebalard): recognize RTM_IFANNOUNCE + + * src/racoon/grabmyaddr.c: From Arnaud Ebalard: Fix indentation + issues for readability + + * src/racoon/session.c: From Arnaud Ebalard: initfds() needs to be + called only if monitored file descriptor numbers have changed + + * src/racoon/isakmp_var.h: From Arnaud Ebalard: Remove duplicate + declaration + +2008-10-23 Timo Teras + + * src/racoon/: privsep.c, session.c, session.h: From Krzysztof + Piotr Oledzki : Revert parts of 2008-08-06 commit; the + problem those changes address are already handled in a sensible way + by Cyrus Rahman's patch from 2008-03-06. + +2008-10-09 Timo Teras + + * src/racoon/isakmp_quick.c: From Arnaud Ebalard: remove + unnecessary unbindph12() call which is now done in remph2() + +2008-09-25 Yvan Vanhullebus + + * src/racoon/isakmp.c: Fixed resending mechanism to have non-ESP + marker for retransmitted packets + +2008-09-19 Thomas Klausner + + * src/racoon/racoon.conf.5: New sentence, new line. + +2008-09-19 Timo Teras + + * src/racoon/: admin.c, cfparse.y, cftoken.l, handler.c, handler.h, + isakmp.c, isakmp_cfg.c, isakmp_inf.c, isakmp_quick.c, + isakmp_var.h, isakmp_xauth.c, pfkey.c, proposal.c, racoon.conf.5, + remoteconf.c, remoteconf.h: Implement ISAKMP SA rekeying + configurable with rekey {on|off|force} option in remote conf. + + * src/racoon/: handler.c, handler.h, isakmp.c, isakmp_inf.c, + isakmp_quick.c, isakmp_var.h, isakmp_xauth.c, isakmp_xauth.h, + nattraversal.c, pfkey.c, pfkey.h, schedule.c, schedule.h, + session.c: Change struct sched to be allocated be the caller to + avoid some memory allocations. Optimize scheduling algorithm to not + scan all entries in the main loop. + +2008-09-17 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: Fixed port match in purge_ipsec_spi() + when NAT-T enabled and trying to purge non NAT-T SAs + +2008-09-09 Yvan Vanhullebus + + * src/racoon/pfkey.c: Some calls to set_port() were not correctly + updated in the previous commit + +2008-09-03 Yvan Vanhullebus + + * src/racoon/pfkey.c: From Tomas Mraz: Duplicate addresses in + pk_sendxxx functions, as they may be altered for NAT-T stuff. + +2008-09-03 Timo Teras + + * src/: libipsec/pfkey.c, racoon/pfkey.c, racoon/sockmisc.c: + - Fix reloading of SPD (Linux satype check, handling of SPD dump + responses) + - Remove some spurious error log message from extract_port() + +2008-08-29 Gregory McGarry + + * src/racoon/isakmp.c: Eliminate gcc-specific feature of empty + structures. + + * src/racoon/evt.h: Eliminate superfluous semicolon. + + * src/racoon/: admin.c, admin.h: Eliminate gcc-specific feature of + unnamed structures added recently. + +2008-08-12 Yvan Vanhullebus + + * src/racoon/isakmp.c: From Krzysztof Piotr Oledzki: Remove + ph1handler if we received an invalid first exchange from initiator. + +2008-08-06 Timo Teras + + * src/racoon/: privsep.c, session.c, session.h: From Krzysztof + Piotr Oledzki: Make privileged process exit if unprivileged process + is terminated and some spelling fixes. + +2008-07-23 Matthew Grooms + + * src/racoon/: cfparse.y, session.c: Add some missing ifdefs + required for non-radius enabled builds. + +2008-07-23 Timo Teras + + * src/racoon/Makefile.am: Do not use GNU make specific extension. + + * src/: libipsec/Makefile.am, racoon/Makefile.am, + setkey/Makefile.am: Do flex/bison invocation in a more standard + way, and keep the generated files in the dist tarball. + +2008-07-22 Yvan Vanhullebus + + * src/racoon/proposal.c: From Kohki Ohhira: fix some memory leaks, + when malloc fails or when peer sends invalid proposal. + +2008-07-22 Matthew Grooms + + * src/racoon/: cfparse.y, cftoken.l, isakmp_cfg.c, isakmp_xauth.c, + isakmp_xauth.h, main.c, racoon.conf.5, session.c: Add an optional + radius configuration section to the racoon.conf file. This is + similar to the the LDAP configuration section and overrides settings + in the system radius configuration file. + +2008-07-21 Matthias Scheler + + * src/racoon/cfparse.y: Correct typo to fix the build. + +2008-07-21 Timo Teras + + * src/racoon/: isakmp_agg.c, isakmp_base.c, isakmp_ident.c, + vendorid.c, vendorid.h: Separate generic vendor id handling to a + new function and use it. + + * src/racoon/cfparse.y: Do not set default gss id if xauth is used, + otherwise gss-id attribute might be sent even if it was not + requested. + +2008-07-15 Matthew Grooms + + * src/racoon/isakmp_cfg.c: Fix an a typo that prevented racoon from + building with hybrid enabled. + + * src/racoon/: crypto_openssl.c, eaytest.c, misc.c, misc.h, + racoonctl.c: Fix a conflict with the FreeBSD 8 system hexdump + function. + +2008-07-14 Timo Teras + + * src/racoon/: handler.h, ipsec_doi.c, ipsec_doi.h, isakmp_quick.c, + pfkey.c: Handle RESPONDER-LIFETIME notification in quick mode. + + * src/racoon/: handler.h, isakmp.c, isakmp_agg.c, isakmp_ident.c, + isakmp_inf.c, isakmp_inf.h, isakmp_quick.c, strnames.c: Clean up + notification payload handling. Handle INITIAL-CONTACT notification + in last main mode exchange (delayed) and during quick mode + exchanges. + +2008-07-11 Timo Teras + + * src/racoon/: isakmp.c, isakmp_inf.c: Original patch from Atis + Elsts: Fix a double memory free and a memory corruption + (LIST_REMOVE() on an uninserted node) in some error handling paths. + +2008-07-09 Timo Teras + + * src/racoon/cfparse.y: From Chong Peng: fix a file descriptor and + memory leak on configuration file reread + +2008-07-02 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: From Timo Teras: fix some %d to %zu + (size_t values) + +2008-06-18 Thomas Klausner + + * src/racoon/racoonctl.8: Bump date for previous. + +2008-06-18 Matthew Grooms + + * src/racoon/: admin.c, admin.h, racoonctl.8, racoonctl.c: Add an + admin port command to retrieve the peer certificate. Submitted by + Timo Teras. + + * src/racoon/: admin.c, grabmyaddr.c, isakmp.c, misc.c, misc.h: Set + sockets to be closed on exec to avoid potential file descriptor + inheritance issues. Submitted by Timo Teras. + + * src/racoon/: admin.c, grabmyaddr.c, ipsec_doi.c, isakmp.c, + isakmp_cfg.c, isakmp_inf.c, privsep.c, remoteconf.c: Use utility + functions to evaluate and manipulate network port values. No + functional changes. Submitted by Timo Teras. + + * src/racoon/: admin.c, racoonctl.c: Admin port code cleanup. No + functional changes. Submitted by Timo Teras. + + * src/racoon/pfkey.c: Correct a phase2 status event. Submitted by + Timo Teras. + +2008-05-24 Christos Zoulas + + * src/racoon/privsep.c: Coverity CID 5018: Fix double frees. + +2008-05-08 Emmanuel Dreyfus + + * configure.ac: From Christian Hohnstaedt: allow out of tree + building + +2008-04-30 Martin Husemann + + * netbsd-import.sh: Convert TNF licenses to new 2 clause variant + +2008-04-25 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: From Timo Teras: extract port numbers + from SADB_X_EXT_NAT_T[SD]PORT if present in purge_ipsec_spi(). + +2008-04-13 Christos Zoulas + + * src/racoon/privsep.c: for symmetry set controllen the same way we + set it on the receiving side. + +2008-04-02 Emmanuel Dreyfus + + * src/racoon/: Makefile.am, sockmisc.c, sockmisc.h: fix Linux build + +2008-03-28 Christos Zoulas + + * src/racoon/privsep.c: properly fix the variable stack allocation + code. + +2008-03-28 Emmanuel Dreyfus + + * src/racoon/privsep.c: Still from Cyrus Rahman: fix file + descriptor leak introduced by previous commit. + + * src/racoon/: Makefile.am, isakmp.c, isakmp_inf.c, privsep.c, + privsep.h, sockmisc.c, doc/README.privsep: From Cyrus Rahman: + Allow interface reconfiguration when running in privilege separation + mode, document privilege separation + +2008-03-06 Yvan Vanhullebus + + * src/racoon/oakley.c: Generates a log if cert validation has been + disabled by configuration + +2008-03-06 Emmanuel Dreyfus + + * src/racoon/: privsep.c, session.c: From Cyrus Rahman + privilegied instance exit when unprivilegied one + terminates. Save PID in real root, not in chroot + +2008-03-06 Matthew Grooms + + * src/racoon/: admin.c, isakmp.c, isakmp_var.h, pfkey.c, + racoonctl.8, racoonctl.c: Add the ability to initiate IPsec SA + negotiations using the admin socket. Submitted by Timo Teras. + + * src/racoon/: admin.c, admin.h, evt.c, evt.h, handler.c, + handler.h, isakmp.c, isakmp_agg.c, isakmp_base.c, isakmp_cfg.c, + isakmp_ident.c, isakmp_inf.c, isakmp_var.h, isakmp_xauth.c, + racoonctl.8, racoonctl.c, session.c: Refactor admin socket event + protocol to be less error prone. Backwards compatibility is + provided. Submitted by Timo Teras. + +2008-03-05 Matthew Grooms + + * src/racoon/cfparse.y: Properly initialize the unity network + struct to prevent erroneous protocol and port info from being + transmitted. + + * src/racoon/: pfkey.c, pfkey.h, session.c: Reload SPD on SIGHUP or + adminport reload. Also provide better handling for pfkey socket read + errors. Submitted by Timo Teras. + +2008-02-25 Emmanuel Dreyfus + + * src/racoon/ipsec_doi.c: From Brian Haley + There's a cut/paste error in cmp_aproppair_i(), it's supposed to be + checking spi_size but it's not. I'm not sure this patch is correct, + but what's there isn't either. + +2008-02-22 Emmanuel Dreyfus + + * src/racoon/isakmp.c: Fix address length, from Brian Haley + +2008-02-10 S.P.Zeidler + + * src/racoon/ipsec_doi.c: closes PR bin/37644 did not meet violent + opposition ( :) ) on ipsec-tools-devel + +2008-01-11 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: From Timo Teras: reset iph1->dpd_r_u in + the scheduler's callback, to avoid access to freed memory. + + * src/racoon/crypto_openssl.c: From Krzysztof Oledzki: Fix + compilation with IDEA and recent gcc. + + * src/racoon/isakmp_inf.c: From Krzysztof Oledzki: added some + details to some logs (also reported new getph1byaddr() arg). + + * src/racoon/isakmp.c: From Krzysztof Oledzki: Only search for + established ph1 handles in DPD (also reported new getph1byaddr() + arg). + + * src/racoon/: handler.c, handler.h: added an 'established' arg to + getph1byaddr() + +2007-12-31 Matthew Grooms + + * src/racoon/: policy.c, racoonctl.8, racoonctl.c: Add GRE protocol + number to racoonctl. Correct id wildcard matching for transport + mode. Submitted by Timo Teras. + +2007-12-12 Matthew Grooms + + * NEWS, src/racoon/isakmp_quick.c: Add corrections submitted in a + follow up patch for the nat-t oa support. + + * src/racoon/: handler.c, handler.h, isakmp_quick.c, pfkey.c: Add + support for nat-t oa payload handling. Submitted by Timo Teras. + +2007-12-04 Matthew Grooms + + * src/racoon/: ipsec_doi.c, ipsec_doi.h, isakmp_quick.c: Modify + ipsecdoi_sockaddr2id() to obtain an id without specifying the exact + prefix length. Correct a memory leak in phase2. Both submitted by + Timo Teras. + +2007-12-01 Thomas Klausner + + * src/racoon/racoon.conf.5: Fix typos. New sentence, new line. + +2007-11-29 Yvan Vanhullebus + + * src/racoon/Makefile.am: From Natanael Copa: fixed a race + condition when building yacc stuff. + +2007-11-09 Yvan Vanhullebus + + * src/racoon/pfkey.c: From Arnaud Ebalard: Some sanity checking in + pk_recv() + + * src/racoon/policy.c: From Arnaud Ebalard: Better matching of SPD + entries in getsp_r(). + + * src/racoon/isakmp_quick.c: From Arnaud Ebalard: Added some debug + in get_proposal_r(). + +2007-10-19 Emmanuel Dreyfus + + * src/racoon/: isakmp_cfg.c, isakmp_unity.c, isakmp_unity.h, + racoon.conf.5: Add SPLITNET_{INCLUDR_LOCAL}_CIDR to hook scripts + +2007-10-15 Yvan Vanhullebus + + * src/libipsec/pfkey.c: Try to increase the buffer size of the + pfkey socket, this may help things when we have a huge SPD + +2007-10-02 Yvan Vanhullebus + + * src/racoon/crypto_openssl.c: From Scott Lamb: include plog.h to + work with the new plog macro. + + * src/racoon/kmpstat.c: From Scott Lamb: plog changed to _plog to + work with new plog macro + + * src/racoon/: plog.c, plog.h: From Scott Lamb: new plog macro. + +2007-09-19 Matthew Grooms + + * src/racoon/isakmp.c: Set REUSE option on sockets to prevent + failures associated with closing and immediately re-opening. + Submitted by Gabriel Somlo. + + * src/racoon/isakmp_unity.c: Prevent duplicate entries in splitnet + list. Submitted by Gabriel Somlo. + +2007-09-13 Matthew Grooms + + * configure.ac: Fix autoconf check for selinux support. Submitted + by Joy Latten. + +2007-09-12 Matthew Grooms + + * src/racoon/: cfparse.y, cftoken.l, handler.c, isakmp_quick.c, + pfkey.c, racoon.conf.5, sainfo.c, sainfo.h: Implement clientaddr + sainfo remote id option and refine the sainfo man page syntax. + +2007-09-05 Matthew Grooms + + * src/racoon/sainfo.c: Sort sainfo sections on insert and improve + matching logic. + +2007-09-03 Matthew Grooms + + * src/racoon/: cftoken.l, racoon.conf.5: Correct the syntax for + wins4 in the man page and add nbns4 as an alias. Pointed out by + Claas Langbehn. + +2007-08-07 Emmanuel Dreyfus + + * src/racoon/isakmp_xauth.c: src/racoon/isakmp_xauth.c: Don't mix + up RADIUS authentication and authorization ports. Allow + interoperability with freeradius + +2007-07-24 Matthew Grooms + + * NEWS: Update NEWS file with additional 0.7 improvements. + +2007-07-18 Matthew Grooms + + * src/racoon/racoon.conf.5: Various racoon configuration manpage + updates. + +2007-07-18 Yvan Vanhullebus + + * configure.ac, src/libipsec/ipsec_dump_policy.c, + src/libipsec/ipsec_get_policylen.c, + src/libipsec/ipsec_strerror.c, src/libipsec/key_debug.c, + src/libipsec/libpfkey.h, src/libipsec/pfkey.c, + src/libipsec/pfkey_dump.c, src/libipsec/policy_parse.y, + src/libipsec/policy_token.l, src/libipsec/test-policy-priority.c, + src/racoon/admin.c, src/racoon/backupsa.c, src/racoon/cfparse.y, + src/racoon/cftoken.l, src/racoon/ipsec_doi.c, + src/racoon/isakmp.c, src/racoon/isakmp_inf.c, + src/racoon/isakmp_quick.c, src/racoon/pfkey.c, + src/racoon/policy.c, src/racoon/proposal.c, + src/racoon/remoteconf.c, src/racoon/sainfo.c, + src/racoon/session.c, src/racoon/sockmisc.c, + src/racoon/strnames.c, src/setkey/parse.y, src/setkey/setkey.c, + src/setkey/token.l: use a single PATH_IPSEC_H to fix some + path_to_ipsec.h issues + +2007-07-16 Yvan Vanhullebus + + * src/racoon/grabmyaddr.c: fixed a socket leak + + * src/racoon/proposal.c: indentation + +2007-06-07 Emmanuel Dreyfus + + * src/racoon/isakmp_cfg.c: From Paul Winder + : Fix ignored INTERNAL_DNS4_LIST + +2007-06-06 Yvan Vanhullebus + + * src/racoon/: eaytest.c, var.h: From Rong-En Fan: fix compilation + with gcc 4.2 + + * src/racoon/session.c: From Jianli Liu: speed up interfaces update + when they change. + + * src/racoon/handler.c: ignore obsolete lifebyte when validating + reloaded configuration + +2007-05-31 Emmanuel Dreyfus + + * src/racoon/: main.c, policy.h, security.c: From Joy Latten + Fix file descriptor shortage when using + labeled IPsec. + +2007-05-30 Emmanuel Dreyfus + + * src/racoon/kmpstat.c: From Jianli Liu : In + racoonctl, use the specified socket path instead of the default + location + +2007-05-16 Christos Zoulas + + * src/racoon/cfparse.y: coverity CID 4168: yyerror() does not + return, so we proceed to de-reference NULL. Make it return -1 + instead like in other places. + + * src/racoon/cfparse.y: coverity CID 4170: yyerror() does not + return, so we proceed to de-reference NULL. Make it return -1 + instead like in other places. + +2007-05-04 Yvan Vanhullebus + + * src/racoon/handler.c: search a ph1 by address if iph2->ph1 is + NULL when validating the new config + + * src/racoon/handler.c: added some debug in getph1byaddr() to track + some port matching problems with NAT-T + + * src/racoon/isakmp.c: added some debug in isakmp_chkph1there() to + track some port matching problems with NAT-T + + * src/racoon/isakmp_inf.c: added some debug for DELETE_SA process + + * src/racoon/pfkey.c: Force the update of ph2 in pk_recvupdate() if + NAT_T support, to solve some port match problems with the first + IPSec SAs negociated as initiator + +2007-04-04 Yvan Vanhullebus + + * src/racoon/ipsec_doi.c: checks proto_id in ipsecdoi_chkcmpids() + + * src/racoon/oakley.c: dumps peer's ID and peer's certificate + subject /subjectaltname if they don't match + +2007-03-26 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: Store the DPD main scheduler in ph1 + handler, to be able to cancel it when removing the handler, and some + minor cleanups in DPD code + +2007-03-24 Christos Zoulas + + * src/racoon/isakmp_xauth.c: PR/36069: Huang Yushuo: racoon can't + work with pam_group Set RUSER. + +2007-03-23 Yvan Vanhullebus + + * src/racoon/: ipsec_doi.c, security.c: From Joy Latten: fix a + segfault when using security labels between 32bit and 64bit host. + + * src/racoon/handler.c: expire zombie handlers in getph2byid(), to + avoid situations where we'll never negociate a phase2 again + + * src/racoon/: oakley.c, racoon.conf.5: From Cyrus Rahman: give + more details about what is checked when using certificates to + authenticate + +2007-03-22 Yvan Vanhullebus + + * src/racoon/: cfparse.y, ipsec_doi.c: fixed subnet check to + generate IPV4_ADDRESS when needed in sockaddr2id() + +2007-03-21 Yvan Vanhullebus + + * src/racoon/: handler.c, isakmp.c, isakmp_inf.c, pfkey.c: NULL + sched check is now done in SCHED_KILL + + * src/racoon/schedule.h: checks if arg is NULL in SCHED_KILL + +2007-03-15 Yvan Vanhullebus + + * src/racoon/grabmyaddr.c: From Yves-Alexis Perez: enable + monitoring of ipv6 address changes on Linux. + + * src/racoon/isakmp.c: Consider a negociation timeout when + retry_counter is <=0 instead of < 0 + +2007-02-28 Matthew Grooms + + * src/racoon/ipsec_doi.c: Add logic to allow ip address ids to be + matched to ip subnet ids when appropriate. + +2007-02-21 Yvan Vanhullebus + + * src/racoon/ipsec_doi.c: block variable declaration before code in + ipsecdoi_id2str() + +2007-02-20 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: Removed a debug printf.... + + * src/racoon/isakmp.c: Only delete a generated SPD if it's creation + date matches the creation date of the SA we are currently deleting + + * src/racoon/: handler.c, isakmp_var.h: updated delete_spd() calls + + * src/racoon/: isakmp_inf.c, pfkey.c: fills creation date of + generated SPDs + + * src/racoon/policy.h: added 'created' var + +2007-02-19 Yvan Vanhullebus + + * src/racoon/isakmp.c: Removed a debug printf.... + +2007-02-16 Yvan Vanhullebus + + * src/racoon/ipsec_doi.c: From Olivier Warin: Fix a %zu in a + printf. + +2007-02-15 Emmanuel Dreyfus + + * src/racoon/security.c: Missing SELinux file + + * configure.ac: Missing stuff for SELinux + +2007-02-15 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: From "Uncle Pedro" on sf.net: Just + expire a ph1 handle when receiving a DELETE-SA instead of calling + purge_remote(). + + * src/racoon/isakmp.c: Fixed the way phase1/2 messages are + sent/resent, to avoid zombie handles and acces to freed memory + +2007-02-02 Yvan Vanhullebus + + * src/racoon/cfparse.y: Fixed a check of NAT-T support in libipsec + +2007-02-01 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: From "Uncle Pedro" on sf.net: When + receiving an ISAKMP DELETE_SA, get the cookie of the SA to be + deleted from payload instead of just deleting the ISAKMP SA used to + protect the informational exchange. + +2006-12-26 Arnaud Lacombe + + * src/racoon/ipsec_doi.c: CID-4167: check for 'iph1->approval != + NULL' + +2006-12-23 Thomas Klausner + + * src/racoon/racoon.conf.5: Use even more macros. + + * src/racoon/racoon.conf.5: Use more macros. + + * src/racoon/racoon.conf.5: Serial comma, and bump date for + previous. + +2006-12-18 Yvan Vanhullebus + + * src/racoon/crypto_openssl.c: From Joy Latten: fix a memory leak + +2006-12-10 Emmanuel Dreyfus + + * src/: libipsec/Makefile.am, libipsec/libpfkey.h, + libipsec/pfkey.c, racoon/backupsa.c, racoon/cfparse.y, + racoon/pfkey.c: Bring back API and ABI backward compatibility + with previous libipsec before recent interface change. Bump libipsec + minor version. Remove ifdefs in struct pfkey_send_sa_args to avoid + ABI compatibility lossage. Add a capability flags to detect missing + optional feature in libipsec + + * src/racoon/: Makefile.am, doc/README.plainrsa: From Joy Latten: + README.plainrsa documenting plain RSA auth + +2006-12-09 Emmanuel Dreyfus + + * configure.ac, src/libipsec/libpfkey.h, src/libipsec/pfkey.c, + src/racoon/Makefile.am, src/racoon/backupsa.c, + src/racoon/backupsa.h, src/racoon/cftoken.l, + src/racoon/ipsec_doi.c, src/racoon/ipsec_doi.h, + src/racoon/isakmp_inf.c, src/racoon/isakmp_quick.c, + src/racoon/pfkey.c, src/racoon/policy.c, src/racoon/policy.h, + src/racoon/proposal.c, src/racoon/proposal.h, + src/racoon/remoteconf.c: From Joy Latten: Add support for SELinux + security contexts. Also cleanup the libipsec interface for adding + and updating security associations. + + * src/racoon/racoon.conf.5: From Simon Chang: More hints about + plain RSA authentication + +2006-12-05 Yvan Vanhullebus + + * src/racoon/: proposal.c, proposal.h, racoon.conf.5: Check keys + length regarding proposal_check level + +2006-11-16 Matthew Grooms + + * src/racoon/sainfo.c: Correct issues associated with anonymous + sainfo selection in racoon. + +2006-11-09 Christos Zoulas + + * src/racoon/crypto_openssl.c: eliminate the only variable stack + array allocation. + +2006-10-31 Christian Biere + + * src/racoon/sockmisc.c: Don't define the deprecated + IPV6_RECVDSTADDR if the "advanced IPv6 API" is used because + IPV6_RECVPKTINFO and IPV6_PKTINFO are used to prevent potential bugs + in the future just in case that the numeric value of the socket + option is ever recycled. + +2006-10-22 Yvan Vanhullebus + + * src/racoon/: backupsa.c, cfparse.y: From Michal Ruzicka: fix + typos + +2006-10-19 Yvan Vanhullebus + + * src/racoon/sainfo.c: From Matthew Grooms: use + ipsecdoi_chkcmpids() and changed src/dst to loc/rmt in getsainfo(). + + * src/racoon/: ipsec_doi.c, ipsec_doi.h: From Matthew Grooms: Added + ipsecdoi_chkcmpids() function. + +2006-10-09 Emmanuel Dreyfus + + * src/racoon/proposal.c: Fix memory leak (Coverity 3438 and 3437) + + * src/racoon/isakmp_unity.c: Correctly check read() return value: + it's signed (Coverity 1251) + +2006-10-06 Emmanuel Dreyfus + + * configure.ac, src/libipsec/pfkey_dump.c, src/racoon/algorithm.c, + src/racoon/algorithm.h, src/racoon/cftoken.l, + src/racoon/crypto_openssl.c, src/racoon/crypto_openssl.h, + src/racoon/eaytest.c, src/racoon/ipsec_doi.c, + src/racoon/ipsec_doi.h, src/racoon/oakley.h, src/racoon/pfkey.c, + src/racoon/racoon.conf.5, src/racoon/strnames.c, + src/setkey/setkey.8, src/setkey/test-pfkey.c, src/setkey/token.l: + Camelia cipher support as in RFC 4312, from Tomoyuki Okazaki + + +2006-10-03 Emmanuel Dreyfus + + * src/racoon/admin.c: fix endianness issue introduced yesterday + +2006-10-03 Yvan Vanhullebus + + * src/racoon/racoon.conf.5: Added remoteid/ph1id syntax + + * src/racoon/: cfparse.y, cftoken.l: Parses remoteid/ph1id values + + * src/racoon/: handler.c, isakmp_quick.c, pfkey.c, sainfo.c: Uses + remoteid/ph1id values + + * src/racoon/: remoteconf.h, sainfo.h: Added remoteid/ph1id values + +2006-10-02 Emmanuel Dreyfus + + * src/racoon/isakmp_base.c: + avoid reusing free'd pointer (Coverity 2613) + + * src/racoon/isakmp_inf.c: Check for NULL pointer (COverity 4175) + + * src/racoon/isakmp_ident.c: Remove dead code (Coverity 3451) + + * src/racoon/algorithm.c: Fix array overrun (Coverity 4172) + + * src/racoon/admin.c: Fix memory leak (Coverity 2002) + + * src/racoon/: admin.c, isakmp.c, sockmisc.c: Fix memory leak + (Coverity 2001), refactor the code to use port get/set functions + + * src/racoon/admin.c: Avoid reusing free'd pointer (Coverity 4200) + + * src/racoon/oakley.c: Don't use NULL pointer (Coverity 3443), + reformat to 80 char/line + +2006-10-02 Tom Spindler + + * src/racoon/ipsec_doi.c: If you're going to initialize a pointer, + you have to init it with a pointer type, not an int. + +2006-10-02 Emmanuel Dreyfus + + * src/racoon/isakmp.c: Don't use NULL pointer (coverity 3439) + + * src/racoon/ipsec_doi.c: Don't use NULL pointer (Coverity 1334) + + * src/racoon/pfkey.c: Don't use NULL pointer (Coverity 944) + + * src/racoon/proposal.c: Don't use NULL pointer (Coverity 941) + + * src/racoon/racoonctl.c: Don't use NULL pointer (Coverity 942) + + * src/racoon/sockmisc.c: Don't use null pointer (Coverity 863) + +2006-10-01 Emmanuel Dreyfus + + * src/racoon/ipsec_doi.c: FIx memory leak (Coverity 4181) + + * src/racoon/isakmp.c: Check that iph1->remote is not NULL before + using it (Coverity 3436) + +2006-09-30 Emmanuel Dreyfus + + * src/racoon/isakmp_agg.c: emove dead code (Coverity 4165) + + * src/racoon/isakmp_cfg.c: Fix memory leak (Coverity 4179) + + * src/racoon/samples/roadwarrior/client/: phase1-down.sh, + phase1-up.sh: update the scripts for wrorking around routing + problems on NetBSD + + * src/racoon/session.c: Reuse existing code for closing IKE + sockets, and avoid screwing things by setting p->sock = -1, which is + not expected (Coverity 4173). + + * src/racoon/admin.c: Do not free id and key, as they are used + later + +2006-09-29 Emmanuel Dreyfus + + * src/racoon/racoonctl.c: Fix the fix: handle_recv closes the + socket, so we must call com_init before sending any data. + +2006-09-28 Emmanuel Dreyfus + + * src/racoon/isakmp_xauth.c: Fix unchecked mallocs (Coverity 4176, + 4174) + + * src/racoon/racoonctl.c: Fix access after free (Coverity 4178) + +2006-09-26 Emmanuel Dreyfus + + * src/racoon/cfparse.y: Fix memory leak (Coverity) + + * src/racoon/backupsa.c: Fix memory leak (Coverity) + + * src/racoon/admin.c: Remove dead code (Coverity) + + * src/racoon/admin.c: Fix memory leak (Coverity) + + * src/racoon/admin.c: One more memory leak + + * src/racoon/admin.c: Fix memory leak in racoonctl (coverity) + + * src/racoon/ipsec_doi.c: Fix buffer overflow Also fix credits: SA + bundle fix was contributed by Jeff Bailey, not Matthew Grooms. + Matthew updated the patch for current code, though. + + * src/racoon/: pfkey.c, proposal.c: fix SA bundle (e.g.: for + negotiating ESP+IPcomp) + +2006-09-25 Yvan Vanhullebus + + * src/racoon/isakmp.c: From Yves-Alexis Perez: struct ip -> struct + iphdr for Linux + +2006-09-25 Emmanuel Dreyfus + + * src/racoon/isakmp.c: style (mostly for testing + ipsec-tools-commits@netbsd.org) + + * src/racoon/ipsec_doi.c: Fix double free, from Matthew Grooms + +2006-09-21 Yvan Vanhullebus + + * src/libipsec/pfkey.c: use sysdep_sa_len to make it compile on + Linux + +2006-09-19 Thomas Klausner + + * src/racoon/racoon.conf.5: Bump date for ike_frag force. + + * src/racoon/: plainrsa-gen.8, racoon.conf.5: New sentence, new + line. + + * src/racoon/: racoon.conf.5, plainrsa-gen.8: Remove trailing + whitespace. + +2006-09-19 Yvan Vanhullebus + + * src/racoon/proposal.c: From Yves-Alexis Perez: fixes default + value for encmodesv in set_proposal_from_policy() + + * src/racoon/isakmp.c: always include some headers, as they are + required even without NAT-T + + * src/: libipsec/pfkey_dump.c, setkey/token.l: From Larry Baird: + define SADB_X_EALG_AESCBC as SADB_X_EALG_AES if needed + + * src/racoon/crypto_openssl.c: From Larry Baird: some printf() -> + plog() + +2006-09-18 Emmanuel Dreyfus + + * src/racoon/: cfparse.y, cftoken.l, isakmp.c, isakmp_frag.h, + isakmp_inf.c, racoon.conf.5, remoteconf.c: From Matthew Grooms: + ike_frag force option to force the use of IKE on first packet + exchange (prior to peer consent) + + * src/racoon/isakmp.c: From Matthew Grooms: handle IKE frag used in + the first packet. That should not normally happen, as the initiator + does not know yet if the responder can handle IKE frag. However, in + some setups, the first packet is too big to get through, and + assuming the peer supports IKE frag is the only way to go. + + racoon should have a setting in the remote section to do taht + (something like ike_frag force) + +2006-09-16 Emmanuel Dreyfus + + * src/racoon/ipsec_doi.c: Trivial bugfix in RFC2407 4.6.2 + conformance, from Matthew Grooms + +2006-09-15 Emmanuel Dreyfus + + * src/racoon/ipsec_doi.c: Fix build on Linux + +For older changes see ChangeLog.old diff --git a/ipsec-tools/ChangeLog.old b/ipsec-tools/ChangeLog.old new file mode 100644 index 00000000..0277b740 --- /dev/null +++ b/ipsec-tools/ChangeLog.old @@ -0,0 +1,2626 @@ + Migration to cvs.netbsd.org + +2006-08-22 Emmanuel Dreyfus + + From Matthew Grooms: + * src/racoon{cfparse.y|cftoken.l|isakmp_cfg.c|isakmp_cfg.h} + src/racoon{isdakmp_quick.c|isakmp_xauth.c|isakmp_xauth.h} + src/racoon/racoon.conf.5: Add a group check option + +2006-08-17 Yvan Vanhullebus + + Patch from Matthew Grooms: + * src/racoon/ipsec_doi.c: fixed an ASN1 size in + ipsecdoi_checkid1() + +2006-08-11 Yvan Vanhullebus + + Patch from Matthew Grooms: + * src/racoon/ipsec_doi.[ch]: fixed and public ipsecdoi_id2str() + * src/racoon/isakmp_quick.c: text fix + * src/racoon/pfkey.c: sainfo debug + * src/racoon/sainfo.c: sainfo debug + +2006-07-17 Yvan Vanhullebus + + Reported by Matthew Grooms: + * src/racoon/isakmp_quick.c: Fixed iph2->id / id_p checks in + get_sainfo_r(). + * src/racoon/racoon.conf.5: updated man page for sainfo logic. + +2006-07-31 Emmanuel Dreyfus + From Matthew Grooms + * src/racoon/{cfparse.y|isakmp_cfg.c|isakmp_cfg.h} + src/racoon/{isakmp_unity.c|isakmp_unity.h}: splinet support + becomes dynamic, bugfixes + +2006-07-19 Emmanuel Dreyfus + From Peter Eisch + * src/racoon/samples/roadwarrior/client/phase1-up.sh: add missing + netmask in network interface configuration + + From Matthew Grooms + * configure.ac src/racoon/isakmp_xauth.c: update the LDAP API usage + + From Matthew Grooms + * src/racoon/{cfparse.y|cftoken.l|isakmp_cfg.c|isakmp_cfg.h} + src/racoon/{isakmp_cfg.c|isakmp_unity.c|racoon.conf.5}: Split DNS + support (server side) + +2006-07-17 Yvan Vanhullebus + + * src/libipsec/pfkey.c: Fixed SADB_X_EXT_SEC_CTX support in pfkey_align(). + Break reported by Matthew Grooms. + +2006-07-13 Frederic Senault + + * src/racoon/isakmp_cfg.c: fix a typo that rendered DNS4 / WINS4 + unoperable on 64bit architectures ; add a packetdump of MODE_CFG + exchange in debug mode. + +2006-07-09 Emmanuel Dreyfus + From Matthew Grooms + * src/racoon{cfparse.y|cftoken.l|isakmp_quick.c|isakmp_xauth.c} + src/racoon{isakmp_xauth.h|racoon.conf.5|sainfo.c|sainfo.h}: + Group authentication for Xauth. Supports system groups and LDAP. + +2006-07-04 Yvan Vanhullebus + + * src/racoon/nattraversal.c: fixed a malloc check in + natt_keepalive_add(). Patch from Bruno Wagenseil. + +2006-06-30 Emmanuel Dreyfus + + * src/racoon/{cfparse.l|cftoken.l}: meaningful error message when + we cannot find the configuration file. + +2006-06-24 Emmanuel Dreyfus + From Matthew Grooms + * src/racoon{cfparse.y|cftoken.l|isakmp_cfg.c|isakmp_cfg.h} + src/racoon/{isakmp_xauth.c|isakmp_xauth.h|racoon.conf.5}: network + configuration obtained from LDAP directory + +2006-06-23 Emmanuel Dreyfus + From Matthew Grooms + * configure.ac: build fixes + +2006-06-22 Emmanuel Dreyfus + * src/racoon/evt.c: build fix + From Matthew Grooms + * configure.ac: build fixes around libldap and libiconv search + +2006-06-21 Emmanuel Dreyfus + * src/racoon/evt.c: Do not record events if admin socket is + disabled. + +2006-06-20 Emmanuel Dreyfus + + * configure.ac: Check for conflicts between system libiconv + and newer libiconv header + From Matthew Grooms + * configure.ac src/racoon/{cfparse.y|cftoken.l} + src/racoon/{isakmp_cfg.h|isakmp_xauth.c|isakmp_xauth.h} + src/racoon/{main.c|racoon.conf.5}: Use LDAP for Xauth + +2006-06-20 Yvan Vanhullebus + + * configure.ac: fixed SHA256 detection on some systems. Patch by + Dmitry Andrianov. + * src/racoon/{cfparse.y|cftoken.l|plog.[ch]|racoon.conf.5}: + changed logging levels. Patch by Michal Ruzicka. + +2006-06-15 Emmanuel Dreyfus + From Matthew Grooms + * src/racoon/main.c: make sure RADIUS is correctly initialized + +2006-06-14 Yvan Vanhullebus + + * Makefile.am, src/Makefile.am: fixed make dist on *BSD + +2006-06-07 Emmanuel Dreyfus + * src/racoon/isakmp_cfg.c: Fix build. + +2006-05-26 Emmanuel Dreyfus + From Pawel Jakub Dawidek + * src/racoon/handler.c: Fix a crash caused by a NULL pointer + * src/racoon/oakley.c: Typos + * src/racoon/isakmp_base.c: Fix uninitialized buffer + * src/racoon/isakmp_base.c: Do send DPD VID in resp case (base mode) + +2006-05-23 Emmanuel Dreyfus + * src/racoon/isakmp_cfg.c: Mode cfg can be used without Xauth, so + do not assume Xauth when preparing a hook script environement. + From chunkeey@web.de + * src/racoon/{algorithm.c|oakley.c|gssapi.c|ipsec_doi.c}: Fix amd64 + build warnings + * src/racoon/ipsec_doi.c: Don't free a referenced buffer + From Matthew Grooms + * src/racoon/isakmp_cfg.c: Fix for unity local_lan support + +2006-05-07 Emmanuel Dreyfus + * src/racoon/{isakmp.c|session.c|sockmisc.c|racoon.conf.5}: Do + not reconfigure interface sockets when running in privilege + separation as it will not work. Add debug for setsockopt(). + * src/racoon/racoonctl.8: Do not tell config reload is completely + broken (it's only somewhat broken). + +2006-05-06 Emmanuel Dreyfus + + * src/racoon/{remoteconf.c|remoteconf.h|isakmp.c|cfparse.y}: Fix + memory leak (Coverity) + * src/racoon/pfkey.c: Fix memory leak (Coverity) + * src/racoon/ipsec_doi.c: Fix memory leak (Coverity) + * src/racoon/isakmp.c: Fix memory leak (Coverity) + * src/racoon/dnssec.c: Fix memory leak (Coverity) + * src/racoon/backupsa.c: Fix memory leak (Coverity) + * src/racoon/{nattraversal.c|isakmp.c|cfparse.y}: Check for non NULL + allocation (Coverity) + * src/racoon/isakmp_quick.c: Remove dead code (Coverity) + * src/racoon/oakley.c: Remove dead code (Coverity) + * src/racoon/crypto_openssl.c: Remove dead code (Coverity) + +2006-05-05 Yvan Vanhullebus + + * src/racoon/pfkey.c: Sets NAT-T ports to 0 if no NAT + encapsulation in pk_sendgetspi(). + +2006-05-04 Yvan Vanhullebus + From Preggna S (spreggna@novell.com) + * src/racoon/schedule.h: fixed gnuc.h include. + * src/racoon/{cfparse.y|cftoken.l}: Address range sainfos support. + * src/racoon/ipsec_doi.[ch]: ipsecdoi_sockrange2id() function. + +2006-05-03 Yvan Vanhullebus + From Joy Latten + * configure.ac: security context support check + * src/libipsec/{pfkey.c|pfkey_dump.c}: + SADB_X_EXT_PACKET / SADB_X_EXT_SEC_CTX support + * src/setkey/{parse.ytoken.l}: parses optionnal security context + * src/setkey/setkey.8: security context syntax + +2006-04-27 Emmanuel Dreyfus + + * src/racoon/{remoteconf.c|proposal.c}: fix memory leak (Coverity) + +2006-04-24 Yvan Vanhullebus + + * src/racoon/isakmp.c: style cleanup in delete_spd() + +2006-04-13 Yvan Vanhullebus + + * src/racoon/pfkey.c: Sets NAT-T ports to 0 if no NAT + encapsulation in pk_sendupdate(). + +2006-04-12 Emmanuel Dreyfus + + * src/racoon/ipsec_doi.c: fix memory leaks (Coverity) + +2006-04-06 Emmanuel Dreyfus + + * src/racoon/{admin.c|cfparse.y|cftoken.l|debugrm.c|debugrm.h} + src/racoon/{gcmalloc.h|isakmp.c|isakmp_inf.c|isakmp_xauth.c} + src/racoon/{logger.c|misc.h|plog.c|racoonctl.c|sockmisc.c}: Add + strdup in the malloc debugging framework, check for strdup failures + (found by Coverity) + * src/racoon/admin.c: Do not use an unallocated pointer (Coverity) + * src/racoon/schedule.c: Check for NULL pointer + * src/racoon/{grabmyaddr.c|handler.c|isakmp.c|isakmp_cfg.c} + src/racoon/{isakmp_inf.c|isakmp_quick.c|nattraversal.c}: Check + that dupsaddr returns non NULL pointers (Coverity) + * src/racoon/isakmp_quick.c: Ignore multiple notifications in the + same message, and do not leak memory (Coverity) + * src/racoon/{isakmp_agg.c|isakmp_ident.c}: Fix memory leak in + GSSAPI code (Coverity) + * src/racoon/racoonctl.c: fix minor memory leak (Coverity) + * src/racoon/isakmp.c: fix memory leak (Coverity) + * src/racoon{isakmp.c|isakmp_inf.c}: fix phase 1 handler leak (Coverity) + +2006-04-05 Emmanuel Dreyfus + + * src/racoon/isakmp_xauth.c: fix unitialized variable, found by + Coverity + * src/racoon/{isakmp_cfg.c|isakmp_xauth.h|isakmp_xauth.c}: Do not + use deleted phase 1 handler after errors, found by coverity + * src/racoon/main.c: tell which config file we use + * src/racoon/isakmp_cfg.c: Do not use deleted phase 1 handler, found + by Coverity + * src/racoon/{isakmp_agg.c|isakmp_ident.c}: Do not use deleted phase 1 + handler, found by Coverity + * src/racoon/dnssec.c: do not return a free'ed certificate, found by + Coverity + * src/racoon/oakley.c: fix stale pointer alias, found by Coverity + * src/racoon/throttle.c: do not free current item while walking a + chained list, found by Coverity + * src/racoon/vmbuf.c: handle NULL argument for vdup, found by Coverity + +2006-03-18 Emmanuel Dreyfus + + From John Nemeth and a Coverity scan + * src/racoon/isakmp_xauth.c: fix memory leak + +2006-02-25 Emmanuel Dreyfus + + From Thomas Klausner + * src/racoon/{cfparse.y|handler.h}: typos + +2006-02-23 Emmanuel Dreyfus + + * src/racoon/main.c: do not reset isakmp_cfg structure after + config reload. + +2006-02-22 Yvan Vanhullebus + + * src/racoon/vendorid.c: Fixed Vendor IDs order (well, should not + be really necessary) and DPD VId hash generation + +2006-02-17 Yvan Vanhullebus + + * src/racoon/{cfparse.y|sainfo.c}: Support for "semi anonymous" + sainfos. + * src/racoon/racoon.conf.5: updated sainfos syntax + * src/racoon/vendorid.[ch]: IPSec-Tools Vendor ID + +2006-02-15 Yvan Vanhullebus + + * src/racoon/{cfparse.y|cftoken.l}: Parse new generate_policy + levels + * src/racoon/remoteconf.h: defines for REQUIRE/UNIQUE/NONE + generate policy levels + * src/racoon/proposal.c: Sets optionnal reqid for generated + policies + * src/racoon/pfkey.c: sends UNIQUE policies to kernel if reqid + specified + * src/racoon/racoon.conf.5: updated generate_policy syntax + +2006-02-02 Yvan Vanhullebus + + * src/racoon/isakmp.c: Fixed zombie PH1 handler when isakmp_send() + fails in isakmp_ph1resend() + +2006-01-17 Frederic Senault + + * src/racoon/cfparse.y: Add the keyid [ (tag|file) ] semantics to the + peers_identifier keyword. + + * src/racoon/{evt.h|isakmp.c|racoonctl.c}: Send a message to the + adminsock to allow for racoonctl to stop looping when the + vpn-connect command is used and there is no mode config exchange. + +2006-01-08 Emmanuel Dreyfus + + * src/racoon/isakmp_cfg.c: make software behave as the documentation + advertise for INTERNAL_NETMASK4. Keep the old INTERNAL_MASK4 to + avoid breaking backward compatibility. + +2005-12-19 Yvan Vanhullebus + + * src/racoon/session.c: Fixed / cleaned up signal handling. + +2005-12-13 Yvan Vanhullebus + + * src/libipsec/samples/*: replaced "obey" mode by "strict" mode. + +2005-12-07 Yvan Vanhullebus + + * src/libipsec/pfkey_dump.c: fixed compilation when NAT_T + disabled (Fred has still some CVS problems). + * src/racoon/session.c: Calls isakmp_cfg_init() only if + ENABLE_HYBRID in reload_conf(). + +2005-12-04 Frederic Senault + + * src/libipsec/{libpfkey.h|pfkey_dump.c}: add a sadump_withports + function to display SAD entries with their associated ports. + * src/setkey/{parse.y|setkey.c|setkey.8}: allow to use setkey -p flag + in conjunction with -D to show SADs with the port, allow both get and + delete commands to use bracketed ports if needed. + +2005-11-26 Emmanuel Dreyfus + + * src/racoon/session.c: fix possible race conditions in signal handlers + * src/racoon/{isakmp_cfg.c|isakmp_cfg.h|main.c|session.c}: when + reloading configuration, do not new add mode_cfg config to the + existign one, overwrite it instead. + +2005-11-25 Emmanuel Dreyfus + + From Thomas Klausner + * src/racoon/racoon.conf.5: Style changes + +2005-11-21 Yvan Vanhullebus + + * src/racoon/isakmp_[ident|agg].c: Check if natt is available when + receiving a NAT_D payload from initiator. It saves a crash, + reported by Dave Huang to NetBSD. + +2005-11-20 Yvan Vanhullebus + + * src/racoon/isakmp_agg.c: Check that we got some needed payloads + from peer (could cause a DoS). Crash reported by Adrian Portelli + using IKE test suite from + http://www.ee.oulu.fi/research/ouspg/protos/testing/c09/isakmp/ + +2005-11-10 Yvan Vanhullebus + + Patches from Francis Dupont + * src/libipsec/key_debug.c: SADB_X_EXT_PACKET support + * src/libipsec/{libpfkey.h|pfkey.c}: pfkey_send_migrate() function + * src/setkey/parse.y: IPPROTO_MH support + * src/racoon/pfkey.c: fixed some logs + * src/racoon/strnames.c: fixed a typo for SADB_X_PROMISC, + appropriate define for SADB_X_NAT_T_NEW_MAPPING, added + SADB_X_MIGRATE + +2005-11-06 Aidas Kasparas + + * src/racoon/main.c, src/racoon/session.c: moved .pid file writing + just before main loop. Thanks Stephen Thorne + * src/racoon/localconf.h, src/racoon/cftoken.l: introduced + path pidfile directive + * src/racoon/racoon.conf.5: documented above + * configure.ac: OpenSSL 0.9.8 compilation fix. Thank Ganesan + Rajagopal + * configure.ac: added check for strlcat function + * src/racoon/misc.h: define strlcat function for systems without one + * src/racoon/remoteconf.c: strncat -> strlcat + +2005-11-01 Aidas Kasparas + + * src/racoon/isakmp_inf.c: repeated gcc-4.0 build fix. Thanks + Andreas Tobler + +2005-10-30 Yvan Vanhullebus + + Patches from Christoph Nadig for compilation on MacOS X + * configure.ac: no lcrypt for darwin + * src/libipsec/key_debug.c: include stdint.h if HAVE_STDINT_H + * src/racoon/isakmp_cfg.c: some includes and some %zu + * src/racoon/isakmp_unity.c: fixed a %zu + * src/racoon/vmbuf.h: vfree already defined for Apple + +2005-10-17 Aidas Kasparas + + Introduced subnet sainfo type. + * src/racoon/cftoken.l: new token "subnet" + * src/racoon/cfparse.y: added address/subnet diferentiation logic + * src/racoon/ipsec-doi.h: new constant + * src/racoon/ipsec-doi.c: adopted to above + * src/racoon/racoon.conf.5: documented above + +2005-09-14 Emmanuel Dreyfus + + * src/libipsec/pfkey.c: One forgotten cast caddr_t -> void * + +2005-10-14 Yvan Vanhullebus + + * src/racoon/ipsec_doi.c: don't allow NULL or empty FQDNs or + USER_FQDNs (problem reported by Bernhard Suttner). + +2005-09-10 Emmanuel Dreyfus + + * src/racoon[isakmp.c|isakmp_cfg.c|isakmp_inf.c} + src/racoon/doc/FAQ configure.ac: Add --enable-broken-natt for + kernel implementing NAT-T but unable to cope with IKE ports in + SAD and SPD. + +2005-09-05 Emmanuel Dreyfus + + From Wilfried Weissmann: + * src/libipsec/policy_parse.y src/racoon/oakley.c + src/racoon/{sockmisc.c|sockmisc.h}: build fixes + + +2005-09-03 Emmanuel Dreyfus + + From Francis Dupont + * src/libipsec/pfkey.c src/racoon/pfkey.c: Cope with extensions + +2005-08-26 Emmanuel Dreyfus + + * src/racoon/evt.c: Fix memory leak when event queue overflows + +2005-08-23 Emmanuel Dreyfus + + * src/racoon/{isakmp_agg.c|isakmp_ident.c|isakmp_base.c}: Correctly + initialize NAT-T VID to avoid freeing unallocated stuff. + +2005-08-21 Emmanuel Dreyfus + + From Matthias Scheler + * src/racoon/{isakmp_cfg.c|racoon.conf.5}: enable the use of + ISAKMP mode config without Xauth. + +2005-08-16 Emmanuel Dreyfus + + From Thomas Klausner + * src/setkey/setkey.8: remove trailing whitespaces + +2005-09-09 Yvan Vanhullebus + + * src/racoon/policy.c: Do not parse all sptree in inssp() if we + don't use Policies priority. + +2005-08-20 Yvan Vanhullebus + + * src/racoon/handler.c: Fixed a possible crash in + remove_ph2(). Reported by Dietmar Eggemann. + +2005-08-14 Emmanuel Dreyfus + + From Francis Dupont + * src/racoon/dnssec.c: fix bogus test on function result + +2005-08-11 Yvan Vanhullebus + + * src/racoon/isakmp.c: Improved in/out SA addresses check in + purge_remote(). Reported by Patrick Ma. + +2005-08-08 Emmanuel Dreyfus + + * src/libipsec/{key_debug.c|pfkey.c|pfkey_dump.c}: de-lint, warnings + +2005-08-08 Yvan Vanhullebus + + * src/racoon/privsep.c: Fixed a %d -> %zu in + port_check() (reported by Matthias Scheler). + +2005-08-04 Emmanuel Dreyfus + + * configure.ac: correctly quote RACOON_PATH_LIBS arguments + +2005-08-02 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: First fix to + info_recv_initialcontact(): do a basic IP check when no NAT-T. + +2005-07-26 Yvan Vanhullebus + + * src/racoon/isakmp.c: Fixed purge_remote() + +2005-07-25 Yvan Vanhullebus + + * src/racoon/isakmp.c: Do not purge IPSec SAs in purge_remote() if + a new ph1handle exists (patch by Krzysztof Oledzki) + +2005-07-20 Aidas Kasparas + + * configure.ac: disabled --enable-samode-unspec under linux + +2005-07-20 Yvan Vanhullebus + + * src/racoon/isakmp_quick.c: Ignore NATOA payloads in + quick_r1recv() as it is done in quick_i2recv(). + * configure.ac: new --enable-fastquit option + * src/racoon/session.c: new code optional code when flushing SAs, + which is faster and should have no deadlocks. configure + --enable-fastquit option to enable it. + +2005-07-19 Yvan Vanhullebus + + * src/racoon/isakmp.c: Checks in isakmp_ph1begin_r() if we got the + packet from NAT-T port, and set up the NAT_PORTS_CHANGED in that + case (RFC 3947, sect 4, we MUST allow new phase1 negociations on + NAT-T floated port), to correctly generate the reply. + +2005-07-16 Aidas Kasparas + + * src/racoon/grabmyaddr.c: fixed file descriptor leak. Thanks to + Patrice Fournier + * src/racoon/setkey.c: disabled readline's filename completion + (bug 1179281 fix) + * src/racoon/proposal.c: fixed mode selection for SAs with + complex_bundle on behind NAT + +2005-07-14 Yvan Vanhullebus + + * src/racoon/handler.c: - Clears the DPD schedule in delph1() + - Cleared up sanity checks in delph1() + - Sets p->rmconf to NULL if no new + remoteconf in revalidate_ph1tree_rmconf() + * src/racoon/isakmp.c: Added sanity checks in script_hook() + * src/racoon/oakley.c: Sanity check in save_certbuf() + + +2005-07-13 Emmanuel Dreyfus + + * src/setkey/Makefile.am: missing file in distribution + +2005-07-12 Yvan Vanhullebus + + * src/racoon/isakmp.c: Fixed a mem leak in isakmp_send(). + +2005-07-12 Emmanuel Dreyfus + + * src/racoon/pfkey.c: Set IKE ports to 0 in the SA when NAT-T is not + used. + * src/racoon/{crypto_openssl.c|ipsec_doi.c|oakley.c} configure.ac + src/racoon/missing/crypto/sha2/sha2.h: Support OpenSSL-0.9.8 + * src/racoon/{admin.c|session.c}: Don't use the adminport if it is + disabled + * src/racoon/samples/roadwarrior/client/{pahse1-up.sh|phase1-down.sh}: + Add comments for using the scripts without NAT-T + +2005-07-11 Emmanuel Dreyfus + + * src/racoon/ipsec_doi.c configure.ac: More build fixes on Linux. + Accomodate various libiconv versions + +2005-07-10 Emmanuel Dreyfus + + * src/racoon/ipsec_doi.c configure.ac: build fixes on Linux. + Accomodate various libiconv versions + +2005-07-09 Yvan Vanhullebus + + * src/racoon/crypto_openssl.c: Fixed evp_crypt when using crypto + algorithms with variable key size but not OpenSSL default key + size. + +2005-07-07 Emmanuel Dreyfus + + From Mathias Scheler + * src/racoon/raccon.conf.5: Document that aes can be used in + racoon.conf + +2005-07-06 Frederic Senault + + * src/setkey/setkey.c: fix compilation with readline. + * src/racoon/oakley.c: move declarations to fix compilation issues + with gcc 2.95.4/FreeBSD4, re-indentation and style cleanup of the + pkcs7 patch. + +2005-07-04 Emmanuel Dreyfus + + * src/racoon/isakmp_inf.c: safety checks on informational messages + * src/racoon/{pfkey.c|proposal.c}: IPcomp fixes + +2005-07-01 Emmanuel Dreyfus + + From Uri Blumenthal : + * src/racoon/{ipsec_doi.c|Makefile.am}: Linux build fixes + * src/racoon/oakley.c: pkcs7 support + +2005-06-29 Emmanuel Dreyfus + + From Christos Zoulas + * configure.ac src/setkey/{parse.y|setkey.c|token.l} + src/libipsec/{ipsec_dump_policy.c|ipsec_get_policylen.c|key_debug.c} + src/libipsec/{libpfkey.h|pfkey_dump.c|policy_parse.y}: de-lint, + using void * instead of caddr_t and adding const where appropriate. + * src/setkey/extern.h: new file + * src/libipsec/{pfkey.c|pfkey_dump.c|policy_parse.y} + src/racoon/{sockmisc.c|sockmisc.h}: de-lint signed/unsigned, + size_t/int and lint constants + +2005-06-24 Yvan Vanhullebus + + * src/racoon/handler.c: Fixed phase2 enc algo check when reloading + conf (could flush a phase2 handler when not needed). + +2005-06-19 Emmanuel Dreyfus + + * src/racoon/{admin.c|handler.c|handler.h|racoonctl.c|racoonctl.h} + src/racoon/racoonctl.8: + Add a logout-user command to racoonctl to kick out all SA for a + given Xauth user + + From Ludo Stellingwerff : + * src/racoon/isakmp.c: NAT-T fix: We treat null ports in SPD as + wildcard so that IKE ports are used instead. This was done on + phase 2 initiation from the kernel (acquire message), but not + on phase 2 initiation retries when the phase 2 had been queued + for a phase 1. + + From Uri Blumenthal + and Larry Baird : + * src/libipsec/pfkey_dump.c src/setkey/test-pfkey.c + src/racoon/{algorithm.c|cftoken.l|eaytest.c|ipsec_doi.c} + src/racoon/{ipsec_doi.h|pfkey.c|strnames.c}: Add SHA2 support + * src/setkey/setkey.8 src/racoon/racoon.conf.5: update doc for SHA2 + * src/setkey/token.l: Add aliases shaxxx for sha2_xxx + +2005-06-07 Emmanuel Dreyfus + + From Larry Baird + * src/racoon/isakmp.c: consume NAT keepalive data already seen + with MSG_PEEK + +2005-06-07 Frederic Senault + + * configure.ac src/racoon/{cfparse.y|isakmp_cfg.h|isakmp_cfg.c} + src/racoon/{handler.c|privsep.c|privsep.h|racoon.conf.5}: Add + support for system accounting into the utmp files, with the + "accounting system" directive. + + * src/privsep.c: Bug fixes in the xauth password handling code. + +2005-06-06 Emmanuel Dreyfus + + * src/racoon/isakmp_quick.c: endianness bug fix + +2005-06-05 Emmanuel Dreyfus + + From Thomas Klausner + * src/setkey/setkey.8 src/racoon/racoon.conf.5: remove trailing + spaces, grammar fix + +2005-05-31 Aidas Kasparas + + * src/racoon/ipsec_doi.c: Inserted missing 0th element of + rm_idtype2doi array. Bug #1199700 fix. + +2005-05-30 Frederic Senault + + * src/racoon/oakley.h: Fix a typo in the RMAUTHMETHOD macro + definition. + + * src/racoon/isakmp_cfg.c: Fix the switch so that the phase1 script + is executed at the end of the mode cfg exchange ; add a debug + message at the script startup. + +2005-05-23 Emmanuel Dreyfus + + * src/racoon/admin.c: build fix + +2005-05-20 Emmanuel Dreyfus + + From Mike Robinson + * src/racoon/isakmp_xauth.c: really delete phase 1 on Xauth failure + + * src/libipsec/pfkey.c src/racoon/ipsec_doi.c: Fix NAT-T + IPcomp + + From hgates + * src/racoon/proposal.c: fix SPI size test for IPcomp + + From Larry Baird + * src/racoon/{handler.c|ipsec_doi.c}: When altering lifetime, + duplicate the proposal instead of modifying the configured one. + +2005-05-19 Frederic Senault + + * configure.ac src/racoon/plog.c: Fix the logging functions to work + around the lack of support of printf %zu in FreeBSD 4 (at least). + + * src/racoon/{isakmp.c|pfkey.c}: Put sockets in non-blocking mode to + fix a hangup with FreeBSD 4. + + * src/racoon/{isakmp_inf.c|isakmp_unity.h|strnames.c}: Recognize a + unity-specific heartbeat message. + * src/racoon/isakmp_inf.c: Reorganize switch statement in + isakmp_check_notify. + +2005-05-17 Yvan Vanhullebus + + * src/racoon/handler.c: Fixed exchange type check in + revalidate_ph1(). + * src/racoon/pfkey.c: changed includes order to fix compilation. + +2005-05-14 Emmanuel Dreyfus + + * src/libipsec/policy_parse.y: Fix parse problem + +2005-05-14 Aidas Kasparas + + * src/racoon/sockmisc.c: Debug message said it will send to + source address insted of destination. + +2005-05-13 Emmanuel Dreyfus + + * src/racoon/isakmp_inf.c: fix build problem + +2005-05-13 Yvan Vanhullebus + + * src/racoon/isakmp.c: Fixed a double ph2handler free in + isakmp_ph2begin_i(). + +2005-05-12 Emmanuel Dreyfus + + * src/racoon/isakmp_quick.c: fix build problem on some platforms + + * src/racoon/isakmp.c: For acquire messages, when NAT-T is in use, + consider null port as a wildcard and use IKE ports. + +2005-05-10 Emmanuel Dreyfus + + * src/racoon/samples/roadwarrior/server/{racoon.conf|racoon.conf-radius} + src/racoon/samples/roadwarrior/server/phase1-down.sh: removed file + src/racoon/samples/roadwarrior/client/racoon.conf: update config + files to higher security settings. Remove now useless phase 1 down + script on server side. + * Update README to reflect server/phase1-down.sh removal + +2005-05-09 Emmanuel Dreyfus + + * src/racoon/{cftoken.l|cfparse.y|isakmp_cfg.c|isakmp_cfg.h} + src/racoon/{isakmp_unity.c|racoon.conf.5}: Add PFS group and + save password extensions from Cisco in ISAKMP mode config. + +2005-05-08 Emmanuel Dreyfus + + * src/racoon/{handler.c|ipsec_doi.c|proposal.c}: check for lifebyte + in proposals + * src/racoon/ipsec_doi.c: fix a bug in proposal_check claim for phase 1 + * src/racoon/handler.c: style + + * src/racoon/isakmp_xauth.c: fix build with shadow passwords + +2005-05-07 Emmanuel Dreyfus + + * configure.ac src/racoon/isakmp_xauth.c: support shadow passwords + * src/racoon/{isakmp_inf.c|isakmp_inf.h}: missing prototype + * src/racoon/{handler.h|isakmp_inf.c|isakmp_quick.c|isakmp_var.h} + src/racoon/pfkey.c: Move purge_remote() and delete_spd() prototypes + to the right header file + +2005-05-06 Emmanuel Dreyfus + + * src/racoon/{admin.c|isakmp.c|isakmp_inf.c}: factor various + ISAKMP SA termination (for DPD timeouts and delete message) to + use purge_remote() so that SA and generated SPD get correctly flushed + * src/racoon/{handler.c|handler.h}: Introduce getph1byaddrwop() and + getph2bysaddr() + * src/racoon/{isakmp.c|isakmp_var.h|isakmp_inf.c|isakmp_inf.h}: make + purge_remote(), setcopeid() and delete_spd() public + * src/racoon/isakmp_quick.c: remove duplicated setscopeid() + * src/racoon/{sockmisc.c|sockmisc.h} introduce a CMPSADDR() macro + to compare with ports when ENABLE_NATT and without otherwise + +2005-05-06 Frederic Senault + + * src/racoon/isakmp_inf.c: Only print the contents of an informative + message if the payload indicates an error ; transmit the return + values from the DPD functions. + +2005-05-06 Emmanuel Dreyfus + + * src/racoon/isakmp_inf.c: Fix a bug causing informational message + payloads to be ignored + +2005-05-05 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: Fixed some potential crashes in + purge_remote() and purge_ipsec_spi(). + +2005-05-05 Emmanuel Dreyfus + + * src/libipsec/{policy_parse.y|policy_token.l} + src/setkey/{setkey.8|token.l}: Allow ports to be supplied in SP + endpoints, for accurate ESP over UDP matching + * src/racoon/{isakmp.c|racoon.conf.5}: Send IKE local and remote + ports to the hook scripts + * src/racoon/remoteconf.c: do not honour ports when looking up + a remote config, as our remote config have no port information + * src/racoon/samples/roadwarrior/client/{phase1-up.sh|phase1-down.sh}: + use the IKE ports supplied by racoon to set up acurate endpoints + ports in SP endpoints + +2005-05-04 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: code cleanup for SPD remove, generated + policies are now also removed when DPD purge. + +2005-05-04 Emmanuel Dreyfus + + From Manisha Malla + * src/racoon/isakmp_cfg.c: fix unsigned int checked for being negative + + From Ludo Stellingwerff + * src/setkey/{parse.y|token.l}: build on system that do not have + TCP-MD5 support + +2005-05-04 Michal Ludvig + + * configure.ac: Revert GLIBC_BUGS change from 2005-04-15 + +2005-05-03 Frederic Senault + + * src/racoon/{cfparse.y|cftoken.l|isakmp_inf.c|racoon.conf.5} + src/racoon/{remoteconf.c|remoteconf.h}: Add a weak_phase1_check + option to enable the handling of unencrypted delete payloads. + + * src/racoon/plog.c: Use of isgraph in binsanitize. + + * src/racoon/rfc/rfc3706.txt: new file: Dead Peer Detection RFC. + + * src/racoon/isakmp_inf.c: Unused code cleanup. + +2005-04-26 Emmanuel Dreyfus + + * bootstrap: Darwin support + + From Larry Baird + * src/racoon/nattraversal.c: Fix NAT-T for initiator + + From Andreas Tobler : + * src/racoon/{misc.h|throttle.c|remoteconf.c|sockmisc.c|privsep.c} + src/racoon/{pfkey.c|isakmp.c|grabmyaddr.c|getcertsbyname.c} + src/racoon/configure.ac src/libipsec/policy_token.l + src/setkey/token.l: Build on Darwin + +2005-04-25 Emmanuel Dreyfus + + * src/racoon/handler.h: ifdef DPD and NAT-T data in data structures + + * src/libipsec/{ipsec_dump_policy.c|pfkey_dump.c|libpfkey.h} + src/setkey/{setkey.8|setkey.c}: add a -p option to setkey to + enable the display of ESP over UDP ports in policies. + + * src/racoon/ipsec_doi.c: fix LP64 bug + + From Ludo Stellingwerff : + * src/racoon/isakmp.c: build without NAT-T + + From F. Senault + * src/racoon/{evt.h|isakmp.h|isakmp_inf.c|plog.c|plog.h|racoonctl.c} + src/racoon/isakmp_xauth.c: Take into account payloads bundled after + an ISAKMP informationnal message. + + From Patrick McHardy + * src/racoon/{handler.c|handler.h|pfkey.c}: When handling acquire + message, lookup phase 2 by (src, dst, id) instead of only id. + +2005-04-23 Emmanuel Dreyfus + + * src/libipsec/ipsec_dump_policy.c: display port numbers in policies + * src/racoon/{isakmp.c|isakmp_cfg.c|isakmp_inf.c|pfkey.c}: don't + forget port numbers so that mutiple clients behind the same NAT + can work. + + From Larry Baird + * src/racoon/{isakmp.c|nattraversal.c|isakmp_quick.c|nattraversal.h}: + NAT-T fixes for interoperability with greenbow VPN client. + +2005-04-21 Aidas Kasparas + + * src/libipsec/policy.parse.y, src/racoon/cfparse.y, + src/libipsec/policy_parse.y, src/racoon/cfparse.y, + src/racoon/cftoken.l, src/racoon/crypto_openssl.c, + src/racoon/getcertsbyname.c, src/racoon/grabmyaddr.c, + src/racoon/ipsec_doi.c, src/racoon/isakmp.c, + src/racoon/isakmp_inf.c, src/racoon/pfkey.c, + src/racoon/plainrsa-gen.c, src/racoon/sockmisc.c, + src/racoon/sockmisc.h, src/racoon/racoonctl.c: made compile + with gcc-4.0 (20050410 prerelease) + +2005-04-20 Aidas Kasparas + + From: Ganesan Rajagopal + * configure.ac: fix --enable-ipv6 logic + +2005-04-19 Yvan Vanhullebus + + * src/racoon/remoteconf.c: fixed dupisakmpsa() and dhgroup. + +2005-04-18 Aidas Kasparas + + * src/racoon/crypto_openssl.c: fixed single DES support; + * NEWS: noted fix + +2005-04-18 Emmanuel Dreyfus + + * src/racoon/isakmp_base.c: DPD support, fix memory leak + + From Thomas Klausner + * src/libipsec/{ipsec_set_policy.3|ipsec_strerror.3} + src/racoon/{admin.c|plainrsa-gen.8|racoon.8|racoon.conf.5|racoonctl.8} + src/racoon/samples/{racoon.conf.in|racoon.conf.sample} + src/racoon/samples/racoon.conf.sample-gssapi + src/racoon/samples/racoon.conf.sample-inherit + src/racoon/samples/racoon.conf.sample-natt + src/racoon/samples/racoon.conf.sample-plainrsa + src/racoon/samples/roadwarrior/README + src/racoon/samples/roadwarrior/server/phase1-down.sh + src/setkey/setkey.8: docmumentation fixes + + From KAME + * src/racoon/ipsec_doi.c: wrong check on SA lifebyte + + From Fred Senault + * src/racoon/{cfparse.y|cftoken.l} drop split_net_type directive, + which is now incoprated into split_net_tunnels + * src/raccon/{isakmp.c|isakmp_cfg.c|isakmp_cfg.h|isakmp_xauth.c} + src/racoon/isakmp_xauth.h: support login and password sent + in different packets during the Xauth exchange. This makes racoon + interoperable with SecureComputing's sidewinder + * src/racoon/{strnames.c|strnames.h}: more debug strings for Xauth + +2005-04-17 Yvan Vanhullebus + + * src/racoon/handler.c: Configuration reload validation code + * src/racoon/handler.h:revalidate_ph12() function + * src/racoon/ipsec_doi.c: duplicates iph1->approval in + get_ph1approval(), some fields sets to NULL when needed + * src/racoon/isakmp_inf.[ch]: purge_ipsec_spi() is now public + * src/racoon/localconf.[ch]: save/restore_params() functions + * src/racoon/main.c: moved restore_params functions to localconf + * src/racoon/remoteconf.c: save_rmconf() functions, dupisakmpsa() + function, some values set to NULL when needed + * src/racoon/remoteconf.h: save_rmconf() functions, dupisakmpsa() + function + * src/racoon/sainfo.[ch]: save_sainfotree() functions + * src/racoon/session.c: Reloads conf on a SIGHUP without loosing + existing tunnels + +2005-04-15 Aidas Kasparas + + From Zilvinas Valinskas : + * configure.ac: + - cross-compile type fix (patch 1); + - --enable-{frag|hybrid}=no fixes (patches 6,7); + - support for --with-flex, --with-flexlib (patch 11); + - GLIBC_BUGS assignment correction (patch 14 with mods). + * src/racoon/isakmp.c: fix compilation when hybrid disabled. + +2005-04-11 Emmanuel Dreyfus + + * src/racoon/rfc/{rfc2407.txt|rfc2408.txt: new files + RFC for IPsec DOI and ISAKMP + +2005-04-10 Emmanuel Dreyfus + + * src/racoon/isakmp_base.c: resurect RSASIG support + * src/racoon/isakmp_ident.c: missing support for hybrid auth + * src/racoon/{isakmp_base.c|oakley.c}: missing bits for hybrid/base mode + +2005-04-09 Emmanuel Dreyfus + + * src/racoon/{algorithm.c|algorithm.h|cftoken.l|ipsec_doi.c} + src/racoon/{isakmp.c|isakmp_agg.c|isakmp_ident.c|isakmp_base.c} + src/racoon/{isakmp_frag.h|isakmp_xauth.c|oakley.c|racoon.conf.5}: + Add Xauth + RSASIG, for client and server. Add all Xauth and + IKE fragmentation logic to base and ident mode. + * src/libipsec/{pfkey.c|pfkey_dump.c} + src/setkey/parse.y: more missing TCP_MD5 bits from KAME + +2005-04-08 Emmanuel Dreyfus + + * src/racoon/cfparse.y: a list of network can be specified for split + tunnelling + * src/racoon/{isakmp_cfg.c|racoon.conf.5}: add INTERNAL_CIDR4, the + netmask in CIDR notation, to the hook script environement. + * src/setkey/{token.l|parse.y|setkey.8}: KAME backport of missing + bits for TCP_MD5 support. + + From Fred Senault + * src/racoon/{cfparse.y|cftoken.l|ipsec_doi.c|ipsec_doi.h} + src/racoon/racoon.conf.5: KEYID identifier can be taken from + a file or from a quoted string + +2005-04-05 Emmanuel Dreyfus + + From Fred Senault + * src/racoon/admin.c: fix the admin interface that was left behind + after recent Xauth changes + * src/racoon/{cfparse.y|isakmp_xauth.c|isakmp_xauth.h|oakley.c} + src/racoon/{remoteconf.c|remoteconf.h}: factor Xauth info in + remote conf within a single structure. + * src/racoon/{isakmp.c|isakmp_cfg.c}: on client side, do not run + phase1-up script before ISAKMP mode config is done + * src/racoon/isakmp_inf.c: log a buggy condition + * src/racoon/{isakmp.c|isakmp_agg.c|isakmp_base.c|isakmp_ident.c} + src/racoon/{oakley.c|oakley.h}: Use the AUTHMETHOD macro to + distinguish between XAUTH PSK and Kerberos authentications + * src/racoon/{oakley.c|remoteconf.c}: set a default for certificate + requests + * src/racoon/isakmp_xauth.c: Fix serious security bug introduced + on 2005-03-09: Xauth validation was required for phase 2 on the + client (thus blocking phase 2), but not on the server (thus + making it open regardless of Xauth exchange). + * src/racoon/vendorid.c: dump unknown VIDs + + +2005-04-06 Yvan Vanhullebus + + * src/racoon/crypto_openssl.c: Disable OpenSSL padding in + evp_crypt(), because it may cause some interoperability problems. + Solution reported by Ganesan Rajagopal. + +2005-04-05 Emmanuel Dreyfus + + * src/racoon/main.c: build with hybrid but without libradius + +2005-04-05 Yvan Vanhullebus + + * src/racoon/handler.h: added a flag to identify generated policies + * src/racoon/isakmp.c: changed logging in isakmp_ph1expire() + * src/racoon/isakmp_inf.c: use iph2->generated_spidx to check if + policy have been generated in purge_remote_spi() + * src/racoon/isakmp_quick.c: sets iph2->generated_spidx for + generated policies + * src/racoon/pfkey.c: reactivated the unbindph12() in pk_recvupdate() + +2005-04-04 Emmanuel Dreyfus + + * src/racoon/isakmp_cfg.c: fix a buffer overrun in mode config SET + +2005-03-30 Michal Ludvig + + * configure.ac: Don't compile with NAT-T by default (according to + documentation, finally :-) + +2005-03-27 Michal Ludvig + + From Zilvinas Valinskas : + * configure.ac: + - Use AC_CHECK_HEADER for kernel headers instead of AC_CHECK_FILE. + - Fix OpenSSL check for cross-compilation. + * acracoon.m4(RACOON_CHECK_VA_COPY): Allow cross-compilation. + (RACOON_CHECK_BUGGY_GETADDRINFO): Ditto. + +2005-03-16 Emmanuel Dreyfus + + * src/racoon/privsep.c: check for NULL path in unsafe_path() + * src/racoon/privsep.c: missing space + +2005-03-15 Emmanuel Dreyfus + + * src/racoon/{cfparse.y|cftoken.l|isakmp.c|isakmp_cfg.c|isakmp_cfg.h} + src/racoon/{isakmp_var.h|isakmp_xauth.c|localconf.h|privsep.c} + src/racoon/{privsep.h|racoon.conf.5|remoteconf.c|remoteconf.h} + src/racoon/main.c: Remove most of config dependency from + privilegied instance for upcoming config reload patch. + * src/racoon/isakmp_cfg.h: fix the application version for Xauth + * src/racoon/isakmp_cfg.c: only call cleanup_pam when PAM is used + +2005-03-14 Emmanuel Dreyfus + + * configure.ac: handle correctly dynamic libradius + * src/racoon/cfparse.y: correctly initialize address pool + +2005-03-13 Yvan Vanhullebus + + * src/racoon/isakmp.c: Fixed a buffer underrun (CAN-2005-0398) + +2005-03-09 Emmanuel Dreyfus + + From Fred Senault + * src/racoon/cfparse.y: endainness bugfix + * src/racoon/isakmp_xauth.c: off by one bugs in strings + * src/racoon/oakley.h: missing parenthesis causing bugs + +2005-03-09 Emmanuel Dreyfus + + * src/racoon/isakmp_xauth.c: fix a crash when using RADIUS auth + +2005-03-07 Emmanuel Dreyfus + + From Fred Senault + * src/racoon/{algorithm.c|algorithm.h|cfparse.y|cftoken.l} + src/racoon/{handler.c|ipsec_doi.c|ipsec_doi.h|isakmp.c} + src/racoon/{isakmp_agg.c|isakmp_base.c|isakmp_cfg.c|isakmp_cfg.h} + src/racoon/{isakmp_ident.c|isakmp_inf.c|isakmp_quick.c} + src/racoon/{isakmp_unity.c|isakmp_xauth.c|kmpstat.c|oakley.c} + src/racoon/{oakley.h|plainrsa-gen.8|privsep.c|racoon.conf.5} + src/racoon/{racoonctl.c|remoteconf.c|remoteconf.h|strnames.c} + src/racoon/{strnames.h|throttle.c}: Support plain Xauth, split + tunnelling, multiple DNS & WINS in ISAKMP mode config. + +2005-03-02 Yvan Vanhullebus + + * src/racoon/isakmp_quick.c: tunnel_mode_prop() is now public + * src/racoon/isakmp_inf.c: fixed compilation if HAVE_POLICY_FWD. + +2005-03-01 Yvan Vanhullebus + + * src/racoon/oakley.c: fixed oakley_newiv2() when errors + +2005-02-24 Emmanuel Dreyfus + + * src/racoon/privsep.c: safety check port numbers given by the + unprivilegied instance. + * src/racoon/racoonctl.8: display fixes in racoonctl(8) + +2005-02-23 Emmanuel Dreyfus + + * configure.ac, src/racoon/{Makefile.am|crypto_openssl.c}: optionnal + support for patented algorithms: IDEA and RC5. + * src/racoon/{isakmp_xauth.c|main.c}: don't initialize RADIUS if it + is not required in the configuration + * src/racoon/isakmp.c: do not reject addresses for which kernel + refused UDP encapsulation, they can still be used for non NAT-T + traffic (eg: NAT-T enabled racoon on non NAT-T enabled kernel) + * src/libipsec/libpfkey.h: prefer __inline to inline + * src/racoon/{cfparse.y|cftoken.l|localconf.c|localconf.h|privsep.c} + src/racoon/racoon.conf.5: Add chroot capability + +2005-02-18 Emmanuel Dreyfus + + * src/racoon/{main.c|eaytest.c|plairsa-gen.c} + src/setkey/setkey.c: don't use fuzzy paths for package_version.h + +2005-02-18 Michal Ludvig + + * configure.ac, rpm/suse/ipsec-tools.spec.in, + rpm/suse/Makefile.am: Distribute .spec file with + resolved version string. + * src/racoon/Makefile.am: Allow parallel cluster build. + +2005-02-17 Emmanuel Dreyfus + + From Fred Senault + * src/racoon/remoteconf.c: Fix a bug in script init + +2005-02-17 Yvan Vanhullebus + + * src/racoon/ipsec_doi.c: Workaround for phase1 lifetime checks + +2005-02-16 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: Purge generated SPDs when getting a + related DELETE_SA + * src/racoon/pfkey.c: do NOT unbindph12() when SA acquire + +2005-02-15 Michal Ludvig + + * configure.ac: Changed --enable-natt_NN to --enable-natt-versions=NN,NN + +--------------------------------------------- + + Branch for 0.6 created (ipsec-tools-0_6-branch) + +2005-02-11 Emmanuel Dreyfus + + From Jason Thorpe + * src/raccon/samples/racoon.conf.sample-gssapi + src/racoon/{cfparse.y|cftoken.l|gssapi.c|gssapi.h|ipsec_doi.c} + src/racoon/{localconf.c|localconf.h|racoon.conf.5} + configure.ac: Multiple GSSAPI fixes to get interoperability + with Microsoft IKE. + +2005-02-09 Emmanuel Dreyfus + + * src/racoon/{cfparse.y|isakmp_cfg.c|isakmp_cfg.h|isakmp_xauth.c} + src/racoon/{isakmp_xauth.h|main.c|privsep.c|privsep.h} + src/racoon/racoon.conf.5: Make PAM work with privilege separation + +2005-02-07 Michal Ludvig + + From Krisztian Kovacs: + * src/racoon/cfparse.y: Allocate correct space for "struct sockaddr". + +2005-01-30 Yvan Vanhullebus + + * src/racoon/vmbuf.c: bugfix in vrealloc() + * src/racoon/oakley.c: mem leak fix in INITDHVAL() + * src/racoon/session.c: mem leak fix in check_flushsa() + +2005-01-29 Yvan Vanhullebus + + * src/racoon/isakmp_{ident|agg}.c: NAT-T cleanup + * src/racoon/pfkey.c: Uses NATT encaps_type in pk_sendupdate() + * src/racoon/vendorid.[ch]: NAT-T cleanup, NATT_01 VID + * src/racoon/nattraversal.[ch]: NATT cleanup, support for all + drafts (disabled by default) / RFC. + * src/racoon/isakmp.h: NATT cleanup for NATT RFC support + * src/racoon/ipsec_doi.h: updated comments about NATT + * configure.ac: enable-natt_XX options + * src/racoon/isakmp.c: set UDP_ENCAPS_ESPINUDP_NON_IKE option when needed + + +2005-01-29 Emmanuel Dreyfus + + From Fred Senault + * src/racoon/pfkey.c: Update SAD even if NAT-T is disabled, so that + phase2 can start. + +2005-01-23 Emmanuel Dreyfus + + * src/setkey/{sekkey.8|setkey.c|token.l|parse.y}: implement NetBSD's + SADB_X_AALG_TCP_MD5. Resurrect setkey -h meaning on NetBSD. + +2005-01-22 Emmanuel Dreyfus + + From Fred Senault + * src/racoon/{cftoken.l|cfparse.y|raccon.conf.5} + src/racoon/samples/roadwarrior/README: change "my_identifier login" + into "xauth_login" in the config file so that we can introduce Xauth + with a pre-shared key later. + +2005-01-21 Emmanuel Dreyfus + + * src/racoon/samples/roadwarrior/client/{phase1-up.sh|phase1-down.sh}: + workaround Linux problems. This needs a better fix. + +2005-01-18 Emmanuel Dreyfus + + * src/racoon/privsep.c: build without ENABLE_HYBRID + +2005-01-14 Emmanuel Dreyfus + + * src/raccon/rfc/{rfc3947.txt|rfc3948.txt}: new files (NAT-T) + +2005-01-13 Yvan Vanhullebus + + * src/racoon/ipsec_doi.c: Uses proposal_check value to check phase + 1 lifetime. + * src/racoon/racoon.conf.5: Updated racoon man page for phase 1 + lifetime check / proposal_check. + +2005-01-11 Emmanuel Dreyfus + + * src/racoon/isakjmp_quick.c: endianness bugfix from KAME + +2005-01-07 Emmanuel Dreyfus + + * src/racoon/{cfparse.y|cftoken.l|nattraversal.h|pfkey.c} + src/racoon/{racoon.conf.5|remoteconf.c|remoteconf.h} + src/libipsec/{libpfkey.h|pfkey.c}: ESP fragmentation size is + now configurable (supported only on NetBSD so far). + +2005-01-05 Emmanuel Dreyfus + + * src/racoon/privsep.c: Build again on Linux with privsep + +2005-01-03 Emmanuel Dreyfus + + * src/racoon/{isakmp_cfg.c|isakmp_cfg.h|isakmp_xauth.c|isakmp_xauth.h} + src/racoon/{cfparse.y|cftoken.l|racoon.conf.5} + src/racoon/doc/FAQ + configure.ac: PAM support for authentication and accounting in + hybrid auth + +2005-01-02 Emmanuel Dreyfus + + * src/racoon/admin.c: never fork, it buys nothing an break on some + operations + +2004-12-30 Emmanuel Dreyfus + + * src/racoon/{Makefile.am|admin.h|cfparse.y|cftoken.l|isakmp.c} + src/racoon/{isakmp_cfg.c|isakmp_cfg.h|isakmp_var.h| isakmp_xauth.c} + src/racoon/{localconf.c|localconf.h|main.c|oakley.c|pfkey.c} + src/racoon/{racoon.conf.5|remoteconf.c|remoteconf.h|session.c} + src/racoon/{privsep.c|privsep.h}: new files + Privilege separation + + * src/racoon/{Makefile.am|admin.h|admin_var.h|kmpstat.c} + src/racoon/{racoonctl.c|racoonctl.h}: new files + configure.ac: publically export the adminport interface so that + external program can control racoon + + * src/racoon/{racoonctl.c|racoonctl.h|kmpstat.c}: Add interface + versionning + + * src/racoon/admin.h: make sure no / will be missing in adminsock path + +--------------------------------------------- + + Branch for 0.5 created (ipsec-tools-0_5-branch) + +2004-12-23 Yvan Vanhullebus + + * src/racoon/crypto_openssl.c: Indentation + +2004-12-28 Yvan Vanhullebus + + * src/racoon/crypto_openssl.c: Fixed eay_get_x509subjectaltname() + when getting an IP (Bug # 1092095) + + +2004-12-26 Emmanuel Dreyfus + + * src/racoon/session.c: remove outdated comment + +--------------------------------------------- + + 0.5.beta2 released + +2004-12-21 Michal Ludvig + + * src/racoon/pfkey.c: Fix AES vs Rijndael defines. + +2004-12-20 Yvan Vanhullebus + + * configure.ac, src/racoon/isakmp.c, src/racoon/pfkey.c: + Some FreeBSD / NATT support. + +2004-12-17 Emmanuel Dreyfus + + * src/racoon/isakmp.c: only IPv4 NAT-T is supported, so skip IPv6 here. + * src/racoon/pfkey.c: Restore AES support on NetBSD. + +2004-12-17 Yvan Vanhullebus + + * src/racoon/crypto_openssl.c: Uses sprintf() instead of + asprintf() in eay_get_x509subjectaltname(), because of some + compilation problems reported with asprintf() on some platforms. + * src/racoon/oakley.c: just take the first cert in + oakley_savecert() if cert ID check is disabled. + +2004-12-16 Emmanuel Dreyfus + + * src/racoon/crypto_openssl.c: Build again on NetBSD + * src/racoon/samples/roadwarrior/server/racoon + src/racoon/samples/roadwarrior/server/racoon.conf-radius + src/racoon/samples/roadwarrior/README: Use DPD in sample files. + +2004-12-16 Yvan Vanhullebus + + * src/racoon/crypto_openssl.c: Fixed eay_get_x509subjectaltname() + when SubjectAltName contains an IP. OpenSSL code from Ludovic + Flament (ludovic.flament@free.fr). + +--------------------------------------------- + + 0.5.beta1 released + +2004-12-13 Michal Ludvig + + From Ganesan R : + * src/racoon/Makefile.am, src/setkey/Makefile.am: Fix compilation + with shared libraries. + +2004-12-10 Yvan Vanhullebus + + * src/racoon/oakley.c: takes the first certificate which matches + the Identity, instead of just taking the first certificate. + +2004-12-07 Yvan Vanhullebus + + * src/racoon/isakmp_inf.c: Set spi_size for R-U-THERE/R-U-THERE-ACK. + +2004-12-04 Aidas Kasparas + + * src/libipsec/pfkey_dump.c: distinguish per-socket policies from + general ones (Linux case); + * src/racoon/pfkey.c: dito, do not negotiate policies if racoon + do not listen on out tunnel's source address. + +2004-12-01 Yvan Vanhullebus + + * src/racoon/isakmp_agg.c: code cleanup in NATT / DPD VIDs + generation in r1send() + +2004-12-01 Yvan Vanhullebus + + * src/racoon/remoteconf.{c|h}: DPD support option (enabled by default) + * src/racoon/{cfparse.y|cftoken.l}: DPD token, yyerror if DPD + parameters but compiled without ENABLE_DPD + * src/racoon/isakmp_{agg|ident}.c: Send DPD VID only if DPD + support activated in configuration + +2004-11-30 Emmanuel Dreyfus + + * src/racoon{evt.c|evt.h|admin.c}: init event queue at compile time, + to avoid garbage pointer if admin port is disabled. + * src/racoon/{throttle.c|throttle.h}: new files + src/racoon/{Makefile.am|isakmp_cfg.c|isakmp_xauth.c|racoon.conf.5} + configure.ac: Add a per-host throttling count. When throttling, + don't sleep, schedule the answer for later instead. + * src/racoon/kmpstat.c: default with no hexdump of the packet + * src/racoon/admin.c: don't remove admin socket after first request, + on the other hand remove on startup stale sockets left by + crashed racoon. + * src/racoon/samples/roadwarrior/README + src/racoon/kmpstat.c: fix option parsing problem on Linux + +2004-11-29 Yvan Vanhullebus + + * src/racoon/session.c: Only listen on pfkey socket when received + shutdown signal + +2004-11-28 Emmanuel Dreyfus + + * src/racoon/{cfparse.y|cftoken.l|isakmp_cfg.c|isakmp_cfg.h} + src/racoon/{isakmp_xauth.c|racoon.conf.5}: Add a one second throttle + on each Xauth authentication to avoid brute force attacks + +2004-11-24 Emmanuel Dreyfus + + * src/racoon/samples/roadwarrior/README + src/racoon/samples/roadwarrior/client{phase1-up.sh|phase1-down.sh} + src/racoon/samples/roadwarrior/client/{racoon.conf|racoon.conf-radius} + src/racoon/samples/roadwarrior/server/{racoon.conf|phase1-down.sh}: + Fill Linux gaps for hybrid auth client, Replace public IP by + private and example IP in the sample config files. + +2004-11-24 Emmanuel Dreyfus + + DPD patch from Yvan Vanhullebus + * src/racoon/cfparse.y: missing bits for DPD support + +2004-11-23 Aidas Kasparas + + * src/setkey/parse.y: generate require fwd policies for unique in + policies. + * src/setkey/setkey.c: made -r/-k options awailable only when + system has FWD policies. + * src/setkey/setkey.8: updated docs about change above. + +2004-11-22 Michal Ludvig + + * src/racoon/{admin.c,pfkey.c}: Wrap adminport-parts to + #ifdef ENABLE_ADMINPORT/#endif. + +2004-11-22 Michal Ludvig + + Revert these changes (ludvigm, 2004-11-18): + * src/racoon/Makefile.am: install sample racoon.conf and psk.txt. + * src/setkey/Makefile.am: Install setkey.conf. + +2004-11-22 Emmanuel Dreyfus + + * src/raccon/{isakmp_cfg.c|isakmp_cfg.h|isakmp_xauth.c}: defer phase 1 + removal so that it's not used after been deleted. + * src/racoon/{evt.h|isakmp.c|isakmp_agg.c|isakmp_base.c|session.c} + src/racoon/{isakmp_ident.c|isakmp_inf.c|kmpstat.c}: report more + errors to racoonctl + +2004-11-21 Emmanuel Dreyfus + + * src/racoon/doc/FAQ: NAT-T kernel patch for NetBSD is now on + the ipsec-tools web site + * src/racoon/{kmpstat.c|racoonctl.8}: New racoonctl command to + display all events reported by racoon: show-event + * src/racoon/isakmp_cfg.c: don't send ISAKMP mode config message + with immature or dying phase 1 + * src/racoon/kmpstat.c: racoonctl vd awaits phase 1 to get down + +2004-11-20 Emmanuel Dreyfus + + * src/racoon/isakmp_agg.c: for hybrid auth client, advertise ourself + as Unity compliant. + * src/racoon/{evt.c|evt.h}: new files + src/racoon/{Makefile.am|admin.c|admin.h|isakmp.c|isakmp_cfg.c} + src/racoon/{isakmp_xauth.c|kmpstat.c|pfkey.c}: framework for + event reporting from racoon to racoonctl + +2004-11-20 Aidas Kasparas + + * src/racoon/grabmyaddr.c: Prevent doubling addresses and error messages + when racoon is compiled with INET6 support and kernel is not. + Fixed with help of Zilvinas Valinskas. + * src/racoon/{var.h|sockmisc.c}: Fixed compilation with gcc-3.4.2+ + problem. + +2004-11-19 Emmanuel Dreyfus + + * src/racoon/doc/FAQ: more options and warn about software patents. + +2004-11-18 Emmanuel Dreyfus + + * src/racoon/vmbuf.c: don't allocate zero-length buffer + * src/racoon/samples/roadwarrior/client/phase1-down.sh + src/racoon/samples/roadwarrior/server/phase1-down.sh: Also + flush SAD when disconnecting. + * src/racoon/admin.c: Send a notification when deleting ISAKMP SA + * src/racoon/samples/roadwarrior/README: accomodate the recent + sysconfdir change + +2004-11-18 Michal Ludvig + + * src/racoon/Makefile.am: Fix adminsocket dir, install sample + racoon.conf and psk.txt. + * src/racoon/localconf.h: Look for racoon.conf in $(SYSCONFDIR), + not $(SYSCONFDIR)/racoon. + * src/racoon/algorithm.h, src/racoon/eaytest.c, + src/racoon/schedule.h, src/racoon/gnuc.h: Build fixes for really + strict environments. + * src/setkey/setkey.conf: Yet another sample config file. + * src/setkey/Makefile.am: Install setkey.conf. + * rpm/suse/{ipsec-tools.spec.in,sysconfig.racoon,racoon.init}: New + files. + * rpm/suse/{Makefile.am,.cvsignore}: New files. + * configure.ac, rpm/Makefile.am: Build in rpm/suse. + +2004-11-17 Aidas Kasparas + + * configure.ac: paste bugfix by Zilvinas Valinskas + * src/racon/{isakmp_quick.c|policy.c|strnames.c}: fwd policy support + for generated policies. Path by Patrick McHardy. + +2004-11-16 Emmanuel Dreyfus + + * src/racoon/racoonctl.8: racoonctl man page (new file) + +2004-11-16 Emmanuel Dreyfus + + From Ganesan + * src/racoon/ipsec_doi.c: fix free'd memory access + +2004-11-16 Michal Ludvig + + DPD patch from Yvan Vanhullebus + * configure.ac, src/racoon/cfparse.y, src/racoon/cftoken.l, + src/racoon/handler.c, src/racoon/handler.h, + src/racoon/isakmp.c, src/racoon/isakmp.h, + src/racoon/isakmp_agg.c, src/racoon/isakmp_ident.c, + src/racoon/isakmp_inf.c, src/racoon/isakmp_inf.h, + src/racoon/racoon.conf.5 src/racoon/remoteconf.c, + src/racoon/remoteconf.h, src/racoon/vendorid.c, + src/racoon/vendorid.h: Dead Peer Detection (DPD) support. + +2004-11-16 Michal Ludvig + + * configure.ac: Remove a bash-specific construction, take II. + * src/racoon/grabmyaddr.c: FreeBSD fix for headers. + +2004-11-15 Michal Ludvig + + * configure.ac: Use correct include paths during ./configure run. + * src/racoon/Makefile.am: Compile cftoken.l from $(srcdir), + remove samples/racoon.conf.sample-cvpn, added samples/roadwarrior + (hint, hint, manu :-)) + +2004-11-15 Emmanuel Dreyfus + + * README: update the docs + * src/racoon/doc/FAQ: update the docs + * configure.ac: Remove a bash-specific construction + +2004-11-14 Aidas Kasparas + + * src/racoon/cfparse.y: ensure that returns from rules are + initialized even on erroneous config file. + * src/racoon/admin_var.h: changed management socket location + * src/racoon/Makefile.am: ditto, added rule to install directory + for management socket. + * src/setkey/{setkey.c|parse.y}: introduced rfc/kernel modes, + added generation of fwd policies for every in policy spdadd'ed. + * src/setkey/setkey.8,src/libipsec/ipsec_set_policy.3: updated docs + * src/setkey/policy_token.l: return something reasonable when + fwd direction is parsed on systems with no forward policy + support. + +2004-11-14 Emmanuel Dreyfus + + * src/racoon/isakmp.c: avoid a double free when using IKE fragmentation + * src/racoon/{backupsa.c|ipsec_doi.c|localconf.c|str2val.c} + src/{libipsec/key_debug.c|setkey/parse.y}: fix build warnings + * configure.ac src/racoon/{admin.c|admin_var.h} + src/racoon/racoon.conf.5 src/racoon/samples/roadwarrior/README + src/racoon/samples/roadwarrior/client/racoon.conf: make the default + mode for the admin socket more secure. + +2004-11-13 Emmanuel Dreyfus + + * src/racoon/{cfparse.y|remoteconf.c|crypto_openssl.c|crypto_openssl.h} + src/racoon/{eaytest.c|oakley.c|racoon.conf.5|cftoken.l|remoteconf.h} + src/racoon/samples/roadwarrior/README + src/racoon/samples/roadwarrior/client/racoon.conf: Make the root + certificate authority location per-peer and configurable. + * src/racoon/isakmp_frag.c: fix unallocated memory access + * src/racoon/isakmp_agg.c: fix incorrect queue deallocation + * src/racoon/remoteconf.c: fix uninitialized data + * src/racoon/{admin.c|isakmp_xauth.c}: fix free'ed memory access + +2004-11-12 Emmanuel Dreyfus + + * src/racoon/{Makefile.am|kmpstat.c}: Make racoonctl vc and vd + commands IPv6 friendly. + * src/racoon/{admin.c|admin.h|handler.c|handler.h|kmpstat.c}: + Add an admin message to flush all the SA for a given peer. + Convert racoonctl vd to use it. + * src/racoon/{admin.c|kmpstat.c|cftoken.l|cfparse.y} + src/racoon/{admin_var.h|admin.h|raccon.conf.5}: Enable the + administrator to choose the admin socket path, ownership and mode. + * src/racoon/sample/roadwarrior: complete config files for + road warriors using hybrid authentication. + +2004-11-12 Michal Ludvig + + * configure.ac: Config option --enable-natt=kernel + * src/racoon/Makefile.am: Distribute only yacc/lex source files, + not the preprocessed .c files. + +2004-11-11 Emmanuel Dreyfus + + * src/racoon/samples/racoon.conf.sample-cvpn: more complete setup + and comments in the VPN concentrator setup for the Cisco VPN client + * src/racoon/racoon.conf.5: fix documentation + * src/racoon/isakmp_cfg.c: get the internal IPv4 address in script + hooks event if we are a server. + +2004-11-10 Emmanuel Dreyfus + + * src/racoon/{ipsec_doi.c|remoteconf.c}: fix LP64 problems + +2004-11-09 Michal Ludvig + + * Makefile.am: Remove aclocal-related lines. + * src/racoon/Makefile.am: Add isakmp_frag.h into noints_HEADERS + * configure.ac: Cleanup, define INET6 if IPv6 shoud be supported, + better handling of KRB5 and NAT-T. + * src/racoon/{isakmp_cfg.c,isakmp_frag.c,isakmp_unity.c}: Make + FreeBSD happy with includes (Arrgh...&^#$^@!!!) + +2004-11-08 Michal Ludvig + + * src/libipsec/policy_parse.y: Define INT32_MAX/INT32_MIN. + * src/libipsec/policy_token.l, src/racoon/kmpstat.c, + src/racoon/{pfkey.c,prsa_par.y,rsalist.c,token.l}: Small + fixes to support FreeBSD (tested with 4.10). + +2004-11-05 Michal Ludvig + + * configure.ac: Add --with-readline switch. + * src/setkey/setkey.c(stdin_loop): Fix newlines and comments + when compiled without readline. + +2004-11-01 Aidas Kasparas + + * src/racoon/isakmp_quick.c: generated policy refresh patch + by Yvan Vanhullebus + +2004-10-29 Michal Ludvig + + * configure.ac: Check for IPSEC_DIR_FWD and eventually define + HAVE_POLICY_FWD. + * src/libipsec/{ipsec_dump_policy.c,policy_token.l}: Use + HAVE_POLICY_FWD in ifdefs. + * NEWS: Mention the fix. + * src/racoon/kmpstat.c: Fix compilation on Linux. + * src/racoon/ipsec_doi.h: Ditto. + * src/racoon/Makefile.am, src/setkey/Makefile.am: Update + explicit dependencies. + +2004-10-29 Emmanuel Dreyfus + + * src/racoon/{isakmp_cfg.h,grabmyaddr.c,handler.c,handler.h}: + do not reconfigure internal addresses obtained through ISAKMP + mode config. + * src/racoon/{isakmp.c,isakmp_cfg.c,isakmp_xauth.c}: On authentication + failure, kill the phase 1 and log the failure. Do not run the sa_up + script in this case. + * src/racoon/{admin.c,admin.h,isakmp_xauth.c,kmpstat.c,remoteconf.h}: + Add -u user to racoonctl establish-sa, prompt for the PSK from + the terminal, and add a vpn-connect target with simplified syntax + for establishing a SA in the road warrior case. + * src/racoon/{admin.c,kmpstat.c}: implement delete-sa and + vpn-disconnect commands of racoonctl + * src/racoon/{cfparse.y,cftoken.l,handler.c,isakmp.c,isakmp_cfg.c} + src/racoon/{isakmp_var.h,racoon.conf.5,remoteconf.c,remoteconf.h}: + Remove sa_up and sa_down and replace them by a more general + script hook framework. + +2004-10-27 Emmanuel Dreyfus + + * src/racoon/nattraversal.c: Use macros instead of magic numbers + * src/racoon/kmpstat.c: pull up fixes from KAME so that racoonctl + can actually establish a SA + * src/racoon/{cfparse.y,cftoken.l,handler.c,isakmp.c,isakmp_cfg.c} + src/racoon/{isakmp_var.h,racoon.conf.5,remoteconf.c,remoteconf.h}: + Shell script hooks for ISAKMP SA creation and removal + +2004-10-26 Emmanuel Dreyfus + + * src/racoon/rfc/draft-ietf-ipsec-isakmp-hybrid-auth-05.txt: removed + src/racoon/rfc/draft-ietf-ipsec-isakmp-mode-cfg-04.txt: removed + src/racoon/rfc/draft-beaulieu-ike-xauth-02.txt: new file + src/racoon/rfc/draft-dukes-ike-mode-cfg-02.txt: new file + Update to the latest drafts + +2004-10-25 Emmanuel Dreyfus + + * src/racoon/rfc/draft-ietf-ipsec-isakmp-hybrid-auth-05.txt: new file + src/racoon/rfc/draft-ietf-ipsec-isakmp-mode-cfg-04.txt: new file + src/racoon/rfc/draft-ietf-ipsec-isakmp-xauth-07.txt: new file + drafts documenting ISAKMP mode config, Xauth and hybrid auth + * src/racoon/cftoken.l: fix build problem, add an error message + when using hybrid auth options while hybrid auth is not built + * src/racoon/isakmp_cfg.c: build without RADIUS support too + +2004-10-24 Emmanuel Dreyfus + + * src/racoon/{algorithm.c,algorithm.h,cfparse.y,cftoken.l} + src/racoon/{ipsec_doi.c,ipsec_doi.h,isakmp.c,isakmp_agg.c} + src/racoon/{isakmp_cfg.c,isakmp_cfg.h,isakmp_xauth.c,isakmp_xauth.h} + src/racoon/{oakley.c,oakley.h,racoon.conf.5} + src/racoon/{remoteconf.c,remoteconf.h,strnames.c}: Client side + of hybrid auth and ISAKMP mode config + +2004-10-24 Emmanuel Dreyfus + + * src/racoon/{cfparse.y,cftoken.l,handler.h,isakmp.c} + src/racoon/{isakmp_agg.c,isakmp_base.c,isakmp_frag.c,isakmp_frag.h} + src/racoon/{isakmp_inf.c,racoon.conf.5,remoteconf.c,remoteconf.h}: + Receiver-side of IKE fragmentation + +2004-10-24 Emmanuel Dreyfus + + * src/racoon/isakmp_cfg.c: Fix read buffer overflow + * src/racoon/isakmp_xauth.c: Fix weak authentication + * src/racoon/{oakley.c,oakley.h}: Fix weak authentication + +2004-10-21 Michal Ludvig + + From Emmanuel Dreyfus: + * src/racoon/{isakmp_frag.c,isakmp_frag.h}: New files. + * src/racoon/isakmp_cfg.c: Fix endianness. + +2004-10-20 Michal Ludvig + + From Emmanuel Dreyfus: + * src/racoon/{cfparse.y,cftoken.l,handler.c}, + src/racoon/{isakmp_cfg.c,isakmp_cfg.h,isakmp_xauth.c}, + src/racoon/racoon.conf.5: RADIUS IP addresses allocation + and RADIUS accounting. + * configure.ac, + src/racoon/{Makefile.am,handler.h,isakmp.c,isakmp.h}, + src/racoon/{isakmp_agg.c,isakmp_base.c,isakmp_inf.c}, + src/racoon/{vendorid.c,vendorid.h}: IKE Fragmentation patch. + +2004-10-08 Michal Ludvig + + * src/racoon/isakmp_cfg.c: Fixes from Emmanuel Dreyfus. + +2004-10-06 Aidas Kasparas + + * src/racoon/remoteconf.c: dupidvl(), dupetypes() - new functions + to duplicate dynamically allocatd structures; duprmconf() - call + these functions to produce private copy of inherited id and etype + structures. + * src/racoon/remoteconf.c: declaration for dupetypes(). + +2004-10-04 Aidas Kasparas + + * src/racoon/cfparse.y: check inherited_from dereferencing + * src/racoon/crypto_openssl.c: prevent crash on incorect DNs + +2004-09-27 Michal Ludvig + + From KOVACS Krisztian : + * src/racoon/sockmisc.c(sendfromto): Set src address. + +2004-09-24 Aidas Kasparas + + * configure.ac: added check for linux-gnu, as my box reports + * src/racoon/grabmyaddr.c: added missing include + +2004-09-21 Michal Ludvig + + Merged 'autoconf' branch to mainline: + * .cvsignore, ChangeLog, Makefile.am, bootstrap, configure.ac, + src/racoon/.cvsignore, src/racoon/cfparse.y, + src/racoon/crypto_openssl.c, src/racoon/crypto_openssl.h, + src/racoon/ipsec_doi.c, src/racoon/isakmp.c, + src/racoon/isakmp_agg.c, src/racoon/isakmp_base.c, + src/racoon/isakmp_cfg.c, src/racoon/isakmp_ident.c, + src/racoon/isakmp_unity.c, src/racoon/main.c, + src/racoon/nattraversal.c, src/racoon/oakley.c, + src/racoon/oakley.h, src/racoon/sockmisc.c, + src/racoon/missing/crypto/sha2/sha2.c: Modified (see ChangeLog + in 'autoconf' branch for details). + * acracoon.m4, src/racoon/Makefile.am: New files. + * src/racoon/Makefile.in, src/racoon/aclocal.m4, + src/racoon/client-puzzle.c, src/racoon/config.guess, + src/racoon/config.sub, src/racoon/configure.in, + src/racoon/install-sh, src/racoon/doc/SantaBarbara-result.jp, + src/racoon/doc/helsinki-result.jp, src/racoon/doc/ibm-result.jp, + src/racoon/doc/pattern, src/racoon/doc/question, + src/racoon/doc/racoonquestion.sh, src/racoon/doc/redmond.txt, + src/racoon/doc/rules.jp, src/racoon/doc/sandiego-result.en, + src/racoon/doc/sandiego-result.jp, + src/racoon/doc/sandiego0009-result.en, + src/racoon/missing/addrinfo.h, src/racoon/missing/getaddrinfo.c, + src/racoon/missing/getnameinfo.c, src/racoon/samples/Makefile, + src/racoon/samples/sandiego.pl: Removed. + +2004-09-17 Michal Ludvig + + * src/racoon/vendorid.[ch]: Rewrote the VendorID handling. + We don't use the array with fixed offsets anymore, instead + a generally unordered structure with ID, string and + precomputed MD5 hashes. + * src/racoon/{isakmp_agg.c,isakmp_base.c,isakmp_ident.c}, + src/racoon/nattraversal.c: Updated to the new VID model. + * src/racoon/main.c(main): Precompute VendorIDs. + * src/racoon/arc4random.h, src/racoon/missing/arc4random.c: + Files removed. Function arc4random() renamed to eay_random() + and moved to crypto_openssl.c. + * src/racoon/pfkey.c, src/racoon/oakley.c, src/racoon/main.c, + src/racoon/isakmp.c: Updated to the above change. + * src/racoon/Makefile.in, src/racoon/configure.in: Remove + arc4random() from building. + * src/racoon/crypto_openssl.[ch](eay_random): New function. + * src/racoon/isakmp_cfg.c, src/racoon/isakmp_unity.c, + src/racoon/isakmp_xauth.c: Cleaned up headers. + +2004-09-16 Michal Ludvig + + * src/racoon/crypto_openssl.c (base64_encode): Terminate + the result with '\0'. + +2004-09-15 Michal Ludvig + + * configure.ac: How about calling the next version 0.5? + * src/include-glibc/glibc-bugs.h: Define _XOPEN_SOURCE + _BSD_SOURCE and don't require + * src/racoon/isakmp_cfg.c, src/racoon/isakmp_unity.c, + src/racoon/isakmp_xauth.c: Don't include + * src/racoon/Makefile.in: Add new files to distribution. + * src/racoon/configure.in: Fix linux kernel NATT detection. + * src/setkey/parse.y: Fix types. + * src/racoon/backupsa.c, src/racoon/ipsec_doi.c, + src/racoon/isakmp_inf.c, src/racoon/isakmp_quick.c, + src/racoon/pfkey.c, src/racoon/remoteconf.c, + src/racoon/session.c, src/racoon/sockmisc.c: Fix headers + ordering, use HAVE_NETINET6_IPSEC. + * src/racoon/isakmp_cfg.c: Use %z for size_t. + * src/racoon/configure.in: Clean up IPv6 stack check. + +2004-09-15 Michal Ludvig + + Merged "Hybrid XAUTH" support from Emmanuel Dreyfus: + * src/racoon/isakmp_cfg.h, src/racoon/isakmp_cfg.c, + src/racoon/isakmp_unity.c, src/racoon/isakmp_unity.h, + src/racoon/isakmp_xauth.c, src/racoon/isakmp_xauth.h, + src/racoon/samples/racoon.conf.sample-cvpn: New files. + * src/racoon/algorithm.c, src/racoon/algorithm.h, + src/racoon/cfparse.y, src/racoon/cftoken.l, + src/racoon/handler.c, src/racoon/handler.h, + src/racoon/ipsec_doi.c, src/racoon/isakmp.c, + src/racoon/isakmp.h, src/racoon/isakmp_agg.c, + src/racoon/isakmp_inf.c, src/racoon/oakley.c, + src/racoon/oakley.h, src/racoon/strnames.c, + src/racoon/vendorid.c, src/racoon/vendorid.h: Added + code for XAUTH support. + * src/racoon/racoon.conf.5: Documentation for XAUTH. + * src/racoon/isakmp_base.c, src/racoon/isakmp_ident.c, + src/racoon/nattraversal.c: Added NATT VID "02\n" + * src/racoon/configure.in: New config option --enable-hybrid + +2004-09-14 Michal Ludvig + + * configure.ac: Preset CFLAGS + * src/racoon/configure.in: Preset LDFLAGS instead of CFLAGS on NetBSD, + Check if printf() accepts "%z" modifiers. + * src/racoon/isakmp_agg.c(agg_i1send): Place #endif correctly. + * src/setkey/parse.y(fix_portstr): Init 'p2'. + * src/setkey/setkey.c: Add required prototypes. + +2004-09-14 Aidas Kasparas + + * src/racoon/gssapi.c: sa_len -> sysdep_sa_len. Patch by Andreas. + +2004-09-14 Michal Ludvig + + * src/racoon/configure.in: Check for NetBSD NAT-T kernel support. + +2004-09-13 Michal Ludvig + + * src/racoon/configure.in: Check for + * src/racoon/crypto_openssl.c: Only use OpenSSL engines if available. + * src/racoon/plainrsa-gen.c: Ditto. + +2004-09-13 Michal Ludvig + + NetBSD fixes from Emmanuel Dreyfus : + * Makefile.am: build in rpm/ only on Linux + * configure.ac: Check for netinet6/ipsec.h instead of netinet/ipsec.h + * src/Makefile.am: Build include-glibc only on Linux + * src/libipsec/{ipsec_dump_policy.c,ipsec_get_policylen.c, + ipsec_strerror.c,key_debug.c,pfkey.c,pfkey_dump.c, + policy_parse.y,policy_token.l,test-policy-priority.c}, + src/racoon/{cfparse.y,cftoken.l,grabmyaddr.c,isakmp.c, + nattraversal.c,pfkey.c,plainrsa-gen.c,policy.c, + proposal.c,sainfo.c,schedule.c,strnames.c}, + src/setkey/{parse.y,setkey.c,token.l}: Fix headers and some + ifdefs. + * src/racoon/sockmisc.c(sendfromto): Wrap for Linux only. + * src/racoon/configure.in: Check for kernel NAT-T support, + fix libipsec.a linkage path. + * src/racoon/eaytest.c(certtest): Use %z for size_t. + +2004-09-12 Aidas Kasparas + + * src/racoon/grabmyaddr.c: improoved socket selection algorithm for + case when link-local addresses comes w/o sin6_scope_id set. + +2004-09-07 Aidas Kasparas + + * src/racoon/session.c: fix for SIGHUP handler for case when config + file contains listen directives. + +2004-09-01 Aidas Kasparas + + * src/racoon/grabmyaddr.c: added scope id handling for link-local + IPv6 addresses. Now racoon will not err on such addresses. + +2004-08-19 Aidas Kasparas + + * src/racoon/crypto_openssl.c: hmac memory leak fix by R. Ganesan + * src/racoon/eaytest.c: eay_init_error() -> eay_init() due to + 2004-06-01 changes in src/racoon/crypto_openssl.c + +2004-08-15 Aidas Kasparas + + * src/racoon/cfparse.y src/racoon/crypto_openssl.c + src/racoon/eaytest.c src/racoon/genlist.h src/racoon/ipsec_doi.c + src/racoon/racoon.conf.5 src/racoon/remoteconf.c + src/racoon/remoteconf.h: peers_identifier wildcard and + list patch by James Matheson + +--------------------------------------------- + + 0.4rc1 released + +2004-08-09 Michal Ludvig + + * NEWS: Notes for release 0.4rc1 + * configure.ac: Bump up version to 0.4rc1 + +2004-07-12 Michal Ludvig + + PlainRSA support. + See ChangeLog.prsa from the 'plainrsa' branch for details. + * src/racoon/stringlist.c src/racoon/stringlist.h: Removed. + * src/racoon/genlist.c src/racoon/genlist.h + src/racoon/plainrsa-gen.8 src/racoon/plainrsa-gen.c + src/racoon/prsa_par.y src/racoon/prsa_tok.l + src/racoon/rsalist.c src/racoon/rsalist.h + src/racoon/samples/racoon.conf.sample-plainrsa: New files. + * src/racoon/Makefile.in src/racoon/configure.in + src/racoon/cfparse.y src/racoon/cftoken.l + src/racoon/crypto_openssl.c src/racoon/crypto_openssl.h + src/racoon/handler.h src/racoon/ipsec_doi.c + src/racoon/ipsec_doi.h src/racoon/isakmp.h src/racoon/main.c + src/racoon/oakley.c src/racoon/plog.c src/racoon/remoteconf.c + src/racoon/remoteconf.h src/racoon/sockmisc.c + src/racoon/sockmisc.h src/racoon/eaytest.c: Updated. + +2004-07-12 Michal Ludvig + + * src/racoon/main.c, src/racoon/eaytest.c, src/racoon/plog.c: Move + f_foreground to plog.c. + * src/racoon/proposal.c (cmpsaprop_alloc): Fix printing of encmode + adjusting. + * src/racoon/ipsec_doi.c, src/racoon/isakmp.c, src/racoon/isakmp_quick.c, + src/racoon/oakley.c: Fix typos, newlines and printf() format strings. + +2004-06-16 Aidas Kasparas + + * src/racoon/crypto_openssl.c (eay_get_x509cert): small memory + leak fix. Noticed B.Buesker, patch L.Stellingwerff + * src/racoon/crypto_openssl.c (eay_aes_{en|de}crypt, evp_crypt): + small memory leaks fixed. + +2004-06-15 Aidas Kasparas + + SECURITY + * src/racoon/crypto_openssl.[ch] (cb_check_cert_local, + cb_check_cert_remote): split cb_check_cert() due to stricter + requirements for certificates received from network. + * src/racoon/crypto_openssl.[ch] (eay_check_x509cert): new parameter + local to specify how strict cert check should be + * src/racoon/oakley.c, src/racoon/eaytest.c: adjust to use above + +2004-06-11 Michal Ludvig + + * src/racoon/nattraversal.c (natt_vendorid, natt_fill_options): Support + for all known NAT-T versions. + * vendorid.h: Ditto. + +2004-06-08 Michal Ludvig + + * src/racoon/stringlist.c, src/racoon/stringlist.h: New files. + * src/racoon/Makefile.in: Compile stringlist.o. + +2004-06-07 Michal Ludvig + + * configure.ac: Set version to 'cvs'. + * src/{racoon,setkey,libipsec}/*.h: Wrap headers between + #ifndef/#define/#endif to allow multiple inclusions of the + same file. + * plog.h (plog): Attribute __printf__ for automatic checking + of the parameters' validity. + * cftoken.l, crypto_openssl.c, grabmyaddr.c, ipsec_doi.c, + isakmp.c, isakmp_quick.c, oakley.c, pfkey.c, proposal.c, + sockmisc.c: Fix warnings/errors in the plog() parameters with + the above change. + +2004-06-05 Aidas Kasparas + + * src/setkey/setkey.c: -n (no action) support. + Thanks Thomas Habets. + * src/setkey/setkey.8: Documentation for above. + * src/racoon/doc/README.certificate: updated link to more recent + version of document. Debian bug #252513 by Jose Luis Domingo Lopez + +2004-06-01 Michal Ludvig + + * src/racoon/algorithm.c: Enable compilation without SHA2 support. + * src/racoon/crypto_openssl.c: Ditto. + +2004-06-01 Michal Ludvig + + * src/racoon/crypto_openssl.c: Remove unneeded workarounds for older + OpenSSLs. + (eay_init): New function. + (eay_init_error, eay_check_pkcs7sign): Removed. + * src/racoon/crypto_openssl.h: Reflect the above changes. + * src/racoon/main.c: Call eay_init() instead of eay_init_error(). + +2004-05-27 Michal Ludvig + + Support for inheritance of 'remote' statements: + * src/racoon/cftoken.l: New keyword 'inherit'. + * src/racoon/cfparse.y: Support for 'inherit', remove + global 'prhead', use cur_rmconf->prhead instead. + * src/racoon/remoteconf.c (rmtree): Changed from + LIST queue to TAILQ queue. + (getrmconf): Renamed to getrmconf_strict(). + (copyrmconf, duprmconf) + (dump_rmconf_single, dumprmconf): New functions. + (rm2str): Deleted. + * src/racoon/remoteconf.h: Prototypes for the above. + (struct remoteconf): New fields 'inherited_from' and 'prhead'. + * src/racoon/sockmisc.c (saddr2str): Can print anonymous entries. + * src/racoon/algorithm.c (alg_oakley_encdef_name) + (alg_oakley_hashdef_name, alg_oakley_dhdef_name) + (alg_oakley_authdef_name): New functions. + * src/racoon/algorithm.h: Prototpes for the above. + * src/racoon/strnames.c (num2str): Make extern. + (s_doi, s_etype, s_idtype, s_switch): New functions. + * src/racoon/strnames.h: Prototpes for the above. + * src/racoon/main.c: New parameter -C for dumping the parsed config. + * src/racoon/racoon.conf.5: Document inheritance. + * src/racoon/samples/racoon.conf.sample-inherit: Sample config file. + * src/racoon/Makefile.in: Distribute racoon.conf.sample-inherit + +2004-05-24 Michal Ludvig + + * configure.in, backupsa.c, ipsec_doi.c, isakmp_inf.c, + isakmp_quick.c, pfkey.c, remoteconf.c, session.c, + sockmisc.c: Allow compilation with --disable-ipv6 + +2004-05-21 Michal Ludvig + + * src/racoon/crypto_openssl.[ch]: Use EVP_*() instead of + algorithm specific functions. + +2004-05-20 Aidas Kasparas + + Manual page updates. Thanks Brian + * src/libipsec/ipsec_set_policy.3 + * src/setkey/setkey.8 + * src/libipsec/test-policy-priority.c: new file from policy + priority patch, which I forgot to add + +2004-05-18 Aidas Kasparas + + Policy priority integer handling fixes by Brian Buesker. + * src/libipsec/ipsec_strerror.c + * src/libipsec/ipsec_strerror.h + * src/libipsec/libpfkey.h + * src/libipsec/policy_parse.y + * src/libipsec/test-policy-priority.c + Manual page corrections by me + * src/libipsec/ipsec_set_policy.3 + * src/setkey/setkey.8 + +2004-05-15 Aidas Kasparas + + Policy priority support patch from Brian Buesker. Applied as is + except src/libipsec/Makefile.am is modified instead of + src/libipsec/Makefile.in as found in the patch. + +2004-05-10 Michal Ludvig + + From Heiko Hund, approved by the copyright holder: + * src/racoon/gssapi.[ch]: Update to 3-clause BSD license. + +2004-04-27 Michal Ludvig + + From Heiko Hund: + * src/include-glibc/sys/queue.h: Update to 3-clause BSD license. + +2004-04-26 Aidas Kasparas + + * src/racoon/grabmyaddr.c (update_myaddrs): Only trust kernel to + send notifications about changed interfaces. + +2004-04-24 Aidas Kasparas + + * src/racoon/grabmyaddr.c (recvaddrs): Only trust kernel to send + information about interfaces. Thanks Steve Grubb and Bill + Nottingham. Affects users with glibc w/o getifaddrs(). Users + with glibc earlier than 2003-11-14 should upgrade their glibc. + +2004-04-19 Michal Ludvig + + * src/racoon/isakmp.c (isakmp_handler): Reject too big + packets (CAN-2004-0403). + +--------------------------------------------- + + 0.3 released + +2004-04-14 Michal Ludvig + + * NEWS: Notes for release 0.3 + * configure.ac: Bump up version to 0.3 + * src/racoon/Makefile.in: Use install-sh instead of mkinstalldirs. + * src/racoon/remoteconf.c (foreachrmconf): Avoid warning about + uninitialised variable. + * src/racoon/samples/racoon.conf.in: Cleaned up to work with Linux + and FreeSWAN. + +2004-04-13 Michal Ludvig + + * src/racoon/grabmyaddr.c (suitable_ifaddr6): Anycast addresses are + not suitable. + +2004-04-09 Michal Ludvig + + * src/racoon/crypto_openssl.c (cb_check_cert): Warn if no CRL is found. + * src/racoon/isakmp_ident.c (ident_r2recv): Removed debug plog(). + * src/racoon/proposal.c (cmpsatrns): Downgrade severity of trns_id + mismatch to LLV_WARNING. + * src/libipsec/pfkey_dump.c, src/racoon/algorithm.c + src/racoon/algorithm.h src/racoon/cftoken.l + src/racoon/ipsec_doi.c src/racoon/ipsec_doi.h + src/racoon/oakley.h src/racoon/pfkey.c src/racoon/strnames.c + src/setkey/token.l: Renamed Rijndael to AES. + * src/setkey/token.l: Recognize exit/quit/bye tokens. + * src/setkey/parse.y (exit_command): New. + * src/setkey/setkey.c (stdin_loop): Exit when exit_now is set + in exit_command. + +2004-04-08 Michal Ludvig + + * src/setkey/setkey.c (main): Call get_supported() in interactive mode. + (stdin_loop): Concat multiline input into a single line before parsing. + +2004-04-07 Michal Ludvig + + * src/racoon/nattraversal.c (natt_keepalive_send): Log sending KA + with level DEBUG. Having it with level INFO only pollutes logfiles. + +2004-04-06 Michal Ludvig + + * src/racoon/Makefile.in: eaytest now links plog.o + * src/racoon/crypto_openssl.c: Remove all #ifdef EAYDEBUG/#endif + surrounding plog(). + * src/racoon/eaytest.c (rsatest): Enabled RSA tests again, now + verifying both good and bad signatures. + +--------------------------------------------- + + 0.3rc5 released + +2004-04-05 Michal Ludvig + + * NEWS: Notes for release 0.3rc5 + * configure.ac: Bump up version to 0.3rc5 + +2004-04-05 Michal Ludvig + + Fix for a security bug found by Ralf Spenneberg: + * src/racoon/crypto_openssl.c (eay_check_x509sign): Directly generate + 'evp' instead of 'pubkey'. + (eay_rsa_sign): Use the above. + * src/racoon/crypto_openssl.h: Update prototypes for the above. + * src/racoon/eaytest.c: Disabled RSA tests because of the API change. + +2004-04-05 Michal Ludvig + + * src/racoon/pfkey.c (pfkey_handler): Safety check before accessing + the array (thx to Ren.J.Y for report). + (pkrecvf): Added entry for SADB_X_NAT_T_NEW_MAPPING (NULL for now). + * src/racoon/strnames.c (name_pfkey_type): Ditto. + +2004-04-02 Michal Ludvig + + * src/racoon/eaytest.c (ciphertest_1): Correct padlen. + +2004-04-01 Michal Ludvig + + * src/racoon/ipsec_doi.c (setph2proposal0): Move proposal encmode + update from here ... + (ipsecdoi_setph2proposal): ... to here. Hopefully this is a + better place to do the update. + +2004-03-30 Michal Ludvig + + * src/racoon/crypto_openssl.c (eay_3des_expand_key): New function. + (eay_3des_encrypt, eay_3des_decrypt): Expand key if necessary. + * src/racoon/eaytest.c (ciphertest_1): New function. + (ciphertest): Simplified to simple calls of ciphertest_1(). + +2004-03-29 Michal Ludvig + + * README: Rewritten. Mentioned where to report bugs. + +2004-03-26 Michal Ludvig + + * configure.ac: Check for readline.h and libreadline. + * src/setkey/setkey.c: Call stdin_loop() when '-c' was given. + (stdin_loop): Read user input and parse it line-by-line. + * src/setkey/token.l (parse_string): New function. + +--------------------------------------------- + + 0.3rc4 released + +2004-03-25 Michal Ludvig + + * configure.ac: Bump up version to 0.3rc4 + * NEWS: Notes for release 0.3rc4 + * src/racoon/cfparse.y (algorithm): Hint about missing module. + * src/racoon/crypto_openssl.c (eay_3des_*): Check for strict key + length only with old API. + (eay_des_encrypt): Ditto. + * src/racoon/eaytest.c: Make the testsuite useful, i.e. exit with + non-zero error code if any of the tests fail. + (main): Print banner with version. + * src/racoon/Makefile.in: Run eaytest in 'make check'. + +2004-03-23 Michal Ludvig + + * src/racoon/isakmp_agg.c (agg_i2recv): Copy remote cookie before + comparing NAT-D payloads. (thx to Gaurav Kansal for report). + * src/racoon/crypto_openssl.c: Avoid type-punned warnings. + * src/racoon/eaytest.c: Disable 'cert' tests. + * src/racoon/crypto_openssl.c (eay_des_encrypt): No need to check + for strict length. + (eay_aes_encrypt): Keylength is in bits, not bytes. + +2004-03-22 Michal Ludvig + + * src/setkey/parse.y (ALG_ENC_NOKEY, ALG_ENC_OLD): Use "" for key + instead of NULL and check for availability. + +--------------------------------------------- + + 0.3rc3 released + +2004-03-19 Michal Ludvig + + * configure.ac: Bump up version to 0.3rc3 + * NEWS: Notes for release 0.3rc3 + * src/racoon/cftoken.l: Add 'null' as an alias for 'null_enc'. + * src/racoon/proposal.c (cmpsatrns): New parameter proto_id, + better diagnostic output when trns_id don't match. + * src/racoon/proposal.h (cmpsatrns): Update prototype. + * src/setkey/setkey.c: Change option -h to -H (for hexdump), new + options -h (help) and -V (version). + * src/setkey/setkey.8: Document the above changes. + * src/racoon/rfc/*: Many standards related to IPsec/IKE/NAT-T/... + +2004-03-15 Michal Ludvig + + * src/racoon/configure.in: Prevent compilation error with + --enable-yydebug. + +--------------------------------------------- + + 0.3rc2 released + +2004-03-11 Michal Ludvig + + * configure.ac: Bump up version to 0.3rc2 + * NEWS: Notes for release 0.3rc2 + * src/racoon/aclocal.m4 (RACOON_CHECK_VA_COPY): New test. + * src/racoon/configure.in: Call RACOON_CHECK_VA_COPY + * src/racoon/plog.c (plogv): Replace va_copy() with VA_COPY. + * src/racoon/racoon.conf.5: Note that NAT-T support is a compile + time option. + +2004-03-10 Michal Ludvig + + * src/racoon/racoon.conf.5: Document nat_traversal option. + * src/racoon/racoon.8: DOcument new options (-L and -P). + +2004-03-09 Michal Ludvig + + * src/racoon/grabmyaddr.c (autoconf_myaddrsport): Prepare addrs for + UDP-Encap ports if NAT-T is enabled. + (dupmyaddr): New function. + * src/racoon/grabmyaddr.h: Prototype for dupmyaddr(). + * src/racoon/isakmp.c (isakmp_open): Complain if NAT-T is enabled, but + no port for UDP-Encap was open. + * src/racoon/isakmp_var.h (PORT_ISAKMP_NATT): New define. + * src/racoon/localconf.c, src/racoon/localconf.h: Define and setup + lcconf->port_isakmp_natt. + * src/racoon/main.c (main): Print nicer banner, + (usage): Document new options (-L and -P). + (parse): Recognise the above. + * src/racoon/nattraversal.c (natt_fill_options): Don't use hardcoded + constants for float_port. + (natt_enabled_in_rmconf, natt_enabled_in_rmconf_stub): New functions. + * src/racoon/nattraversal.h: Prototype for natt_enabled_in_rmconf(). + * src/racoon/plog.c: Don't print source:line:function by default. + * src/racoon/remoteconf.c (foreachrmconf): New helper function. + * src/racoon/remoteconf.h: Prototype for the above. + * package_version.h: Define strings for use in banners. + * configure.ac: Fill up the above header. + +2004-03-09 Michal Ludvig + + * src/racoon/configure.in: Don't put -O into OPTFLAGS, + add new option --disable-natt. + * src/racoon/cfparse.y, src/racoon/handler.c, + src/racoon/ipsec_doi.c, src/racoon/isakmp.c, + src/racoon/isakmp_agg.c, src/racoon/isakmp_base.c, + src/racoon/isakmp_ident.c, src/racoon/pfkey.c, + src/racoon/proposal.c, src/racoon/session.c: Replace WITH_NATT + with ENABLE_NATT. + * src/racoon/crypto_openssl.c: Replace %d with %zd for size_t arguments. + +2004-03-06 Aidas Kasparas + + * configure.ac: Refuse to continue if lexer library (yywrap() + function) is missing. Should prevent bugs like #892067, #908758 + * src/racoon/configure.in: renamed --with-ssleay to --with-openssl. + Users should not be given false idea that they require both OpenSSL + and SSLeay to compile racoon. (See bug #902197) + +--------------------------------------------- + + 0.3rc1 released + +2004-03-04 Michal Ludvig + + * configure.ac: Bump up version to 0.3rc1 + * NEWS: Mention release 0.3rc1 (and copy 0.2.3 and 0.2.4 notes + from 0.2 branch). + * src/racoon/samples/racoon.conf.sample-natt: New sample config file. + * src/racoon/Makefile.in: Tweak file lists to make 'distcheck' happy, + enabled NATT by default (will become a config option later). + +2004-03-04 Michal Ludvig + + Merge with 'nat-t_branch' to bring NAT-T (NAT traversal) support + to racoon. + * src/racoon/Makefile.in, src/racoon/cfparse.y, + src/racoon/cftoken.l, src/racoon/grabmyaddr.c, + src/racoon/grabmyaddr.h, src/racoon/handler.c, + src/racoon/handler.h, src/racoon/ipsec_doi.c, + src/racoon/ipsec_doi.h, src/racoon/isakmp.c, src/racoon/isakmp.h, + src/racoon/isakmp_agg.c, src/racoon/isakmp_base.c, + src/racoon/isakmp_ident.c, src/racoon/isakmp_quick.c, + src/racoon/localconf.c, src/racoon/localconf.h, + src/racoon/pfkey.c, src/racoon/proposal.c, src/racoon/proposal.h, + src/racoon/racoon.conf.5, src/racoon/remoteconf.c, + src/racoon/remoteconf.h, src/racoon/session.c, + src/racoon/strnames.c, src/racoon/vendorid.h + src/libipsec/pfkey.c, + src/racoon/nattraversal.c, src/racoon/nattraversal.h, + src/racoon/sockmisc.c: Affected files. + +2004-02-27 Michal Ludvig + + * src/racoon/isakmp.c (set_isakmp_header1): Renamed from + set_isakmp_header(). + (set_isakmp_header): New function common for set_isakmp_header1() + and set_isakmp_header2(). + (copy_ph1addresses): Obey original port. + (isakmp_plist_append, isakmp_plist_set_all): New helper functions. + * src/racoon/isakmp_var.h: Prototypes for the above. + * src/racoon/isakmp.h (struct payload_list): New structure. + * src/racoon/isakmp_agg.c, src/racoon/isakmp_base.c, + src/racoon/isakmp_ident.c: Use isakmp_plist_* functions. + +2004-02-03 Michal Ludvig + + * src/racoon/Makefile.in: Fix install to $(sbindir) + * src/setkey/parse.y: Avoid GCC 3.3 warning (type-punned pointer). + +2004-01-19 Michal Ludvig + + * rpm/ipsec-tools.FC1: Startup script for Fedora Core 1 + (thanks to Kimmo Koivisto ) + +2004-01-17 Aidas Kasparas + + * src/racoon/isakmp_inf.c: endian mismatch fix. From iij seil team + +2004-01-15 Michal Ludvig + + * src/racoon/isakmp_inf.c: Prevent unauthorized deletion of SA + (reported on bugtraq, fixed by iij seil team). + * src/racoon/isakmp.c: Don't try to bind to IPv6 multicast addresses. + +2004-01-14 Michal Ludvig + + * src/racoon/plog.c: Fix segfault on AMD64 (va_list can be used + only once). + * configure.ac: Don't build shared libipsec by default (can be + enabled by --enable-shared). + * bootstrap: Don't run automake for racoon. + +2004-01-12 Michal Ludvig + + * src/racoon/configure.in: Fix AC_DEFINEs to make autoheader happy, + use config.h for defines instead of -DHAVE_* gcc options, + fix CRYPTOBJS to include missing rijndael libraries only once, + checking for AES support in OpenSSL now (hopefully) finally + works on both OpenSSL 0.9.6 and 0.9.7. + * src/racoon/*.[cyl]: Include autogenerated "config.h" + * src/racoon/missing/crypto/*/*.c: Ditto. + * src/racoon/.cvsignore: Add config.h, config.h.in + +2004-01-09 Michal Ludvig + + * src/racoon/.cvsignore: Add "autom4te.cache" and "configure". + +2004-01-09 Aidas Kasparas + + Sync with KAME 2004-01-07 + * src/libipsec/pfkey.c: memory leak fix; comment typo fixes + * src/libipsec/{pfkey.c,pfkey_dump.c}: allow compilation even + no SADB_X_EXT_TAG defined + * src/libipsec/pfkey_dump.c: information about algorithms + ripemd160, aes-xcbc, aes-ctr; bigger buffers; support + * src/libipsec/policy_parse.y: memory leak + * src/libipsec/policy_token.l: memory leak + * src/libipsec/test-policy.c: unneeded \n removed + * src/racoon/Makefile.in: $(sbindir) support + * src/racoon/admin.c: interface changes due to proxy support + * src/racoon/algorithm.c: SHA2 #ifdefs + * src/racoon/{cfparse.y,cftoken.l}: license text added + * src/racoon/cfparse.y: mip6 obsoleted by proxy support + * src/racoon/cfparse.y: from directive support; new algorithms + * src/racoon/cftoken.l: support for globbing of include files + * src/racoon/configure.in: more verbose information about problems + with SHA2 + * src/racoon/crypto_openssl.c: use new DES API if supported; algorithm + key size fixes + * src/racoon/eaytest.c: SHA2 #ifdefs; keysize len check + * src/racoon/ipsec_doi.c: use VPTRINIT; ESP parameter validity checks; + style change + * src/racoon/isakmp.c: use VPTRINIT; interface changes due to + mip6->proxy; typo + * src/racoon/isakmp_inf.c: use VPTRINIT + * src/racoon/isakmp_quick.c: mip6->proxy + * src/racoon/kmpstat.c: not used variables removed + * src/racoon/pfkey.c: mip6->proxy; schedule leak + * src/racoon/proposal.c: style + * src/racoon/remoteconf.c: mip6->proxy + * src/racoon/sainfo.c: from directive support + * src/racoon/sockmisc.c: side correction; addrinfo leak + * src/racoon/strnames.c: typo in descriptions; wrong upper bound check + * src/racoon/missing/crypto/sha2/sha2.c: wrong size + * src/setkey/parse.y: extra algorithms; tagged; not needed periods + removed; memory shortage checks + * src/setkey/setkey.8: typos; tagged; new algorithms + * src/setkey/setkey.c: standard argument names for main(); hexdump + support; info in file support + * src/setkey/token.l: new algorithms; memory shortage checks + Parts not taken from KAME: + * kernelfs stuff; + * sysctl stuff + +2004-01-08 Michal Ludvig + + * src/racoon/config.{sub,guess}: Update from automake 1.7. + +2004-01-08 Michal Ludvig + + Patch from Kostadin Karaivanov : + * src/racoon/configure.in: Check for openssl/aes.h. + * src/racoon/crypto_openssl.c: Use OpenSSL AES functions if available. + +2004-01-08 Michal Ludvig + + * src/racoon/configure: Remove, should be regenerated by bootstrap. + +2004-01-02 Michal Ludvig + + * src/racoon/crypto_openssl.c: Update to work with OpenSSL 0.9.7 + (by Brian Buesker + and Christophe Saout ) + * src/racoon/proposal.c: Be more verbose. (Michal Ludvig) + * src/libipsec/ipsec_dump_policy.c: Dump FWD policies correctly + (by Michal Ludvig). + * src/setkey/token.l, src/setkey/parse.y: Add support for lifetime + specified in bytes (by Michal Ludvig). + * src/setkey/setkey.8: Document -bh/-bs options for the above feature. + * src/libipsec/pfkey.c: Don't include 'sadb_key' in SADB_UPDATE + message for IPcomp SA. (by Brian Buesker ) + * src/racoon/cfparse.y: Flush SA on SIGHUP + (by Brian Buesker ) + * src/racoon/pfkey.c: IPcomp fixes + (by Brian Buesker ) + * src/racoon/proposal.c: Fix typo lifebyte -> lifetime. + * src/racoon/grabmyaddr.c: Prevent segfault if getifaddrs() returns + an entry with NULL ifa_addr (Michal Ludvig). + * configure.ac: Change path to kernel headers + from /usr/src/devel-2.5/devel to /usr/src/linux + * bootstrap: Use default tools, reconfigure src/racoon + * src/racoon/configure.in: Change LIBOBJS -> AC_LIBOBJ, + changed comments from 'dnl' to '#'. + +2003-06-20 Derek Atkins + + * src/racoon/aclocal.m4: + * src/racoon/configure: + Don't execute "for i in $3" if "$3" doesn't exist. + Fixes bug #721296. + +2003-03-31 Derek Atkins + + * src/setkey/parse.y: change the NAT-T Type to use UDP_ENCAP_ESPINUDP + (which is value '2') + +2003-03-27 Derek Atkins + + * src/libipsec/key_debug.c: use ntohs() before printing port + * src/libipsec/pfkey.c: convert port# to network byte order + * src/libipsec/pfkey_dump.c: use ntohs() before printing ports + * src/setkey/parse.y: convert port#'s to network byte order + +2003-03-24 Derek Atkins + + * src/libipsec/pfkey.c: Don't switch off NAT-T extensions + if they don't exist in the kernel. + + * src/racoon/sockmisc.c: use '34' for IPV6_IPSEC_POLICY, + as per Tom Lendacky . Also move the + setting of IPV6_IPSEC_POLICY to the top of the file. + +2003-03-13 Derek Atkins + + Add initial support for NAT-T PFKey Extensions: + * src/libipsec/key_debug.c: add support to print information + about NAT-T extension packets. + * src/libipsec/libpfkey.h: add two new APIs to support NAT-T + for add and update as part of the SADB. + * src/libipsec/pfkey.c: + - Implement extended APIs to support NAT-T for add and update + of the SADB. + - Add APIs to fill a buffer with NAT-T packet types + * src/libipsec/pfkey_dump.c: Extend the SADB output to include + PFKey packets. Put port numbers with the source and dest + addresses, add an 'esp-udp' SA-type, and add a printout for + the NAT-OA. + * src/setkey/parse.y: + - Extend setkey to create an ESP-UDP SA. + - default UDP port is 4500 + - extend 'add' to allow [] for source and dest + (the portnum specification requires the [] characters) + - add an ESPUDP "protocol" from the lexer. This will use + ESP and allow an optional Original Address setting. + - add a function to get a udp port from a struct sockaddr * + - pass the NAT-T extentions into PFKey + * src/setkey/token.l: add "esp-udp" token + + * rpm/ipsec-tools.spec.in: Bill Nottingham's SPEC-file patch: + This switches it to use %{_lib} (for /lib64 systems such as + x86-64 and s390x, and has it own the /etc/racoon directory in + the package as well. + +--------------------------------------------- + + 0.2.2 released + +2003-03-13 Derek Atkins + + * configure.am, NEWS: + Update for 0.2.2 release + + * Makefile.am: distribute depcomp + +2003-03-10 Derek Atkins + + * src/racoon/Makefile.in: add @LEXLIB@ to the LIBS line to make + sure we link against the lexer library when necessary. + +2003-03-07 Derek Atkins + + * configure.am: + * Makefile.am: + * rpm/Makefile.am: + * rpm/ipsec-tools.spec.in: + Added RPM SPEC to CVS + +--------------------------------------------- + + 0.2.1 released + +2003-03-07 Derek Atkins + + * src/racoon/configure.in: change "CFLAGS" to "CPPFLAGS" for + ssl include directory, to make sure the other tests work properly. + +2003-03-06 Derek Atkins + + * src/racoon/kmpstat.c: fix gcc-3.2.2 compiler warning + + * src/racoon/configure.in: look for krb5-config and don't + use it if it's not found. Fixes a configure-time warning. + +-------------------------------------------- + + 0.2 Released diff --git a/ipsec-tools/Makefile.am b/ipsec-tools/Makefile.am new file mode 100644 index 00000000..4c6cff6d --- /dev/null +++ b/ipsec-tools/Makefile.am @@ -0,0 +1,18 @@ +SUBDIRS = src @RPM@ + +DIST_SUBDIRS = src rpm + +EXTRA_DIST = bootstrap README NEWS depcomp ChangeLog ChangeLog.old + +MAINTAINERCLEANFILES = ChangeLog + +$(srcdir)/ChangeLog: + @if test -d "$(srcdir)/CVS"; then \ + $(srcdir)/misc/cvs2cl.pl --follow-only ipsec-tools-0_8-branch -I ChangeLog --utc -U $(srcdir)/misc/cvsusermap --group-by-author --fsf -T -l "-d2006-09-10 $@ ; \ + echo "For older changes see ChangeLog.old" >> $@ ; \ + else \ + echo "A CVS checkout and perl is required to generate ChangeLog" ; \ + exit 1 ; \ + fi + +.PHONY: $(srcdir)/ChangeLog diff --git a/ipsec-tools/Makefile.in b/ipsec-tools/Makefile.in new file mode 100644 index 00000000..22553942 --- /dev/null +++ b/ipsec-tools/Makefile.in @@ -0,0 +1,836 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/config.h.in $(srcdir)/package_version.h.in \ + $(top_srcdir)/src/racoon/samples/psk.txt.in \ + $(top_srcdir)/src/racoon/samples/racoon.conf.in ChangeLog NEWS \ + README compile config.guess config.sub depcomp install-sh \ + missing ylwrap ltmain.sh +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acracoon.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = package_version.h src/racoon/samples/psk.txt \ + src/racoon/samples/racoon.conf +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 +GZIP_ENV = --best +DIST_TARGETS = dist-bzip2 dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGURE_AMFLAGS = @CONFIGURE_AMFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTOBJS = @CRYPTOBJS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_CRYPTO = @EXTRA_CRYPTO@ +FGREP = @FGREP@ +FRAG_OBJS = @FRAG_OBJS@ +GLIBC_BUGS = @GLIBC_BUGS@ +GREP = @GREP@ +HYBRID_OBJS = @HYBRID_OBJS@ +INCLUDE_GLIBC = @INCLUDE_GLIBC@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_OPTS = @INSTALL_OPTS@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KERNEL_INCLUDE = @KERNEL_INCLUDE@ +KRB5_CONFIG = @KRB5_CONFIG@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NATT_OBJS = @NATT_OBJS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RPM = @RPM@ +SECCTX_OBJS = @SECCTX_OBJS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +include_racoondir = @include_racoondir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = src @RPM@ +DIST_SUBDIRS = src rpm +EXTRA_DIST = bootstrap README NEWS depcomp ChangeLog ChangeLog.old +MAINTAINERCLEANFILES = ChangeLog +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +package_version.h: $(top_builddir)/config.status $(srcdir)/package_version.h.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +src/racoon/samples/psk.txt: $(top_builddir)/config.status $(top_srcdir)/src/racoon/samples/psk.txt.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +src/racoon/samples/racoon.conf: $(top_builddir)/config.status $(top_srcdir)/src/racoon/samples/racoon.conf.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-generic \ + distclean-hdr distclean-libtool distclean-tags distcleancheck \ + distdir distuninstallcheck dvi dvi-am html html-am info \ + info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + + +$(srcdir)/ChangeLog: + @if test -d "$(srcdir)/CVS"; then \ + $(srcdir)/misc/cvs2cl.pl --follow-only ipsec-tools-0_8-branch -I ChangeLog --utc -U $(srcdir)/misc/cvsusermap --group-by-author --fsf -T -l "-d2006-09-10 $@ ; \ + echo "For older changes see ChangeLog.old" >> $@ ; \ + else \ + echo "A CVS checkout and perl is required to generate ChangeLog" ; \ + exit 1 ; \ + fi + +.PHONY: $(srcdir)/ChangeLog + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ipsec-tools/NEWS b/ipsec-tools/NEWS new file mode 100644 index 00000000..1efdfd50 --- /dev/null +++ b/ipsec-tools/NEWS @@ -0,0 +1,173 @@ +Version history: +---------------- +0.8.2 - 27 February 2014 + o Fix admin port establish-sa for tunnel mode SAs (Alexander Sbitnev) + o Fix source port selection regression from version 0.8.1 + o Various logging improvements + o Additional compliance and build fixes + +0.8.1 - 08 January 2013 + o Improved X.509 subject name comparation (Götz Babin-Ebell) + o Relax DPD cookie check for Cisco IOS compatibility (Roman Antink) + o Allow simplified syntax for inherited remote blocks (Roman Antink) + o Never shring pfkey socket buffer (Marcelo Leitner) + o Privilege separation child process exit fix + o Multiple memory allocation and use-after-free fixes + +0.8 - 18 March 2011 + o Fix authentication method ambiguity with kerberos and xauth + o RFC2253 compliant escaping of asn1dn identifiers (Cyrus Rahman) + o Local address code rewrite to speed things up + o Improved MIPv6 support (Arnaud Ebalard) + o ISAKMP SA (phase1) rekeying + o Improved scheduler (faster algorithm, support monotonic clock) + o Handle RESPONDER-LIFETIME in quick mode + o Handle INITIAL-CONTACT in from main mode too + o Rewritten event handling framework for admin port + o Ability to initiate IPsec SA through admin port + o NAT-T Original Address handling (transport mode NAT-T support) + o clean NAT-T - PFkey support + o support for multiple anonymous remoteconfs + o Remove various obsolete configuration options + o A lot of other bug fixes, performance improvements and clean ups + +0.7.1 - 23 July 2008 + o Fixes a memory leak when invalid proposal received + o Some fixes in DPD + o do not set default gss id if xauth is used + o fixed hybrid enabled builds + o fixed compilation on FreeBSD8 + o cleanup in network port value manipulation + o Gets ports from SADB_X_EXT_NAT_T_[SD]PORT if present in + purge_ipsec_spi() + o Generates a log if cert validation has been disabled by + configuration + o better handling for pfkey socket read errors + o Fixes in yacc / bison stuff + o new plog() macro (reduced CPU usage when logging is disabled) + o Try to work better with huge SPD/SAD + o Corrected modecfg option syntax + +0.7 - 09 August 2007 + o Xauth with pre-shared key PSK + o Xauth with certificates + o SHA2 support + o pkcs7 support + o system accounting (utmp) + o Darwin support + o configuration can be reloaded + o Support for UNIQUE generated policies + o Support for semi anonymous sainfos + o Support for ph1id to remoteid matching + o Plain RSA authentication + o Native LDAP support for Xauth and modecfg + o Group membership checks for Xauth and sainfo selection + o Camellia cipher support + o IKE Fragment force option + o Modecfg SplitNet attribute support + o Modecfg SplitDNS attribute support ( server side ) + o Modecfg Default Domain attribute support + o Modecfg DNS/WINS server multiple attribute support + +0.6 - 27 June 2005 + o Generated policies are now correctly flushed + o NAT-T works with multiple peers behind the NAT (need kernel support) + o Xauth can use shadow passwords + o TCP-MD5 support + o PAM support for Xauth + o Privilege separation + o ESP fragmentation in tunnel mode can be tunned (NetBSD only) + o racoon admin interface is exported (header and library) to + help building control programs for racoon (think GUI) + o Fixed single DES support; single DES users MUST UPGRADE. + +0.5 - 10 April 2005 + o Rewritten buildsystem. Now completely autoconfed, automaked, + libtoolized. + o IPsec-tools now compiles on NetBSD and FreeBSD again. + o Support for server-side hybrid authentication, with full + RADIUS supoort. This is interoperable with the Cisco VPN client. + o Support for client-side hybrid authentication (Tested only with + a racoon server) + o ISAKMP mode config support + o IKE fragmentation support + o Fixed FWD policy support. + o Fixed IPv6 compilation. + o Readline is optional, fixed setkey when compiled without readline. + o Configurable Root-CA certificate. + o Dead Peer Detection (DPD) support. + +0.4rc1 - 09 August 2004 + o Merged support for PlainRSA keys from the 'plainrsa' branch. + o Inheritance of 'remote{}' sections. + o Support for SPD policy priorities in setkey. + o Ciphers are now used through the 'EVP' interface which allows + using hardware crypto accelerators. + o Setkey has new option -n (no action). + o All source files now have 3-clause BSD license. + +0.3 - 14 April 2004 + o Fixed setkey to handle multiline commands again. + o Added command 'exit' to setkey. + o Fixed racoon to only Warn if no CRL was found. + o Improved testsuite. + +0.3rc5 - 05 April 2004 + o Security bugfix WRT handling X.509 signatures. + o Stability fix WRT unknown PF_KEY messages. + o Fixed NAT-T with more proposals (e.g. more crypto algos). + o Setkey parses lines one by one => doesn't exit on errors. + o Setkey supports readline => more user friendly. + +0.3rc4 - 25 March 2004 + o Fixed adding "null" encryption via 'setkey'. + o Fixed segfault when using AES in Phase1 with OpenSSL>=0.9.7 + o Fixed NAT-T in aggresive mode. + o Fixed testsuite and added testsuite run into make check. + +0.3rc3 - 19 March 2004 + o Fixed compilation error with --enble-yydebug + o Better diagnostic when proposals don't match. + o Changed/added options to setkey. + +0.3rc2 - 11 March 2004 + o Added documentation for NAT-T + o Better NAT-T diagnostic. + o Test and workaround for missing va_copy() + +0.3rc1 - 04 March 2004 + o Support for NAT Traversal (NAT-T) + +0.2.4 - 29 January 2004 + o Sync with KAME as of 2004-01-07 + o Fixed unauthorized deletion of SA in racoon (again). + +0.2.3 - 15 January 2004 + o Support for SA lifetime specified in bytes + (see setkey -bs/-bh options) + o Enhance support for OpenSSL 0.9.7 + o Let racoon be more verbose + o Fixed some simple bugs (see ChangeLog for details) + o Fixed unauthorized deletion of SA in racoon + o Fixed problems on AMD64 + o Ignore multicast addresses for IKE + +0.2.2 - 13 March 2003 + o Fix racoon to build on some systems that require linking against -lfl + o add an RPM spec to the distribution + +0.2.1 - 07 March 2003 + o Fix some more gcc-3.2.2 compiler warnings + o Fix racoon to actually configure with ssl in a non-standard location + o Fix racoon to not complain if krb5-config is not installed + +0.2 - 06 March 2003 + o Glibc-2.3 support + o OpenSSL-0.9.7 support + o Fixed duplicate-macro problems + o Fix racoon lex/yacc support + o Install psk.txt mode 600, racoon.conf mode 644 + o Fix racoon to look in the correct directory for config files + +0.1 - 03 March 2003 + o Initial release of IPsec-Tools diff --git a/ipsec-tools/README b/ipsec-tools/README new file mode 100644 index 00000000..96239976 --- /dev/null +++ b/ipsec-tools/README @@ -0,0 +1,38 @@ +IPsec-tools +=========== + +This package provides a way to use the native IPsec functionality +in the Linux 2.6+ kernel. It works as well on NetBSD and FreeBSD. + + - libipsec, a PF_KEYv2 library + - setkey, a tool to directly manipulate policies and SAs + - racoon, an IKEv1 keying daemon + +IPsec-tools were ported to Linux from the KAME project +(http://www.kame.net) by Derek Atkins . + +Currently the package is actively maintained and developed by: + Emmanuel Dreyfus + VANHULLEBUS Yvan + Matthew Grooms + Timo Teräs + +Sources can be found at the IPsec-Tools home page at: + http://ipsec-tools.sourceforge.net/ + +And CVS repository is hosted at NetBSD tree: + cvs -danoncvs@anoncvs.netbsd.org:/cvsroot co ipsec-tools + +Bug reports and project wiki is located at: + https://trac.ipsec-tools.net/ + +Please report any problems to the mailing list: + ipsec-tools-devel@lists.sourceforge.net + ipsec-tools-users@lists.sourceforge.net + +You can also browse the list archive: + http://sf.net/mailarchive/forum.php?forum_name=ipsec-tools-devel + +Credits: + IHTFP Consulting, see http://www.ihtfp.com/ + SUSE Linux AG, see http://www.suse.com/ diff --git a/ipsec-tools/aclocal.m4 b/ipsec-tools/aclocal.m4 new file mode 100644 index 00000000..98a9b5ef --- /dev/null +++ b/ipsec-tools/aclocal.m4 @@ -0,0 +1,9755 @@ +# generated automatically by aclocal 1.14.1 -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS + +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) + +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) + +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3337 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.2' +macro_revision='1.3337' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) + +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) + +# Copyright (C) 2002-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.14' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.14.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.14.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Copyright (C) 1998-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_LEX +# ----------- +# Autoconf leaves LEX=: if lex or flex can't be found. Change that to a +# "missing" invocation, for better error output. +AC_DEFUN([AM_PROG_LEX], +[AC_PREREQ([2.50])dnl +AC_REQUIRE([AM_MISSING_HAS_RUN])dnl +AC_REQUIRE([AC_PROG_LEX])dnl +if test "$LEX" = :; then + LEX=${am_missing_run}flex +fi]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([acracoon.m4]) diff --git a/ipsec-tools/acracoon.m4 b/ipsec-tools/acracoon.m4 new file mode 100644 index 00000000..1f7e6c15 --- /dev/null +++ b/ipsec-tools/acracoon.m4 @@ -0,0 +1,195 @@ +dnl RACOON_PATH_LIBS(FUNCTION, LIB, SEARCH-PATHS [, ACTION-IF-FOUND +dnl [, ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]]) +dnl Search for a library defining FUNC, if it's not already available. + +AC_DEFUN([RACOON_PATH_LIBS], +[AC_PREREQ([2.13]) +AC_CACHE_CHECK([for $2 containing $1], [ac_cv_search_$1], +[ac_func_search_save_LIBS="$LIBS" +ac_cv_search_$1="no" +AC_TRY_LINK_FUNC([$1], [ac_cv_search_$1="none required"], + [LIBS="-l$2 $LIBS" + AC_TRY_LINK_FUNC([$1], [ac_cv_search_$1="-l$2"], [])]) +LIBS="$ac_func_search_save_LIBS" +ifelse("x$3", "x", , [ test "$ac_cv_search_$1" = "no" && for i in $3; do + LIBS="-L$i -l$2 $ac_func_search_save_LIBS" + AC_TRY_LINK_FUNC([$1], + [ac_cv_search_$1="-L$i -l$2" + break]) + done +LIBS="$ac_func_search_save_LIBS" ]) ]) +if test "$ac_cv_search_$1" != "no"; then + test "$ac_cv_search_$1" = "none required" || LIBS="$ac_cv_search_$1 $LIBS" + $4 +else : + $5 +fi]) + +dnl Check if either va_copy() or __va_copy() is available. On linux systems +dnl at least one of these should be present. +AC_DEFUN([RACOON_CHECK_VA_COPY], [ + saved_CFLAGS=$CFLAGS + CFLAGS="-Wall -O2" + AC_CACHE_CHECK([for an implementation of va_copy()], + ac_cv_va_copy,[ + AC_TRY_RUN([#include + void func (int i, ...) { + va_list args1, args2; + va_start (args1, i); + va_copy (args2, args1); + if (va_arg (args1, int) != 1 || va_arg (args2, int) != 1) + exit (1); + va_end (args1); + va_end (args2); + } + int main() { + func (0, 1); + return 0; + }], + [ac_cv_va_copy=yes], + [ac_cv_va_copy=no], + AC_MSG_WARN(Cross compiling... Unable to test va_copy) + [ac_cv_va_copy=no]) + ]) + if test x$ac_cv_va_copy != xyes; then + AC_CACHE_CHECK([for an implementation of __va_copy()], + ac_cv___va_copy,[ + AC_TRY_RUN([#include + void func (int i, ...) { + va_list args1, args2; + va_start (args1, i); + __va_copy (args2, args1); + if (va_arg (args1, int) != 1 || va_arg (args2, int) != 1) + exit (1); + va_end (args1); + va_end (args2); + } + int main() { + func (0, 1); + return 0; + }], + [ac_cv___va_copy=yes], + [ac_cv___va_copy=no], + AC_MSG_WARN(Cross compiling... Unable to test __va_copy) + [ac_cv___va_copy=no]) + ]) + fi + + if test "x$ac_cv_va_copy" = "xyes"; then + va_copy_func=va_copy + elif test "x$ac_cv___va_copy" = "xyes"; then + va_copy_func=__va_copy + fi + + if test -n "$va_copy_func"; then + AC_DEFINE_UNQUOTED(VA_COPY,$va_copy_func, + [A 'va_copy' style function]) + else + AC_MSG_WARN([Hmm, neither va_copy() nor __va_copy() found.]) + AC_MSG_WARN([Using a generic fallback.]) + fi + CFLAGS=$saved_CFLAGS + unset saved_CFLAGS +]) + +AC_DEFUN([RACOON_CHECK_BUGGY_GETADDRINFO], [ + AC_MSG_CHECKING(getaddrinfo bug) + saved_CFLAGS=$CFLAGS + CFLAGS="-Wall -O2" + AC_TRY_RUN([ + #include + #include + #include + #include + #include + #include + + int main() + { + int passive, gaierr, inet4 = 0, inet6 = 0; + struct addrinfo hints, *ai, *aitop; + char straddr[INET6_ADDRSTRLEN], strport[16]; + + for (passive = 0; passive <= 1; passive++) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = passive ? AI_PASSIVE : 0; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_socktype = SOCK_STREAM; + if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) { + (void)gai_strerror(gaierr); + goto bad; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_addr == NULL || + ai->ai_addrlen == 0 || + getnameinfo(ai->ai_addr, ai->ai_addrlen, + straddr, sizeof(straddr), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + goto bad; + } + switch (ai->ai_family) { + case AF_INET: + if (strcmp(strport, "54321") != 0) { + goto bad; + } + if (passive) { + if (strcmp(straddr, "0.0.0.0") != 0) { + goto bad; + } + } else { + if (strcmp(straddr, "127.0.0.1") != 0) { + goto bad; + } + } + inet4++; + break; + case AF_INET6: + if (strcmp(strport, "54321") != 0) { + goto bad; + } + if (passive) { + if (strcmp(straddr, "::") != 0) { + goto bad; + } + } else { + if (strcmp(straddr, "::1") != 0) { + goto bad; + } + } + inet6++; + break; + case AF_UNSPEC: + goto bad; + break; + default: + /* another family support? */ + break; + } + } + } + + if (!(inet4 == 0 || inet4 == 2)) + goto bad; + if (!(inet6 == 0 || inet6 == 2)) + goto bad; + + if (aitop) + freeaddrinfo(aitop); + exit(0); + + bad: + if (aitop) + freeaddrinfo(aitop); + exit(1); + } + ], + AC_MSG_RESULT(good) + buggygetaddrinfo=no, + AC_MSG_RESULT(buggy) + buggygetaddrinfo=yes, + AC_MSG_RESULT(Cross compiling ... Assuming getaddrinfo is not buggy.) + buggygetaddrinfo=no) + CFLAGS=$saved_CFLAGS + unset saved_CFLAGS +]) diff --git a/ipsec-tools/bootstrap b/ipsec-tools/bootstrap new file mode 100755 index 00000000..1f2bdb66 --- /dev/null +++ b/ipsec-tools/bootstrap @@ -0,0 +1,21 @@ +#!/bin/sh + +set -x + +case `uname -s` in +Darwin) + LIBTOOLIZE=glibtoolize + ;; +*) + LIBTOOLIZE=libtoolize + ;; +esac + +# Remove autoconf 2.5x's cache directory +rm -rf autom4te*.cache + +aclocal -I . || exit 1 +autoheader || exit 1 +${LIBTOOLIZE} --force --copy || exit 1 +automake --foreign --add-missing --copy || exit 1 +autoconf || exit 1 diff --git a/ipsec-tools/compile b/ipsec-tools/compile new file mode 100755 index 00000000..531136b0 --- /dev/null +++ b/ipsec-tools/compile @@ -0,0 +1,347 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-10-14.11; # UTC + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# 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, or (at your option) +# any later version. +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/ipsec-tools/config.guess b/ipsec-tools/config.guess new file mode 100755 index 00000000..49ba16f1 --- /dev/null +++ b/ipsec-tools/config.guess @@ -0,0 +1,1522 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-01-01' + +# This file 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. +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/ipsec-tools/config.h.in b/ipsec-tools/config.h.in new file mode 100644 index 00000000..534b2aa3 --- /dev/null +++ b/ipsec-tools/config.h.in @@ -0,0 +1,270 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* in-kernel NAT-T is broken */ +#undef BROKEN_NATT + +/* If printf doesn't support %zu. */ +#undef BROKEN_PRINTF + +/* Enable admin port */ +#undef ENABLE_ADMINPORT + +/* Enable dead peer detection */ +#undef ENABLE_DPD + +/* IKE fragmentation support */ +#undef ENABLE_FRAG + +/* Hybrid authentication support */ +#undef ENABLE_HYBRID + +/* Enable NAT-Traversal */ +#undef ENABLE_NATT + +/* Enable NAT-Traversal draft 00 */ +#undef ENABLE_NATT_00 + +/* Enable NAT-Traversal draft 01 */ +#undef ENABLE_NATT_01 + +/* Enable NAT-Traversal draft 02 */ +#undef ENABLE_NATT_02 + +/* Enable NAT-Traversal draft 03 */ +#undef ENABLE_NATT_03 + +/* Enable NAT-Traversal draft 04 */ +#undef ENABLE_NATT_04 + +/* Enable NAT-Traversal draft 05 */ +#undef ENABLE_NATT_05 + +/* Enable NAT-Traversal draft 06 */ +#undef ENABLE_NATT_06 + +/* Enable NAT-Traversal draft 07 */ +#undef ENABLE_NATT_07 + +/* Enable NAT-Traversal draft 08 */ +#undef ENABLE_NATT_08 + +/* Enable NAT-Traversal RFC version */ +#undef ENABLE_NATT_RFC + +/* Enable samode-unspec */ +#undef ENABLE_SAMODE_UNSPECIFIED + +/* Enable statictics */ +#undef ENABLE_STATS + +/* Have a monotonic clock */ +#undef HAVE_CLOCK_MONOTONIC + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Have __func__ macro */ +#undef HAVE_FUNC_MACRO + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Enable GSS API */ +#undef HAVE_GSSAPI + +/* Have iconv using const */ +#undef HAVE_ICONV_2ND_CONST + +/* Define to 1 if you have the `iconv_open' function. */ +#undef HAVE_ICONV_OPEN + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Have ipsec_policy_t */ +#undef HAVE_IPSEC_POLICY_T + +/* Hybrid authentication uses LDAP */ +#undef HAVE_LIBLDAP + +/* Hybrid authentication uses PAM */ +#undef HAVE_LIBPAM + +/* Hybrid authentication uses RADIUS */ +#undef HAVE_LIBRADIUS + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_AES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_CAMELLIA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_ENGINE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_IDEA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_RC5_H + +/* Define to 1 if you have the `pam_start' function. */ +#undef HAVE_PAM_START + +/* Are PF_KEY policy priorities supported? */ +#undef HAVE_PFKEY_POLICY_PRIORITY + +/* Have forward policy */ +#undef HAVE_POLICY_FWD + +/* Define to 1 if you have the `rad_create_request' function. */ +#undef HAVE_RAD_CREATE_REQUEST + +/* Is readline available? */ +#undef HAVE_READLINE + +/* Enable Security Context */ +#undef HAVE_SECCTX + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* sha2 is defined in sha.h */ +#undef HAVE_SHA2_IN_SHA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SHADOW_H + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDARG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strlcat' function. */ +#undef HAVE_STRLCAT + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_VARARGS_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Support IPv6 */ +#undef INET6 + +/* Use advanced IPv6 API */ +#undef INET6_ADVAPI + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Path to ipsec.h */ +#undef PATH_IPSEC_H + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* A 'va_copy' style function */ +#undef VA_COPY + +/* Version number of package */ +#undef VERSION + +/* SHA2 support */ +#undef WITH_SHA2 + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#undef YYTEXT_POINTER + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t diff --git a/ipsec-tools/config.sub b/ipsec-tools/config.sub new file mode 100755 index 00000000..d6b6b3c7 --- /dev/null +++ b/ipsec-tools/config.sub @@ -0,0 +1,1766 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-01-01' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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. +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/ipsec-tools/configure b/ipsec-tools/configure new file mode 100755 index 00000000..30101b9a --- /dev/null +++ b/ipsec-tools/configure @@ -0,0 +1,17373 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for ipsec-tools 0.8.2. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='ipsec-tools' +PACKAGE_TARNAME='ipsec-tools' +PACKAGE_VERSION='0.8.2' +PACKAGE_STRING='ipsec-tools 0.8.2' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_unique_file="configure.ac" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +include_racoondir +SECCTX_OBJS +NATT_OBJS +KRB5_CONFIG +FRAG_OBJS +HYBRID_OBJS +EXTRA_CRYPTO +CRYPTOBJS +LIBOBJS +GLIBC_BUGS +KERNEL_INCLUDE +CONFIGURE_AMFLAGS +RPM +INCLUDE_GLIBC +INSTALL_OPTS +LEXLIB +LEX_OUTPUT_ROOT +LEX +YFLAGS +YACC +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +EGREP +GREP +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_shared +enable_dependency_tracking +enable_static +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +with_kernel_headers +with_readline +with_flexdir +with_flexlib +with_openssl +enable_adminport +enable_rc5 +enable_idea +with_libiconv +enable_hybrid +enable_frag +with_libradius +with_libpam +with_libldap +enable_gssapi +enable_stats +enable_dpd +enable_samode_unspec +enable_ipv6 +enable_natt +enable_natt_versions +enable_broken_natt +enable_security_context +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +YACC +YFLAGS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures ipsec-tools 0.8.2 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/ipsec-tools] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of ipsec-tools 0.8.2:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-shared[=PKGS] build shared libraries [default=no] + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-adminport enable admin port + --enable-rc5 enable RC5 encryption (patented) + --enable-idea enable IDEA encryption (patented) + --enable-hybrid enable hybrid, both mode-cfg and xauth support + --enable-frag enable IKE fragmentation payload support + --enable-gssapi enable GSS-API authentication + --enable-stats enable statistics logging function + --enable-dpd enable dead peer detection + --enable-samode-unspec enable to use unspecified a mode of SA + --disable-ipv6 disable ipv6 support + --enable-natt enable NAT-Traversal (yes/no/kernel) + --enable-natt-versions=list list of supported NAT-T versions delimited by coma. + --enable-broken-natt broken in-kernel NAT-T + --enable-security-context enable Security Context(yes/no/kernel) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + --with-kernel-headers=/lib/modules//build/include + where your Linux Kernel headers are installed + --with-readline support readline input (yes by default) + --with-flex use directiory (default: no) + --with-flexlib= specify flex library. + --with-openssl=DIR specify OpenSSL directory + --with-libiconv=DIR specify libiconv path (like/usr/pkg) + --with-libradius=DIR specify libradius path (like/usr/pkg) + --with-libpam=DIR specify libpam path (like/usr/pkg) + --with-libldap=DIR specify libldap path (like/usr/pkg) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + YACC The `Yet Another Compiler Compiler' implementation to use. + Defaults to the first program found out of: `bison -y', `byacc', + `yacc'. + YFLAGS The list of arguments that will be passed by default to $YACC. + This script will default YFLAGS to the empty string to avoid a + default value of `-d' given by some make applications. + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +ipsec-tools configure 0.8.2 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval \${$4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_member + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by ipsec-tools $as_me 0.8.2, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_config_headers="$ac_config_headers config.h" + + +am__api_version='1.14' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='ipsec-tools' + VERSION='0.8.2' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=no +fi + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.2' +macro_revision='1.3337' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +for ac_prog in 'bison -y' byacc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_YACC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$YACC"; then + ac_cv_prog_YACC="$YACC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_YACC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +YACC=$ac_cv_prog_YACC +if test -n "$YACC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 +$as_echo "$YACC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$YACC" && break +done +test -n "$YACC" || YACC="yacc" + +for ac_prog in flex lex +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LEX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LEX"; then + ac_cv_prog_LEX="$LEX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LEX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LEX=$ac_cv_prog_LEX +if test -n "$LEX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 +$as_echo "$LEX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$LEX" && break +done +test -n "$LEX" || LEX=":" + +if test "x$LEX" != "x:"; then + cat >conftest.l <<_ACEOF +%% +a { ECHO; } +b { REJECT; } +c { yymore (); } +d { yyless (1); } +e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */ + yyless ((input () != 0)); } +f { unput (yytext[0]); } +. { BEGIN INITIAL; } +%% +#ifdef YYTEXT_POINTER +extern char *yytext; +#endif +int +main (void) +{ + return ! yylex () + ! yywrap (); +} +_ACEOF +{ { ac_try="$LEX conftest.l" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$LEX conftest.l") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 +$as_echo_n "checking lex output file root... " >&6; } +if ${ac_cv_prog_lex_root+:} false; then : + $as_echo_n "(cached) " >&6 +else + +if test -f lex.yy.c; then + ac_cv_prog_lex_root=lex.yy +elif test -f lexyy.c; then + ac_cv_prog_lex_root=lexyy +else + as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 +$as_echo "$ac_cv_prog_lex_root" >&6; } +LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root + +if test -z "${LEXLIB+set}"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 +$as_echo_n "checking lex library... " >&6; } +if ${ac_cv_lib_lex+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_LIBS=$LIBS + ac_cv_lib_lex='none needed' + for ac_lib in '' -lfl -ll; do + LIBS="$ac_lib $ac_save_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +`cat $LEX_OUTPUT_ROOT.c` +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_lex=$ac_lib +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + test "$ac_cv_lib_lex" != 'none needed' && break + done + LIBS=$ac_save_LIBS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 +$as_echo "$ac_cv_lib_lex" >&6; } + test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 +$as_echo_n "checking whether yytext is a pointer... " >&6; } +if ${ac_cv_prog_lex_yytext_pointer+:} false; then : + $as_echo_n "(cached) " >&6 +else + # POSIX says lex can declare yytext either as a pointer or an array; the +# default is implementation-dependent. Figure out which it is, since +# not all implementations provide the %pointer and %array declarations. +ac_cv_prog_lex_yytext_pointer=no +ac_save_LIBS=$LIBS +LIBS="$LEXLIB $ac_save_LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #define YYTEXT_POINTER 1 +`cat $LEX_OUTPUT_ROOT.c` +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_prog_lex_yytext_pointer=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_save_LIBS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 +$as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } +if test $ac_cv_prog_lex_yytext_pointer = yes; then + +$as_echo "#define YYTEXT_POINTER 1" >>confdefs.h + +fi +rm -f conftest.l $LEX_OUTPUT_ROOT.c + +fi +if test "$LEX" = :; then + LEX=${am_missing_run}flex +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + + +CFLAGS_ADD="$CFLAGS_ADD -Wall -Werror -Wno-unused" + +case $host in +*netbsd*) + LDFLAGS="-Wl,-R/usr/pkg/lib $LDFLAGS" + ;; +*linux*) + LIBS="$LIBS -lresolv" + INSTALL_OPTS="-o bin -g bin" + INCLUDE_GLIBC="include-glibc" + RPM="rpm" + + + + ;; +*darwin*) + LIBS="$LIBS -lresolv" + ;; +esac + +# Look up some IPsec-related headers +ac_fn_c_check_header_mongrel "$LINENO" "net/pfkeyv2.h" "ac_cv_header_net_pfkeyv2_h" "$ac_includes_default" +if test "x$ac_cv_header_net_pfkeyv2_h" = xyes; then : + have_net_pfkey=yes +else + have_net_pfkey=no +fi + + +ac_fn_c_check_header_mongrel "$LINENO" "netinet/ipsec.h" "ac_cv_header_netinet_ipsec_h" "$ac_includes_default" +if test "x$ac_cv_header_netinet_ipsec_h" = xyes; then : + have_netinet_ipsec=yes +else + have_netinet_ipsec=no +fi + + +ac_fn_c_check_header_mongrel "$LINENO" "netinet6/ipsec.h" "ac_cv_header_netinet6_ipsec_h" "$ac_includes_default" +if test "x$ac_cv_header_netinet6_ipsec_h" = xyes; then : + have_netinet6_ipsec=yes +else + have_netinet6_ipsec=no +fi + + +ac_fn_c_check_header_mongrel "$LINENO" "netipsec/ipsec.h" "ac_cv_header_netipsec_ipsec_h" "$ac_includes_default" +if test "x$ac_cv_header_netipsec_ipsec_h" = xyes; then : + have_netipsec_ipsec=yes +else + have_netipsec_ipsec=no +fi + + + +# FreeBSD >=7 has only +# NetBSD has but not +# XXX some *BSD still have both and , +# we can't decide which one to use (actually ) + + +if test "$have_netinet_ipsec$have_netinet6_ipsec$have_netipsec_ipsec" = nonoyes; then + have_netinet_ipsec=yes + +$as_echo "#define PATH_IPSEC_H " >>confdefs.h + +else + if test "$have_netinet_ipsec$have_netinet6_ipsec" = noyes; then + have_netinet_ipsec=yes + +$as_echo "#define PATH_IPSEC_H " >>confdefs.h + + else + # have_netinet_ipsec will be checked a few lines below + +$as_echo "#define PATH_IPSEC_H " >>confdefs.h + + fi +fi + +case "$host_os" in + *linux*) + +# Check whether --with-kernel-headers was given. +if test "${with_kernel_headers+set}" = set; then : + withval=$with_kernel_headers; KERNEL_INCLUDE="$with_kernel_headers" + CONFIGURE_AMFLAGS="--with-kernel-headers=$with_kernel_headers" + +else + KERNEL_INCLUDE="/lib/modules/`uname -r`/build/include" +fi + + + as_ac_Header=`$as_echo "ac_cv_header_$KERNEL_INCLUDE/linux/pfkeyv2.h" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$KERNEL_INCLUDE/linux/pfkeyv2.h" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + +else + ac_fn_c_check_header_mongrel "$LINENO" "/usr/src/linux/include/linux/pfkeyv2.h" "ac_cv_header__usr_src_linux_include_linux_pfkeyv2_h" "$ac_includes_default" +if test "x$ac_cv_header__usr_src_linux_include_linux_pfkeyv2_h" = xyes; then : + KERNEL_INCLUDE=/usr/src/linux/include +else + as_fn_error $? "Unable to find linux-2.6 kernel headers. Aborting." "$LINENO" 5 +fi + + +fi + + + + # We need the configure script to run with correct kernel headers. + # However we don't want to point to kernel source tree in compile time, + # i.e. this will be removed from CPPFLAGS at the end of configure. + CPPFLAGS="-I$KERNEL_INCLUDE $CPPFLAGS" + + ac_fn_c_check_member "$LINENO" "struct sadb_x_policy" "sadb_x_policy_priority" "ac_cv_member_struct_sadb_x_policy_sadb_x_policy_priority" "#include \"$KERNEL_INCLUDE/linux/pfkeyv2.h\" +" +if test "x$ac_cv_member_struct_sadb_x_policy_sadb_x_policy_priority" = xyes; then : + +$as_echo "#define HAVE_PFKEY_POLICY_PRIORITY /**/" >>confdefs.h + +fi + + + GLIBC_BUGS='-include ${top_srcdir}/src/include-glibc/glibc-bugs.h -I${top_srcdir}/src/include-glibc -I${top_builddir}/src/include-glibc' + GLIBC_BUGS_LOCAL="-include ${srcdir-.}/src/include-glibc/glibc-bugs.h -I${srcdir-.}/src/include-glibc -I./src/include-glibc" + CPPFLAGS="$GLIBC_BUGS_LOCAL $CPPFLAGS" + CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS" + + ;; + *) + if test "$have_net_pfkey$have_netinet_ipsec" != yesyes; then + if test "$have_net_pfkey" = yes; then + as_fn_error $? "Found net/pfkeyv2.h but not netinet/ipsec.h. Aborting." "$LINENO" 5 + else + as_fn_error $? "Found netinet/ipsec.h but not net/pfkeyv2.h. Aborting." "$LINENO" 5 + fi + fi + ;; +esac + +### Some basic toolchain checks + +# Checks for header files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 +$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } +if ${ac_cv_header_sys_wait_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_sys_wait_h=yes +else + ac_cv_header_sys_wait_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 +$as_echo "$ac_cv_header_sys_wait_h" >&6; } +if test $ac_cv_header_sys_wait_h = yes; then + +$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h + +fi + +for ac_header in limits.h sys/time.h unistd.h stdarg.h varargs.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in shadow.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "shadow.h" "ac_cv_header_shadow_h" "$ac_includes_default" +if test "x$ac_cv_header_shadow_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SHADOW_H 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 +$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } +if ${ac_cv_struct_tm+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_struct_tm=time.h +else + ac_cv_struct_tm=sys/time.h +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 +$as_echo "$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then + +$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h + +fi + + +# Checks for library functions. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5 +$as_echo_n "checking for working memcmp... " >&6; } +if ${ac_cv_func_memcmp_working+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_memcmp_working=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Some versions of memcmp are not 8-bit clean. */ + char c0 = '\100', c1 = '\200', c2 = '\201'; + if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) + return 1; + + /* The Next x86 OpenStep bug shows up only when comparing 16 bytes + or more and with at least one buffer not starting on a 4-byte boundary. + William Lewis provided this test program. */ + { + char foo[21]; + char bar[21]; + int i; + for (i = 0; i < 4; i++) + { + char *a = foo + i; + char *b = bar + i; + strcpy (a, "--------01111111"); + strcpy (b, "--------10000000"); + if (memcmp (a, b, 16) >= 0) + return 1; + } + return 0; + } + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_memcmp_working=yes +else + ac_cv_func_memcmp_working=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5 +$as_echo "$ac_cv_func_memcmp_working" >&6; } +test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in + *" memcmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" + ;; +esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 +$as_echo_n "checking return type of signal handlers... " >&6; } +if ${ac_cv_type_signal+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_type_signal=int +else + ac_cv_type_signal=void +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 +$as_echo "$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +for ac_func in vprintf +do : + ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" +if test "x$ac_cv_func_vprintf" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VPRINTF 1 +_ACEOF + +ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" +if test "x$ac_cv_func__doprnt" = xyes; then : + +$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h + +fi + +fi +done + + +for ac_func in gettimeofday select socket strerror strtol strtoul strlcpy strlcat +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup" +if test "x$ac_cv_func_strdup" = xyes; then : + $as_echo "#define HAVE_STRDUP 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" strdup.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strdup.$ac_objext" + ;; +esac + +fi + + + + saved_CFLAGS=$CFLAGS + CFLAGS="-Wall -O2" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an implementation of va_copy()" >&5 +$as_echo_n "checking for an implementation of va_copy()... " >&6; } +if ${ac_cv_va_copy+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cross compiling... Unable to test va_copy" >&5 +$as_echo "$as_me: WARNING: Cross compiling... Unable to test va_copy" >&2;} + ac_cv_va_copy=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + void func (int i, ...) { + va_list args1, args2; + va_start (args1, i); + va_copy (args2, args1); + if (va_arg (args1, int) != 1 || va_arg (args2, int) != 1) + exit (1); + va_end (args1); + va_end (args2); + } + int main() { + func (0, 1); + return 0; + } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_va_copy=yes +else + ac_cv_va_copy=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_va_copy" >&5 +$as_echo "$ac_cv_va_copy" >&6; } + if test x$ac_cv_va_copy != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an implementation of __va_copy()" >&5 +$as_echo_n "checking for an implementation of __va_copy()... " >&6; } +if ${ac_cv___va_copy+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cross compiling... Unable to test __va_copy" >&5 +$as_echo "$as_me: WARNING: Cross compiling... Unable to test __va_copy" >&2;} + ac_cv___va_copy=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + void func (int i, ...) { + va_list args1, args2; + va_start (args1, i); + __va_copy (args2, args1); + if (va_arg (args1, int) != 1 || va_arg (args2, int) != 1) + exit (1); + va_end (args1); + va_end (args2); + } + int main() { + func (0, 1); + return 0; + } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv___va_copy=yes +else + ac_cv___va_copy=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___va_copy" >&5 +$as_echo "$ac_cv___va_copy" >&6; } + fi + + if test "x$ac_cv_va_copy" = "xyes"; then + va_copy_func=va_copy + elif test "x$ac_cv___va_copy" = "xyes"; then + va_copy_func=__va_copy + fi + + if test -n "$va_copy_func"; then + +cat >>confdefs.h <<_ACEOF +#define VA_COPY $va_copy_func +_ACEOF + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Hmm, neither va_copy() nor __va_copy() found." >&5 +$as_echo "$as_me: WARNING: Hmm, neither va_copy() nor __va_copy() found." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Using a generic fallback." >&5 +$as_echo "$as_me: WARNING: Using a generic fallback." >&2;} + fi + CFLAGS=$saved_CFLAGS + unset saved_CFLAGS + + +# Check if printf accepts "%z" type modifier for size_t argument +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if printf accepts %z" >&5 +$as_echo_n "checking if printf accepts %z... " >&6; } +saved_CFLAGS=$CFLAGS +CFLAGS="$CFLAGS -Wall -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + +printf("%zu\n", (size_t)-1); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; + CFLAGS_ADD="$CFLAGS_ADD -Wno-format"; + +$as_echo "#define BROKEN_PRINTF /**/" >>confdefs.h + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS=$saved_CFLAGS + +# Can we use __func__ macro? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if __func__ is available" >&5 +$as_echo_n "checking if __func__ is available... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +char *x = __func__; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +$as_echo "#define HAVE_FUNC_MACRO /**/" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +# Check if readline support is requested +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if readline support is requested" >&5 +$as_echo_n "checking if readline support is requested... " >&6; } + +# Check whether --with-readline was given. +if test "${with_readline+set}" = set; then : + withval=$with_readline; with_readline="$withval" +else + with_readline="yes" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_readline" >&5 +$as_echo "$with_readline" >&6; } + +# Is readline available? +if test $with_readline != "no"; then + ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_readline_readline_h" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + + +$as_echo "#define HAVE_READLINE /**/" >>confdefs.h + + LIBS="$LIBS -lreadline" + +fi + +fi + + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-flex option is specified" >&5 +$as_echo_n "checking if --with-flex option is specified... " >&6; } + +# Check whether --with-flexdir was given. +if test "${with_flexdir+set}" = set; then : + withval=$with_flexdir; flexdir="$withval" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flexdir-dirdefault}" >&5 +$as_echo "${flexdir-dirdefault}" >&6; } + +if test "x$flexdir" != "x"; then + LIBS="$LIBS $flexdir/libfl.a" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-flexlib option is specified" >&5 +$as_echo_n "checking if --with-flexlib option is specified... " >&6; } + +# Check whether --with-flexlib was given. +if test "${with_flexlib+set}" = set; then : + withval=$with_flexlib; flexlib="$withval" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flexlib-default}" >&5 +$as_echo "${flexlib-default}" >&6; } + +if test "x$flexlib" != "x"; then + LIBS="$LIBS $flexlib" +fi + +# Check if a different OpenSSL directory was specified +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-openssl option is specified" >&5 +$as_echo_n "checking if --with-openssl option is specified... " >&6; } + +# Check whether --with-openssl was given. +if test "${with_openssl+set}" = set; then : + withval=$with_openssl; crypto_dir=$withval +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${crypto_dir-default}" >&5 +$as_echo "${crypto_dir-default}" >&6; } + +if test "x$crypto_dir" != "x"; then + LIBS="$LIBS -L${crypto_dir}/lib" + CPPFLAGS="-I${crypto_dir}/include $CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking openssl version" >&5 +$as_echo_n "checking openssl version... " >&6; } + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if OPENSSL_VERSION_NUMBER < 0x0090813fL +#error OpenSSL version is too old ... +#endif + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: too old" >&5 +$as_echo "too old" >&6; } +as_fn_error $? "OpenSSL version must be 0.9.8s or higher. Aborting." "$LINENO" 5 + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +for ac_header in openssl/engine.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "openssl/engine.h" "ac_cv_header_openssl_engine_h" "$ac_includes_default" +if test "x$ac_cv_header_openssl_engine_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_OPENSSL_ENGINE_H 1 +_ACEOF + +fi + +done + + +# checking rijndael +for ac_header in openssl/aes.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "openssl/aes.h" "ac_cv_header_openssl_aes_h" "$ac_includes_default" +if test "x$ac_cv_header_openssl_aes_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_OPENSSL_AES_H 1 +_ACEOF + +else + CRYPTOBJS="$CRYPTOBJS rijndael-api-fst.o rijndael-alg-fst.o" +fi + +done + + +# checking sha2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking sha2 support" >&5 +$as_echo_n "checking sha2 support... " >&6; } + +$as_echo "#define WITH_SHA2 /**/" >>confdefs.h + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +ac_fn_c_check_header_mongrel "$LINENO" "openssl/sha2.h" "ac_cv_header_openssl_sha2_h" "$ac_includes_default" +if test "x$ac_cv_header_openssl_sha2_h" = xyes; then : + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if sha2 is defined in openssl/sha.h" >&5 +$as_echo_n "checking if sha2 is defined in openssl/sha.h... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #ifdef HAVE_SYS_TYPES_H + #include + #endif + #include + +int +main () +{ + + SHA256_CTX ctx; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_SHA2_IN_SHA_H /**/" >>confdefs.h + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + case " $LIBOBJS " in + *" sha2.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS sha2.$ac_objext" + ;; +esac + + CRYPTOBJS="$CRYPTOBJS sha2.o" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + CPPFLAGS_ADD="$CPPFLAGS_ADD -I\${top_srcdir}/src/racoon/missing" + +fi + + + + +# checking camellia +for ac_header in openssl/camellia.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "openssl/camellia.h" "ac_cv_header_openssl_camellia_h" "$ac_includes_default" +if test "x$ac_cv_header_openssl_camellia_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_OPENSSL_CAMELLIA_H 1 +_ACEOF + +fi + +done + + + +# Option --enable-adminport +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-adminport option is specified" >&5 +$as_echo_n "checking if --enable-adminport option is specified... " >&6; } +# Check whether --enable-adminport was given. +if test "${enable_adminport+set}" = set; then : + enableval=$enable_adminport; +else + enable_adminport=no +fi + +if test $enable_adminport = "yes"; then + +$as_echo "#define ENABLE_ADMINPORT /**/" >>confdefs.h + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_adminport" >&5 +$as_echo "$enable_adminport" >&6; } + +# Option RC5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-rc5 option is specified" >&5 +$as_echo_n "checking if --enable-rc5 option is specified... " >&6; } +# Check whether --enable-rc5 was given. +if test "${enable_rc5+set}" = set; then : + enableval=$enable_rc5; +else + enable_rc5=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_rc5" >&5 +$as_echo "$enable_rc5" >&6; } + +if test $enable_rc5 = "yes"; then + for ac_header in openssl/rc5.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "openssl/rc5.h" "ac_cv_header_openssl_rc5_h" "$ac_includes_default" +if test "x$ac_cv_header_openssl_rc5_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_OPENSSL_RC5_H 1 +_ACEOF + +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for RC5_32_encrypt in -lcrypto_rc5" >&5 +$as_echo_n "checking for RC5_32_encrypt in -lcrypto_rc5... " >&6; } +if ${ac_cv_lib_crypto_rc5_RC5_32_encrypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto_rc5 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char RC5_32_encrypt (); +int +main () +{ +return RC5_32_encrypt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_rc5_RC5_32_encrypt=yes +else + ac_cv_lib_crypto_rc5_RC5_32_encrypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_rc5_RC5_32_encrypt" >&5 +$as_echo "$ac_cv_lib_crypto_rc5_RC5_32_encrypt" >&6; } +if test "x$ac_cv_lib_crypto_rc5_RC5_32_encrypt" = xyes; then : + EXTRA_CRYPTO="$EXTRA_CRYPTO -lcrypto_rc5" +fi + +fi + +# Option IDEA +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-idea option is specified" >&5 +$as_echo_n "checking if --enable-idea option is specified... " >&6; } +# Check whether --enable-idea was given. +if test "${enable_idea+set}" = set; then : + enableval=$enable_idea; +else + enable_idea=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_idea" >&5 +$as_echo "$enable_idea" >&6; } + +if test $enable_idea = "yes"; then + for ac_header in openssl/idea.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "openssl/idea.h" "ac_cv_header_openssl_idea_h" "$ac_includes_default" +if test "x$ac_cv_header_openssl_idea_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_OPENSSL_IDEA_H 1 +_ACEOF + +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for idea_encrypt in -lcrypto_idea" >&5 +$as_echo_n "checking for idea_encrypt in -lcrypto_idea... " >&6; } +if ${ac_cv_lib_crypto_idea_idea_encrypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto_idea $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char idea_encrypt (); +int +main () +{ +return idea_encrypt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_idea_idea_encrypt=yes +else + ac_cv_lib_crypto_idea_idea_encrypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_idea_idea_encrypt" >&5 +$as_echo "$ac_cv_lib_crypto_idea_idea_encrypt" >&6; } +if test "x$ac_cv_lib_crypto_idea_idea_encrypt" = xyes; then : + EXTRA_CRYPTO="$EXTRA_CRYPTO -lcrypto_idea" +fi + +fi + + +# For dynamic libradius + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypto containing MD5_Init" >&5 +$as_echo_n "checking for crypto containing MD5_Init... " >&6; } +if ${ac_cv_search_MD5_Init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS="$LIBS" +ac_cv_search_MD5_Init="no" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char MD5_Init (); +int +main () +{ +return MD5_Init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_MD5_Init="none required" +else + LIBS="-lcrypto $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char MD5_Init (); +int +main () +{ +return MD5_Init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_MD5_Init="-lcrypto" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$ac_func_search_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_MD5_Init" >&5 +$as_echo "$ac_cv_search_MD5_Init" >&6; } +if test "$ac_cv_search_MD5_Init" != "no"; then + test "$ac_cv_search_MD5_Init" = "none required" || LIBS="$ac_cv_search_MD5_Init $LIBS" + +else : + +fi + +# Check if we need -lutil for login(3) + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for util containing login" >&5 +$as_echo_n "checking for util containing login... " >&6; } +if ${ac_cv_search_login+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS="$LIBS" +ac_cv_search_login="no" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char login (); +int +main () +{ +return login (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_login="none required" +else + LIBS="-lutil $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char login (); +int +main () +{ +return login (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_login="-lutil" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$ac_func_search_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_login" >&5 +$as_echo "$ac_cv_search_login" >&6; } +if test "$ac_cv_search_login" != "no"; then + test "$ac_cv_search_login" = "none required" || LIBS="$ac_cv_search_login $LIBS" + +else : + +fi + +# Specify libiconv prefix +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-libiconv option is specified" >&5 +$as_echo_n "checking if --with-libiconv option is specified... " >&6; } + +# Check whether --with-libiconv was given. +if test "${with_libiconv+set}" = set; then : + withval=$with_libiconv; libiconv_dir=$withval +else + libiconv_dir=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libiconv_dir" >&5 +$as_echo "$libiconv_dir" >&6; } +if test "$libiconv_dir" != "no"; then + if test "$libiconv_dir" = "yes" ; then + libiconv_dir=""; + fi; + if test "x$libiconv_dir" = "x"; then + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv containing iconv_open" >&5 +$as_echo_n "checking for iconv containing iconv_open... " >&6; } +if ${ac_cv_search_iconv_open+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS="$LIBS" +ac_cv_search_iconv_open="no" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char iconv_open (); +int +main () +{ +return iconv_open (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_iconv_open="none required" +else + LIBS="-liconv $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char iconv_open (); +int +main () +{ +return iconv_open (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_iconv_open="-liconv" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$ac_func_search_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_iconv_open" >&5 +$as_echo "$ac_cv_search_iconv_open" >&6; } +if test "$ac_cv_search_iconv_open" != "no"; then + test "$ac_cv_search_iconv_open" = "none required" || LIBS="$ac_cv_search_iconv_open $LIBS" + +else : + +fi + else + if test -d "$libiconv_dir/lib" -a \ + -d "$libiconv_dir/include" ; then + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv containing iconv_open" >&5 +$as_echo_n "checking for iconv containing iconv_open... " >&6; } +if ${ac_cv_search_iconv_open+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS="$LIBS" +ac_cv_search_iconv_open="no" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char iconv_open (); +int +main () +{ +return iconv_open (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_iconv_open="none required" +else + LIBS="-liconv $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char iconv_open (); +int +main () +{ +return iconv_open (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_iconv_open="-liconv" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$ac_func_search_save_LIBS" + test "$ac_cv_search_iconv_open" = "no" && for i in "$libiconv_dir/lib"; do + LIBS="-L$i -liconv $ac_func_search_save_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char iconv_open (); +int +main () +{ +return iconv_open (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_iconv_open="-L$i -liconv" + break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +LIBS="$ac_func_search_save_LIBS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_iconv_open" >&5 +$as_echo "$ac_cv_search_iconv_open" >&6; } +if test "$ac_cv_search_iconv_open" != "no"; then + test "$ac_cv_search_iconv_open" = "none required" || LIBS="$ac_cv_search_iconv_open $LIBS" + +else : + +fi + CPPFLAGS_ADD="$CPPFLAGS_ADD -I$libiconv_dir/include" + else + as_fn_error $? "ICONV libs or includes not found. Aborting." "$LINENO" 5 + fi + fi + LIBS="$LIBS -L$libiconv_dir/lib -R$libiconv_dir/lib -liconv" + for ac_func in iconv_open +do : + ac_fn_c_check_func "$LINENO" "iconv_open" "ac_cv_func_iconv_open" +if test "x$ac_cv_func_iconv_open" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ICONV_OPEN 1 +_ACEOF + +fi +done + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-hybrid option is specified" >&5 +$as_echo_n "checking if --enable-hybrid option is specified... " >&6; } +# Check whether --enable-hybrid was given. +if test "${enable_hybrid+set}" = set; then : + enableval=$enable_hybrid; +else + enable_hybrid=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_hybrid" >&5 +$as_echo "$enable_hybrid" >&6; } + +if test "x$enable_hybrid" = "xyes"; then + case $host in + *darwin*) + ;; + *) + LIBS="$LIBS -lcrypt"; + ;; + esac + HYBRID_OBJS="isakmp_xauth.o isakmp_cfg.o isakmp_unity.o throttle.o" + + +$as_echo "#define ENABLE_HYBRID /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-frag option is specified" >&5 +$as_echo_n "checking if --enable-frag option is specified... " >&6; } +# Check whether --enable-frag was given. +if test "${enable_frag+set}" = set; then : + enableval=$enable_frag; +else + enable_frag=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_frag" >&5 +$as_echo "$enable_frag" >&6; } + +if test "x$enable_frag" = "xyes"; then + case $host in + *darwin*) + ;; + *) + LIBS="$LIBS -lcrypt"; + ;; + esac + FRAG_OBJS="isakmp_frag.o" + + +$as_echo "#define ENABLE_FRAG /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-libradius option is specified" >&5 +$as_echo_n "checking if --with-libradius option is specified... " >&6; } + +# Check whether --with-libradius was given. +if test "${with_libradius+set}" = set; then : + withval=$with_libradius; libradius_dir=$withval +else + libradius_dir=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libradius_dir" >&5 +$as_echo "$libradius_dir" >&6; } +if test "$libradius_dir" != "no"; then + if test "$libradius_dir" = "yes" ; then + libradius_dir=""; + fi; + if test "x$libradius_dir" = "x"; then + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for radius containing rad_create_request" >&5 +$as_echo_n "checking for radius containing rad_create_request... " >&6; } +if ${ac_cv_search_rad_create_request+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS="$LIBS" +ac_cv_search_rad_create_request="no" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char rad_create_request (); +int +main () +{ +return rad_create_request (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_rad_create_request="none required" +else + LIBS="-lradius $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char rad_create_request (); +int +main () +{ +return rad_create_request (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_rad_create_request="-lradius" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$ac_func_search_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_rad_create_request" >&5 +$as_echo "$ac_cv_search_rad_create_request" >&6; } +if test "$ac_cv_search_rad_create_request" != "no"; then + test "$ac_cv_search_rad_create_request" = "none required" || LIBS="$ac_cv_search_rad_create_request $LIBS" + +else : + +fi + else + if test -d "$libradius_dir/lib" -a \ + -d "$libradius_dir/include" ; then + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for radius containing rad_create_request" >&5 +$as_echo_n "checking for radius containing rad_create_request... " >&6; } +if ${ac_cv_search_rad_create_request+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS="$LIBS" +ac_cv_search_rad_create_request="no" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char rad_create_request (); +int +main () +{ +return rad_create_request (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_rad_create_request="none required" +else + LIBS="-lradius $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char rad_create_request (); +int +main () +{ +return rad_create_request (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_rad_create_request="-lradius" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$ac_func_search_save_LIBS" + test "$ac_cv_search_rad_create_request" = "no" && for i in "$libradius_dir/lib"; do + LIBS="-L$i -lradius $ac_func_search_save_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char rad_create_request (); +int +main () +{ +return rad_create_request (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_rad_create_request="-L$i -lradius" + break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +LIBS="$ac_func_search_save_LIBS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_rad_create_request" >&5 +$as_echo "$ac_cv_search_rad_create_request" >&6; } +if test "$ac_cv_search_rad_create_request" != "no"; then + test "$ac_cv_search_rad_create_request" = "none required" || LIBS="$ac_cv_search_rad_create_request $LIBS" + +else : + +fi + CPPFLAGS_ADD="$CPPFLAGS_ADD -I$libradius_dir/include" + else + as_fn_error $? "RADIUS libs or includes not found. Aborting." "$LINENO" 5 + fi + fi + +$as_echo "#define HAVE_LIBRADIUS /**/" >>confdefs.h + + LIBS="$LIBS -L$libradius_dir/lib -R$libradius_dir/lib -lradius" + for ac_func in rad_create_request +do : + ac_fn_c_check_func "$LINENO" "rad_create_request" "ac_cv_func_rad_create_request" +if test "x$ac_cv_func_rad_create_request" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_RAD_CREATE_REQUEST 1 +_ACEOF + +fi +done + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-libpam option is specified" >&5 +$as_echo_n "checking if --with-libpam option is specified... " >&6; } + +# Check whether --with-libpam was given. +if test "${with_libpam+set}" = set; then : + withval=$with_libpam; libpam_dir=$withval +else + libpam_dir=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libpam_dir" >&5 +$as_echo "$libpam_dir" >&6; } +if test "$libpam_dir" != "no"; then + if test "$libpam_dir" = "yes" ; then + libpam_dir=""; + fi; + if test "x$libpam_dir" = "x"; then + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam containing pam_start" >&5 +$as_echo_n "checking for pam containing pam_start... " >&6; } +if ${ac_cv_search_pam_start+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS="$LIBS" +ac_cv_search_pam_start="no" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pam_start (); +int +main () +{ +return pam_start (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_pam_start="none required" +else + LIBS="-lpam $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pam_start (); +int +main () +{ +return pam_start (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_pam_start="-lpam" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$ac_func_search_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pam_start" >&5 +$as_echo "$ac_cv_search_pam_start" >&6; } +if test "$ac_cv_search_pam_start" != "no"; then + test "$ac_cv_search_pam_start" = "none required" || LIBS="$ac_cv_search_pam_start $LIBS" + +else : + +fi + else + if test -d "$libpam_dir/lib" -a \ + -d "$libpam_dir/include" ; then + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam containing pam_start" >&5 +$as_echo_n "checking for pam containing pam_start... " >&6; } +if ${ac_cv_search_pam_start+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS="$LIBS" +ac_cv_search_pam_start="no" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pam_start (); +int +main () +{ +return pam_start (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_pam_start="none required" +else + LIBS="-lpam $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pam_start (); +int +main () +{ +return pam_start (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_pam_start="-lpam" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$ac_func_search_save_LIBS" + test "$ac_cv_search_pam_start" = "no" && for i in "$libpam_dir/lib"; do + LIBS="-L$i -lpam $ac_func_search_save_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pam_start (); +int +main () +{ +return pam_start (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_pam_start="-L$i -lpam" + break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +LIBS="$ac_func_search_save_LIBS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pam_start" >&5 +$as_echo "$ac_cv_search_pam_start" >&6; } +if test "$ac_cv_search_pam_start" != "no"; then + test "$ac_cv_search_pam_start" = "none required" || LIBS="$ac_cv_search_pam_start $LIBS" + +else : + +fi + CPPFLAGS_ADD="$CPPFLAGS_ADD -I$libpam_dir/include" + else + as_fn_error $? "PAM libs or includes not found. Aborting." "$LINENO" 5 + fi + fi + +$as_echo "#define HAVE_LIBPAM /**/" >>confdefs.h + + LIBS="$LIBS -L$libpam_dir/lib -R$libpam_dir/lib -lpam" + for ac_func in pam_start +do : + ac_fn_c_check_func "$LINENO" "pam_start" "ac_cv_func_pam_start" +if test "x$ac_cv_func_pam_start" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PAM_START 1 +_ACEOF + +fi +done + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-libldap option is specified" >&5 +$as_echo_n "checking if --with-libldap option is specified... " >&6; } + +# Check whether --with-libldap was given. +if test "${with_libldap+set}" = set; then : + withval=$with_libldap; libldap_dir=$withval +else + libldap_dir=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libldap_dir" >&5 +$as_echo "$libldap_dir" >&6; } +if test "$libldap_dir" != "no"; then + if test "$libldap_dir" = "yes" ; then + libldap_dir=""; + fi; + if test "x$libldap_dir" = "x"; then + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldap containing ldap_init" >&5 +$as_echo_n "checking for ldap containing ldap_init... " >&6; } +if ${ac_cv_search_ldap_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS="$LIBS" +ac_cv_search_ldap_init="no" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ldap_init (); +int +main () +{ +return ldap_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ldap_init="none required" +else + LIBS="-lldap $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ldap_init (); +int +main () +{ +return ldap_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ldap_init="-lldap" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$ac_func_search_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ldap_init" >&5 +$as_echo "$ac_cv_search_ldap_init" >&6; } +if test "$ac_cv_search_ldap_init" != "no"; then + test "$ac_cv_search_ldap_init" = "none required" || LIBS="$ac_cv_search_ldap_init $LIBS" + +else : + +fi + else + if test -d "$libldap_dir/lib" -a \ + -d "$libldap_dir/include" ; then + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldap containing ldap_init" >&5 +$as_echo_n "checking for ldap containing ldap_init... " >&6; } +if ${ac_cv_search_ldap_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS="$LIBS" +ac_cv_search_ldap_init="no" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ldap_init (); +int +main () +{ +return ldap_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ldap_init="none required" +else + LIBS="-lldap $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ldap_init (); +int +main () +{ +return ldap_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ldap_init="-lldap" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$ac_func_search_save_LIBS" + test "$ac_cv_search_ldap_init" = "no" && for i in "$libldap_dir/lib"; do + LIBS="-L$i -lldap $ac_func_search_save_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ldap_init (); +int +main () +{ +return ldap_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ldap_init="-L$i -lldap" + break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +LIBS="$ac_func_search_save_LIBS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ldap_init" >&5 +$as_echo "$ac_cv_search_ldap_init" >&6; } +if test "$ac_cv_search_ldap_init" != "no"; then + test "$ac_cv_search_ldap_init" = "none required" || LIBS="$ac_cv_search_ldap_init $LIBS" + +else : + +fi + CPPFLAGS_ADD="$CPPFLAGS_ADD -I$libldap_dir/include" + else + as_fn_error $? "LDAP libs or includes not found. Aborting." "$LINENO" 5 + fi + fi + +$as_echo "#define HAVE_LIBLDAP /**/" >>confdefs.h + + LIBS="$LIBS -L$libldap_dir/lib -R$libldap_dir/lib -lldap" + + saved_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -Wall -Werror" + saved_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + #if LDAP_API_VERSION < 2004 + #error OpenLDAP version is too old ... + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: too old" >&5 +$as_echo "too old" >&6; } + as_fn_error $? "OpenLDAP version must be 2.0 or higher. Aborting." "$LINENO" 5 + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$saved_CFLAGS + CPPFLAGS=$saved_CPPFLAGS +fi + +# Check for Kerberos5 support +# XXX This must come after all --with-* tests, else the +# -liconv checks will not work +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-gssapi option is specified" >&5 +$as_echo_n "checking if --enable-gssapi option is specified... " >&6; } +# Check whether --enable-gssapi was given. +if test "${enable_gssapi+set}" = set; then : + enableval=$enable_gssapi; +else + enable_gssapi=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_gssapi" >&5 +$as_echo "$enable_gssapi" >&6; } +# Extract the first word of "krb5-config", so it can be a program name with args. +set dummy krb5-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_KRB5_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $KRB5_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_KRB5_CONFIG="$KRB5_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_KRB5_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_KRB5_CONFIG" && ac_cv_path_KRB5_CONFIG="no" + ;; +esac +fi +KRB5_CONFIG=$ac_cv_path_KRB5_CONFIG +if test -n "$KRB5_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KRB5_CONFIG" >&5 +$as_echo "$KRB5_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "x$enable_gssapi" = "xyes"; then + if test "$KRB5_CONFIG" != "no"; then + krb5_incdir="`$KRB5_CONFIG --cflags gssapi`" + krb5_libs="`$KRB5_CONFIG --libs gssapi`" + else + # No krb5-config; let's make some assumptions based on + # the OS. + case $host_os in + netbsd*) + krb5_incdir="-I/usr/include/krb5" + krb5_libs="-lgssapi -lkrb5 -lcom_err -lroken -lasn1" + ;; + *) + as_fn_error $? "krb5-config not found, but needed for GSSAPI support. Aborting." "$LINENO" 5 + ;; + esac + fi + LIBS="$LIBS $krb5_libs" + CPPFLAGS_ADD="$krb5_incdir $CPPFLAGS_ADD" + +$as_echo "#define HAVE_GSSAPI /**/" >>confdefs.h + + + # Check if iconv 2nd argument needs const + saved_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -Wall -Werror" + saved_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD" + ac_fn_c_check_header_mongrel "$LINENO" "iconv.h" "ac_cv_header_iconv_h" "$ac_includes_default" +if test "x$ac_cv_header_iconv_h" = xyes; then : + +else + as_fn_error $? "iconv.h not found, but needed for GSSAPI support. Aborting." "$LINENO" 5 +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if iconv second argument needs const" >&5 +$as_echo_n "checking if iconv second argument needs const... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + +int +main () +{ + + iconv_t cd = NULL; + const char **src = NULL; + size_t *srcleft = NULL; + char **dst = NULL; + size_t *dstleft = NULL; + + (void)iconv(cd, src, srcleft, dst, dstleft); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_ICONV_2ND_CONST /**/" >>confdefs.h + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$saved_CFLAGS + CPPFLAGS=$saved_CPPFLAGS + + # libiconv is often integrated into libc. If a with-* option + # caused a non libc-based iconv.h to be catched instead of + # the libc-based iconv.h, then we need to link with -liconv + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -liconv is required" >&5 +$as_echo_n "checking if -liconv is required... " >&6; } + saved_CPPFLAGS=$CPPFLAGS + saved_LIBS=$LIBS + CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + +int +main () +{ + + (void)iconv_open("ascii", "ascii"); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +else + + LIBS="$LIBS -liconv" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + +int +main () +{ + + (void)iconv_open("ascii", "ascii"); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + saved_LIBS=$LIBS + +else + + as_fn_error $? "cannot use iconv" "$LINENO" 5 + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CPPFLAGS=$saved_CPPFLAGS + LIBS=$saved_LIBS +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-stats option is specified" >&5 +$as_echo_n "checking if --enable-stats option is specified... " >&6; } +# Check whether --enable-stats was given. +if test "${enable_stats+set}" = set; then : + enableval=$enable_stats; +else + enable_stats=no +fi + +if test "x$enable_stats" = "xyes"; then + +$as_echo "#define ENABLE_STATS /**/" >>confdefs.h + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_stats" >&5 +$as_echo "$enable_stats" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-dpd option is specified" >&5 +$as_echo_n "checking if --enable-dpd option is specified... " >&6; } +# Check whether --enable-dpd was given. +if test "${enable_dpd+set}" = set; then : + enableval=$enable_dpd; +else + enable_dpd=no +fi + +if test "x$enable_dpd" = "xyes"; then + +$as_echo "#define ENABLE_DPD /**/" >>confdefs.h + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_dpd" >&5 +$as_echo "$enable_dpd" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-samode-unspec option is specified" >&5 +$as_echo_n "checking if --enable-samode-unspec option is specified... " >&6; } +# Check whether --enable-samode-unspec was given. +if test "${enable_samode_unspec+set}" = set; then : + enableval=$enable_samode_unspec; +else + enable_samode_unspec=no +fi + +if test "x$enable_samode_unspec" = "xyes"; then + case $host_os in + *linux*) + cat << EOC + +ERROR: --enable-samode-unspec is not supported under linux +because linux kernel do not support it. This option is disabled +to prevent mysterious problems. + +If you REALLY know what your are doing, remove this check. +EOC + exit 1; + ;; + esac + +$as_echo "#define ENABLE_SAMODE_UNSPECIFIED /**/" >>confdefs.h + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_samode_unspec" >&5 +$as_echo "$enable_samode_unspec" >&6; } + +# Checks if IPv6 is requested +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable ipv6" >&5 +$as_echo_n "checking whether to enable ipv6... " >&6; } +# Check whether --enable-ipv6 was given. +if test "${enable_ipv6+set}" = set; then : + enableval=$enable_ipv6; case "$enableval" in + no) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ipv6=no + ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + ipv6=yes + ;; + esac +else + if test "$cross_compiling" = yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ipv6=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + /* AF_INET6 avalable check */ +#include +#include +main() +{ + exit(0); + if (socket(AF_INET6, SOCK_STREAM, 0) < 0) + exit(1); + else + exit(0); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define INET6 /**/" >>confdefs.h + + ipv6=yes +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ipv6=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi + + +if test "$ipv6" = "yes"; then + +$as_echo "#define INET6 /**/" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for advanced API support" >&5 +$as_echo_n "checking for advanced API support... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef INET6 +#define INET6 +#endif +#include +#include +int +main () +{ +struct in6_pktinfo a; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define INET6_ADVAPI /**/" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking getaddrinfo bug" >&5 +$as_echo_n "checking getaddrinfo bug... " >&6; } + saved_CFLAGS=$CFLAGS + CFLAGS="-Wall -O2" + if test "$cross_compiling" = yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Cross compiling ... Assuming getaddrinfo is not buggy." >&5 +$as_echo "Cross compiling ... Assuming getaddrinfo is not buggy." >&6; } + buggygetaddrinfo=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #include + #include + #include + #include + + int main() + { + int passive, gaierr, inet4 = 0, inet6 = 0; + struct addrinfo hints, *ai, *aitop; + char straddr[INET6_ADDRSTRLEN], strport[16]; + + for (passive = 0; passive <= 1; passive++) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = passive ? AI_PASSIVE : 0; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_socktype = SOCK_STREAM; + if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) { + (void)gai_strerror(gaierr); + goto bad; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_addr == NULL || + ai->ai_addrlen == 0 || + getnameinfo(ai->ai_addr, ai->ai_addrlen, + straddr, sizeof(straddr), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + goto bad; + } + switch (ai->ai_family) { + case AF_INET: + if (strcmp(strport, "54321") != 0) { + goto bad; + } + if (passive) { + if (strcmp(straddr, "0.0.0.0") != 0) { + goto bad; + } + } else { + if (strcmp(straddr, "127.0.0.1") != 0) { + goto bad; + } + } + inet4++; + break; + case AF_INET6: + if (strcmp(strport, "54321") != 0) { + goto bad; + } + if (passive) { + if (strcmp(straddr, "::") != 0) { + goto bad; + } + } else { + if (strcmp(straddr, "::1") != 0) { + goto bad; + } + } + inet6++; + break; + case AF_UNSPEC: + goto bad; + break; + default: + /* another family support? */ + break; + } + } + } + + if (!(inet4 == 0 || inet4 == 2)) + goto bad; + if (!(inet6 == 0 || inet6 == 2)) + goto bad; + + if (aitop) + freeaddrinfo(aitop); + exit(0); + + bad: + if (aitop) + freeaddrinfo(aitop); + exit(1); + } + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: good" >&5 +$as_echo "good" >&6; } + buggygetaddrinfo=no +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: buggy" >&5 +$as_echo "buggy" >&6; } + buggygetaddrinfo=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + CFLAGS=$saved_CFLAGS + unset saved_CFLAGS + +if test "$buggygetaddrinfo" = "yes"; then + as_fn_error $? "Broken getaddrinfo() is no longer supported. Aborting." "$LINENO" 5 +fi + +# Check if kernel support is available for NAT-T, defaults to no. +kernel_natt="no" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel NAT-Traversal support" >&5 +$as_echo_n "checking kernel NAT-Traversal support... " >&6; } +case $host_os in +linux*) +# Linux kernel NAT-T check +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#ifdef SADB_X_EXT_NAT_T_TYPE +yes +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "yes" >/dev/null 2>&1; then : + kernel_natt="yes" +fi +rm -f conftest* + + ;; +freebsd*|netbsd*) +# NetBSD case +# Same check for FreeBSD +ac_fn_c_check_member "$LINENO" "struct sadb_x_nat_t_type" "sadb_x_nat_t_type_len" "ac_cv_member_struct_sadb_x_nat_t_type_sadb_x_nat_t_type_len" " +#define _KERNEL +#include +#include + +" +if test "x$ac_cv_member_struct_sadb_x_nat_t_type_sadb_x_nat_t_type_len" = xyes; then : + kernel_natt="yes" +fi + + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernel_natt" >&5 +$as_echo "$kernel_natt" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support NAT-T" >&5 +$as_echo_n "checking whether to support NAT-T... " >&6; } +# Check whether --enable-natt was given. +if test "${enable_natt+set}" = set; then : + enableval=$enable_natt; if test "$enable_natt" = "kernel"; then enable_natt=$kernel_natt; fi +else + enable_natt=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_natt" >&5 +$as_echo "$enable_natt" >&6; } + +if test "$enable_natt" = "yes"; then + if test "$kernel_natt" = "no" ; then + as_fn_error $? "NAT-T requested, but no kernel support! Aborting." "$LINENO" 5 + else + +$as_echo "#define ENABLE_NATT /**/" >>confdefs.h + + NATT_OBJS="nattraversal.o" + + fi +fi + +# Set up defines for supported NAT-T versions. +natt_versions_default="00,02,rfc" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which NAT-T versions to support" >&5 +$as_echo_n "checking which NAT-T versions to support... " >&6; } +# Check whether --enable-natt_versions was given. +if test "${enable_natt_versions+set}" = set; then : + enableval=$enable_natt_versions; test "$enable_natt_versions" = "yes" && enable_natt_versions=$natt_versions_default +else + enable_natt_versions=$natt_versions_default +fi + +if test "$enable_natt" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_natt_versions" >&5 +$as_echo "$enable_natt_versions" >&6; } + for i in `echo $enable_natt_versions | tr ',cfr' ' CFR'`; do + case $i in + 0|00) +$as_echo "#define ENABLE_NATT_00 /**/" >>confdefs.h + ;; + 1|01) +$as_echo "#define ENABLE_NATT_01 /**/" >>confdefs.h + ;; + 2|02) +$as_echo "#define ENABLE_NATT_02 /**/" >>confdefs.h + ;; + 3|03) +$as_echo "#define ENABLE_NATT_03 /**/" >>confdefs.h + ;; + 4|04) +$as_echo "#define ENABLE_NATT_04 /**/" >>confdefs.h + ;; + 5|05) +$as_echo "#define ENABLE_NATT_05 /**/" >>confdefs.h + ;; + 6|06) +$as_echo "#define ENABLE_NATT_06 /**/" >>confdefs.h + ;; + 7|07) +$as_echo "#define ENABLE_NATT_07 /**/" >>confdefs.h + ;; + 8|08) +$as_echo "#define ENABLE_NATT_08 /**/" >>confdefs.h + ;; + RFC) +$as_echo "#define ENABLE_NATT_RFC /**/" >>confdefs.h + ;; + *) as_fn_error $? "Unknown NAT-T version. Aborting." "$LINENO" 5 ;; + esac + done + unset i +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-broken-natt option is specified" >&5 +$as_echo_n "checking if --enable-broken-natt option is specified... " >&6; } +# Check whether --enable-broken-natt was given. +if test "${enable_broken_natt+set}" = set; then : + enableval=$enable_broken_natt; +else + enable_broken_natt=no +fi + +if test "x$enable_broken_natt" = "xyes"; then + +$as_echo "#define BROKEN_NATT /**/" >>confdefs.h + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_broken_natt" >&5 +$as_echo "$enable_broken_natt" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we support FWD policy" >&5 +$as_echo_n "checking whether we support FWD policy... " >&6; } +case $host in + *linux*) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + +int +main () +{ + + int fwd = IPSEC_DIR_FWD; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_POLICY_FWD /**/" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; +esac + +ac_fn_c_check_type "$LINENO" "ipsec_policy_t" "ac_cv_type_ipsec_policy_t" " + #include + #include + +" +if test "x$ac_cv_type_ipsec_policy_t" = xyes; then : + +$as_echo "#define HAVE_IPSEC_POLICY_T /**/" >>confdefs.h + +fi + + +# Check if kernel support is available for Security Context, defaults to no. +kernel_secctx="no" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel Security Context support" >&5 +$as_echo_n "checking kernel Security Context support... " >&6; } +case $host_os in +linux*) +# Linux kernel Security Context check +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#ifdef SADB_X_EXT_SEC_CTX +yes +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "yes" >/dev/null 2>&1; then : + kernel_secctx="yes" +fi +rm -f conftest* + + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernel_secctx" >&5 +$as_echo "$kernel_secctx" >&6; } + +ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default" +if test "x$ac_cv_header_selinux_selinux_h" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for avc_init in -lselinux" >&5 +$as_echo_n "checking for avc_init in -lselinux... " >&6; } +if ${ac_cv_lib_selinux_avc_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lselinux $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char avc_init (); +int +main () +{ +return avc_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_selinux_avc_init=yes +else + ac_cv_lib_selinux_avc_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_avc_init" >&5 +$as_echo "$ac_cv_lib_selinux_avc_init" >&6; } +if test "x$ac_cv_lib_selinux_avc_init" = xyes; then : + selinux_support=yes +else + selinux_support=no +fi + +else + selinux_support=no +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support Security Context" >&5 +$as_echo_n "checking whether to support Security Context... " >&6; } +# Check whether --enable-security-context was given. +if test "${enable_security_context+set}" = set; then : + enableval=$enable_security_context; if test "$enable_security_context" = "kernel"; then + enable_security_context=$kernel_secctx; fi +else + enable_security_context=$kernel_secctx +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_security_context" >&5 +$as_echo "$enable_security_context" >&6; } + +if test "$enable_security_context" = "yes"; then + if test "$kernel_secctx" = "no" ; then + as_fn_error $? "Security Context requested, but no kernel support! Aborting." "$LINENO" 5 + else + if test "$selinux_support" = "no"; then + as_fn_error $? "Security Context requested, but no selinux support! Aborting." "$LINENO" 5 + else + +$as_echo "#define HAVE_SECCTX /**/" >>confdefs.h + + SECCTX_OBJS="security.o" + + LIBS="$LIBS -lselinux" + fi + fi +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rt containing clock_gettime" >&5 +$as_echo_n "checking for rt containing clock_gettime... " >&6; } +if ${ac_cv_search_clock_gettime+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS="$LIBS" +ac_cv_search_clock_gettime="no" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clock_gettime (); +int +main () +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_clock_gettime="none required" +else + LIBS="-lrt $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clock_gettime (); +int +main () +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_clock_gettime="-lrt" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$ac_func_search_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 +$as_echo "$ac_cv_search_clock_gettime" >&6; } +if test "$ac_cv_search_clock_gettime" != "no"; then + test "$ac_cv_search_clock_gettime" = "none required" || LIBS="$ac_cv_search_clock_gettime $LIBS" + +else : + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for monotonic system clock" >&5 +$as_echo_n "checking for monotonic system clock... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +clock_gettime(CLOCK_MONOTONIC, NULL); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +$as_echo "#define HAVE_CLOCK_MONOTONIC /**/" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +CFLAGS="$CFLAGS $CFLAGS_ADD" +CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD" + +case $host in + *linux*) + # Remove KERNEL_INCLUDE from CPPFLAGS. It will + # be symlinked to src/include-glibc/linux in + # compile time. + CPPFLAGS=`echo $CPPFLAGS | sed "s,-I$KERNEL_INCLUDE,,"` + ;; +esac + +include_racoondir=${includedir}/racoon + + +ac_config_files="$ac_config_files Makefile package_version.h src/Makefile src/include-glibc/Makefile src/libipsec/Makefile src/setkey/Makefile src/racoon/Makefile src/racoon/samples/psk.txt src/racoon/samples/racoon.conf rpm/Makefile rpm/suse/Makefile rpm/suse/ipsec-tools.spec" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by ipsec-tools $as_me 0.8.2, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +ipsec-tools config.status 0.8.2 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "package_version.h") CONFIG_FILES="$CONFIG_FILES package_version.h" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "src/include-glibc/Makefile") CONFIG_FILES="$CONFIG_FILES src/include-glibc/Makefile" ;; + "src/libipsec/Makefile") CONFIG_FILES="$CONFIG_FILES src/libipsec/Makefile" ;; + "src/setkey/Makefile") CONFIG_FILES="$CONFIG_FILES src/setkey/Makefile" ;; + "src/racoon/Makefile") CONFIG_FILES="$CONFIG_FILES src/racoon/Makefile" ;; + "src/racoon/samples/psk.txt") CONFIG_FILES="$CONFIG_FILES src/racoon/samples/psk.txt" ;; + "src/racoon/samples/racoon.conf") CONFIG_FILES="$CONFIG_FILES src/racoon/samples/racoon.conf" ;; + "rpm/Makefile") CONFIG_FILES="$CONFIG_FILES rpm/Makefile" ;; + "rpm/suse/Makefile") CONFIG_FILES="$CONFIG_FILES rpm/suse/Makefile" ;; + "rpm/suse/ipsec-tools.spec") CONFIG_FILES="$CONFIG_FILES rpm/suse/ipsec-tools.spec" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="" + +# ### BEGIN LIBTOOL CONFIG + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/ipsec-tools/configure.ac b/ipsec-tools/configure.ac new file mode 100644 index 00000000..85062456 --- /dev/null +++ b/ipsec-tools/configure.ac @@ -0,0 +1,825 @@ +dnl -*- mode: m4 -*- +dnl Id: configure.ac,v 1.77 2006/07/20 19:19:27 manubsd Exp + +AC_PREREQ(2.52) +AC_INIT(ipsec-tools, 0.8.2) +AC_CONFIG_SRCDIR([configure.ac]) +AC_CONFIG_HEADERS(config.h) + +AM_INIT_AUTOMAKE(dist-bzip2) + +AC_ENABLE_SHARED(no) + +AC_PROG_CC +AC_HEADER_STDC +AC_PROG_LIBTOOL +AC_PROG_YACC +AM_PROG_LEX +AC_SUBST(LEXLIB) +AC_PROG_EGREP + +CFLAGS_ADD="$CFLAGS_ADD -Wall -Werror -Wno-unused" + +case $host in +*netbsd*) + LDFLAGS="-Wl,-R/usr/pkg/lib $LDFLAGS" + ;; +*linux*) + LIBS="$LIBS -lresolv" + INSTALL_OPTS="-o bin -g bin" + INCLUDE_GLIBC="include-glibc" + RPM="rpm" + AC_SUBST(INSTALL_OPTS) + AC_SUBST(INCLUDE_GLIBC) + AC_SUBST(RPM) + ;; +*darwin*) + LIBS="$LIBS -lresolv" + ;; +esac + +# Look up some IPsec-related headers +AC_CHECK_HEADER(net/pfkeyv2.h, [have_net_pfkey=yes], [have_net_pfkey=no]) +AC_CHECK_HEADER(netinet/ipsec.h, [have_netinet_ipsec=yes], [have_netinet_ipsec=no]) +AC_CHECK_HEADER(netinet6/ipsec.h, [have_netinet6_ipsec=yes], [have_netinet6_ipsec=no]) +AC_CHECK_HEADER(netipsec/ipsec.h, [have_netipsec_ipsec=yes], [have_netipsec_ipsec=no]) + +# FreeBSD >=7 has only +# NetBSD has but not +# XXX some *BSD still have both and , +# we can't decide which one to use (actually ) + + +if test "$have_netinet_ipsec$have_netinet6_ipsec$have_netipsec_ipsec" = nonoyes; then + have_netinet_ipsec=yes + AC_DEFINE(PATH_IPSEC_H, [], [Path to ipsec.h]) +else + if test "$have_netinet_ipsec$have_netinet6_ipsec" = noyes; then + have_netinet_ipsec=yes + AC_DEFINE(PATH_IPSEC_H, [], [Path to ipsec.h]) + else + # have_netinet_ipsec will be checked a few lines below + AC_DEFINE(PATH_IPSEC_H, [], [Path to ipsec.h]) + fi +fi + +case "$host_os" in + *linux*) + AC_ARG_WITH(kernel-headers, + AC_HELP_STRING([--with-kernel-headers=/lib/modules//build/include], + [where your Linux Kernel headers are installed]), + [ KERNEL_INCLUDE="$with_kernel_headers" + CONFIGURE_AMFLAGS="--with-kernel-headers=$with_kernel_headers" + AC_SUBST(CONFIGURE_AMFLAGS) ], + [ KERNEL_INCLUDE="/lib/modules/`uname -r`/build/include" ]) + + AC_CHECK_HEADER($KERNEL_INCLUDE/linux/pfkeyv2.h, , + [ AC_CHECK_HEADER(/usr/src/linux/include/linux/pfkeyv2.h, + KERNEL_INCLUDE=/usr/src/linux/include , + [ AC_MSG_ERROR([Unable to find linux-2.6 kernel headers. Aborting.]) ] ) ] ) + AC_SUBST(KERNEL_INCLUDE) + # We need the configure script to run with correct kernel headers. + # However we don't want to point to kernel source tree in compile time, + # i.e. this will be removed from CPPFLAGS at the end of configure. + CPPFLAGS="-I$KERNEL_INCLUDE $CPPFLAGS" + + AC_CHECK_MEMBER(struct sadb_x_policy.sadb_x_policy_priority, + [AC_DEFINE(HAVE_PFKEY_POLICY_PRIORITY, [], + [Are PF_KEY policy priorities supported?])], [], + [#include "$KERNEL_INCLUDE/linux/pfkeyv2.h"]) + + GLIBC_BUGS='-include ${top_srcdir}/src/include-glibc/glibc-bugs.h -I${top_srcdir}/src/include-glibc -I${top_builddir}/src/include-glibc' + GLIBC_BUGS_LOCAL="-include ${srcdir-.}/src/include-glibc/glibc-bugs.h -I${srcdir-.}/src/include-glibc -I./src/include-glibc" + CPPFLAGS="$GLIBC_BUGS_LOCAL $CPPFLAGS" + CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS" + AC_SUBST(GLIBC_BUGS) + ;; + *) + if test "$have_net_pfkey$have_netinet_ipsec" != yesyes; then + if test "$have_net_pfkey" = yes; then + AC_MSG_ERROR([Found net/pfkeyv2.h but not netinet/ipsec.h. Aborting.]) + else + AC_MSG_ERROR([Found netinet/ipsec.h but not net/pfkeyv2.h. Aborting.]) + fi + fi + ;; +esac + +### Some basic toolchain checks + +# Checks for header files. +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS(limits.h sys/time.h unistd.h stdarg.h varargs.h) +AC_CHECK_HEADERS(shadow.h) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_HEADER_TIME +AC_STRUCT_TM + +# Checks for library functions. +AC_FUNC_MEMCMP +AC_TYPE_SIGNAL +AC_FUNC_VPRINTF +AC_CHECK_FUNCS(gettimeofday select socket strerror strtol strtoul strlcpy strlcat) +AC_REPLACE_FUNCS(strdup) +RACOON_CHECK_VA_COPY + +# Check if printf accepts "%z" type modifier for size_t argument +AC_MSG_CHECKING(if printf accepts %z) +saved_CFLAGS=$CFLAGS +CFLAGS="$CFLAGS -Wall -Werror" +AC_TRY_COMPILE([ +#include +], [ +printf("%zu\n", (size_t)-1); +], + [AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no); + CFLAGS_ADD="$CFLAGS_ADD -Wno-format"; + AC_DEFINE(BROKEN_PRINTF, [], [If printf doesn't support %zu.]) + ]) +CFLAGS=$saved_CFLAGS + +# Can we use __func__ macro? +AC_MSG_CHECKING(if __func__ is available) +AC_TRY_COMPILE( +[#include +], [char *x = __func__;], + [AC_DEFINE([HAVE_FUNC_MACRO], [], [Have __func__ macro]) + AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no)]) + +# Check if readline support is requested +AC_MSG_CHECKING(if readline support is requested) +AC_ARG_WITH(readline, + [ --with-readline support readline input (yes by default)], + [with_readline="$withval"], [with_readline="yes"]) +AC_MSG_RESULT($with_readline) + +# Is readline available? +if test $with_readline != "no"; then + AC_CHECK_HEADER([readline/readline.h], + [AC_CHECK_LIB(readline, readline, [ + AC_DEFINE(HAVE_READLINE, [], + [Is readline available?]) + LIBS="$LIBS -lreadline" + ], [])], []) +fi + + +AC_MSG_CHECKING(if --with-flex option is specified) +AC_ARG_WITH(flexdir, + [AC_HELP_STRING([--with-flex], [use directiory (default: no)])], + [flexdir="$withval"]) +AC_MSG_RESULT(${flexdir-dirdefault}) + +if test "x$flexdir" != "x"; then + LIBS="$LIBS $flexdir/libfl.a" +fi + +AC_MSG_CHECKING(if --with-flexlib option is specified) +AC_ARG_WITH(flexlib, + [ --with-flexlib= specify flex library.], + [flexlib="$withval"]) +AC_MSG_RESULT(${flexlib-default}) + +if test "x$flexlib" != "x"; then + LIBS="$LIBS $flexlib" +fi + +# Check if a different OpenSSL directory was specified +AC_MSG_CHECKING(if --with-openssl option is specified) +AC_ARG_WITH(openssl, [ --with-openssl=DIR specify OpenSSL directory], + [crypto_dir=$withval]) +AC_MSG_RESULT(${crypto_dir-default}) + +if test "x$crypto_dir" != "x"; then + LIBS="$LIBS -L${crypto_dir}/lib" + CPPFLAGS="-I${crypto_dir}/include $CPPFLAGS" +fi +AC_MSG_CHECKING(openssl version) + +AC_TRY_COMPILE( +[#include +], +[#if OPENSSL_VERSION_NUMBER < 0x0090813fL +#error OpenSSL version is too old ... +#endif], +[AC_MSG_RESULT([ok])], +[AC_MSG_RESULT(too old) +AC_MSG_ERROR([OpenSSL version must be 0.9.8s or higher. Aborting.]) +]) + +AC_CHECK_HEADERS(openssl/engine.h) + +# checking rijndael +AC_CHECK_HEADERS([openssl/aes.h], [], + [CRYPTOBJS="$CRYPTOBJS rijndael-api-fst.o rijndael-alg-fst.o"]) + +# checking sha2 +AC_MSG_CHECKING(sha2 support) +AC_DEFINE([WITH_SHA2], [], [SHA2 support]) +AC_MSG_RESULT(yes) +AC_CHECK_HEADER(openssl/sha2.h, [], [ + AC_MSG_CHECKING(if sha2 is defined in openssl/sha.h) + AC_TRY_COMPILE([ + #ifdef HAVE_SYS_TYPES_H + #include + #endif + #include + ], [ + SHA256_CTX ctx; + ], [ + AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_SHA2_IN_SHA_H], [], [sha2 is defined in sha.h]) + ], [AC_MSG_RESULT(no) + AC_LIBOBJ([sha2]) + CRYPTOBJS="$CRYPTOBJS sha2.o" + ]) + + CPPFLAGS_ADD="$CPPFLAGS_ADD -I\${top_srcdir}/src/racoon/missing" +]) +AC_SUBST(CRYPTOBJS) + +# checking camellia +AC_CHECK_HEADERS([openssl/camellia.h]) + + +# Option --enable-adminport +AC_MSG_CHECKING(if --enable-adminport option is specified) +AC_ARG_ENABLE(adminport, + [ --enable-adminport enable admin port], + [], [enable_adminport=no]) +if test $enable_adminport = "yes"; then + AC_DEFINE([ENABLE_ADMINPORT], [], [Enable admin port]) +fi +AC_MSG_RESULT($enable_adminport) + +# Option RC5 +AC_MSG_CHECKING(if --enable-rc5 option is specified) +AC_ARG_ENABLE(rc5, + [ --enable-rc5 enable RC5 encryption (patented)], + [], [enable_rc5=no]) +AC_MSG_RESULT($enable_rc5) + +if test $enable_rc5 = "yes"; then + AC_CHECK_HEADERS([openssl/rc5.h]) + AC_CHECK_LIB([crypto_rc5], [RC5_32_encrypt], + [EXTRA_CRYPTO="$EXTRA_CRYPTO -lcrypto_rc5"]) +fi + +# Option IDEA +AC_MSG_CHECKING(if --enable-idea option is specified) +AC_ARG_ENABLE(idea, + [ --enable-idea enable IDEA encryption (patented)], + [], [enable_idea=no]) +AC_MSG_RESULT($enable_idea) + +if test $enable_idea = "yes"; then + AC_CHECK_HEADERS([openssl/idea.h]) + AC_CHECK_LIB([crypto_idea], [idea_encrypt], + [EXTRA_CRYPTO="$EXTRA_CRYPTO -lcrypto_idea"]) +fi +AC_SUBST(EXTRA_CRYPTO) + +# For dynamic libradius +RACOON_PATH_LIBS([MD5_Init], [crypto]) + +# Check if we need -lutil for login(3) +RACOON_PATH_LIBS([login], [util]) + +# Specify libiconv prefix +AC_MSG_CHECKING(if --with-libiconv option is specified) +AC_ARG_WITH(libiconv, + [ --with-libiconv=DIR specify libiconv path (like/usr/pkg)], + [libiconv_dir=$withval], + [libiconv_dir=no]) +AC_MSG_RESULT($libiconv_dir) +if test "$libiconv_dir" != "no"; then + if test "$libiconv_dir" = "yes" ; then + libiconv_dir=""; + fi; + if test "x$libiconv_dir" = "x"; then + RACOON_PATH_LIBS([iconv_open], [iconv]) + else + if test -d "$libiconv_dir/lib" -a \ + -d "$libiconv_dir/include" ; then + RACOON_PATH_LIBS([iconv_open], [iconv], ["$libiconv_dir/lib"]) + CPPFLAGS_ADD="$CPPFLAGS_ADD -I$libiconv_dir/include" + else + AC_MSG_ERROR([ICONV libs or includes not found. Aborting.]) + fi + fi + LIBS="$LIBS -L$libiconv_dir/lib -R$libiconv_dir/lib -liconv" + AC_CHECK_FUNCS(iconv_open) +fi + +AC_MSG_CHECKING([if --enable-hybrid option is specified]) +AC_ARG_ENABLE(hybrid, + [ --enable-hybrid enable hybrid, both mode-cfg and xauth support], + [], [enable_hybrid=no]) +AC_MSG_RESULT($enable_hybrid) + +if test "x$enable_hybrid" = "xyes"; then + case $host in + *darwin*) + ;; + *) + LIBS="$LIBS -lcrypt"; + ;; + esac + HYBRID_OBJS="isakmp_xauth.o isakmp_cfg.o isakmp_unity.o throttle.o" + AC_SUBST(HYBRID_OBJS) + AC_DEFINE([ENABLE_HYBRID], [], [Hybrid authentication support]) +fi + +AC_MSG_CHECKING([if --enable-frag option is specified]) +AC_ARG_ENABLE(frag, + [ --enable-frag enable IKE fragmentation payload support], + [], [enable_frag=no]) +AC_MSG_RESULT($enable_frag) + +if test "x$enable_frag" = "xyes"; then + case $host in + *darwin*) + ;; + *) + LIBS="$LIBS -lcrypt"; + ;; + esac + FRAG_OBJS="isakmp_frag.o" + AC_SUBST(FRAG_OBJS) + AC_DEFINE([ENABLE_FRAG], [], [IKE fragmentation support]) +fi + +AC_MSG_CHECKING(if --with-libradius option is specified) +AC_ARG_WITH(libradius, + [ --with-libradius=DIR specify libradius path (like/usr/pkg)], + [libradius_dir=$withval], + [libradius_dir=no]) +AC_MSG_RESULT($libradius_dir) +if test "$libradius_dir" != "no"; then + if test "$libradius_dir" = "yes" ; then + libradius_dir=""; + fi; + if test "x$libradius_dir" = "x"; then + RACOON_PATH_LIBS([rad_create_request], [radius]) + else + if test -d "$libradius_dir/lib" -a \ + -d "$libradius_dir/include" ; then + RACOON_PATH_LIBS([rad_create_request], [radius], ["$libradius_dir/lib"]) + CPPFLAGS_ADD="$CPPFLAGS_ADD -I$libradius_dir/include" + else + AC_MSG_ERROR([RADIUS libs or includes not found. Aborting.]) + fi + fi + AC_DEFINE([HAVE_LIBRADIUS], [], [Hybrid authentication uses RADIUS]) + LIBS="$LIBS -L$libradius_dir/lib -R$libradius_dir/lib -lradius" + AC_CHECK_FUNCS(rad_create_request) +fi + +AC_MSG_CHECKING(if --with-libpam option is specified) +AC_ARG_WITH(libpam, + [ --with-libpam=DIR specify libpam path (like/usr/pkg)], + [libpam_dir=$withval], + [libpam_dir=no]) +AC_MSG_RESULT($libpam_dir) +if test "$libpam_dir" != "no"; then + if test "$libpam_dir" = "yes" ; then + libpam_dir=""; + fi; + if test "x$libpam_dir" = "x"; then + RACOON_PATH_LIBS([pam_start], [pam]) + else + if test -d "$libpam_dir/lib" -a \ + -d "$libpam_dir/include" ; then + RACOON_PATH_LIBS([pam_start], [pam], ["$libpam_dir/lib"]) + CPPFLAGS_ADD="$CPPFLAGS_ADD -I$libpam_dir/include" + else + AC_MSG_ERROR([PAM libs or includes not found. Aborting.]) + fi + fi + AC_DEFINE([HAVE_LIBPAM], [], [Hybrid authentication uses PAM]) + LIBS="$LIBS -L$libpam_dir/lib -R$libpam_dir/lib -lpam" + AC_CHECK_FUNCS(pam_start) +fi + +AC_MSG_CHECKING(if --with-libldap option is specified) +AC_ARG_WITH(libldap, + [ --with-libldap=DIR specify libldap path (like/usr/pkg)], + [libldap_dir=$withval], + [libldap_dir=no]) +AC_MSG_RESULT($libldap_dir) +if test "$libldap_dir" != "no"; then + if test "$libldap_dir" = "yes" ; then + libldap_dir=""; + fi; + if test "x$libldap_dir" = "x"; then + RACOON_PATH_LIBS([ldap_init], [ldap]) + else + if test -d "$libldap_dir/lib" -a \ + -d "$libldap_dir/include" ; then + RACOON_PATH_LIBS([ldap_init], [ldap], ["$libldap_dir/lib"]) + CPPFLAGS_ADD="$CPPFLAGS_ADD -I$libldap_dir/include" + else + AC_MSG_ERROR([LDAP libs or includes not found. Aborting.]) + fi + fi + AC_DEFINE([HAVE_LIBLDAP], [], [Hybrid authentication uses LDAP]) + LIBS="$LIBS -L$libldap_dir/lib -R$libldap_dir/lib -lldap" + + saved_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -Wall -Werror" + saved_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD" + AC_TRY_COMPILE( + [#include ], + [ + #if LDAP_API_VERSION < 2004 + #error OpenLDAP version is too old ... + #endif + ], + [AC_MSG_RESULT([ok])], + [ + AC_MSG_RESULT(too old) + AC_MSG_ERROR([OpenLDAP version must be 2.0 or higher. Aborting.]) + ]) + CFLAGS=$saved_CFLAGS + CPPFLAGS=$saved_CPPFLAGS +fi + +# Check for Kerberos5 support +# XXX This must come after all --with-* tests, else the +# -liconv checks will not work +AC_MSG_CHECKING(if --enable-gssapi option is specified) +AC_ARG_ENABLE(gssapi, + [ --enable-gssapi enable GSS-API authentication], + [], [enable_gssapi=no]) +AC_MSG_RESULT($enable_gssapi) +AC_PATH_PROG(KRB5_CONFIG,krb5-config,no) +if test "x$enable_gssapi" = "xyes"; then + if test "$KRB5_CONFIG" != "no"; then + krb5_incdir="`$KRB5_CONFIG --cflags gssapi`" + krb5_libs="`$KRB5_CONFIG --libs gssapi`" + else + # No krb5-config; let's make some assumptions based on + # the OS. + case $host_os in + netbsd*) + krb5_incdir="-I/usr/include/krb5" + krb5_libs="-lgssapi -lkrb5 -lcom_err -lroken -lasn1" + ;; + *) + AC_MSG_ERROR([krb5-config not found, but needed for GSSAPI support. Aborting.]) + ;; + esac + fi + LIBS="$LIBS $krb5_libs" + CPPFLAGS_ADD="$krb5_incdir $CPPFLAGS_ADD" + AC_DEFINE([HAVE_GSSAPI], [], [Enable GSS API]) + + # Check if iconv 2nd argument needs const + saved_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -Wall -Werror" + saved_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD" + AC_CHECK_HEADER([iconv.h], [], [AC_MSG_ERROR([iconv.h not found, but needed for GSSAPI support. Aborting.])]) + AC_MSG_CHECKING([if iconv second argument needs const]) + AC_TRY_COMPILE([ + #include + #include + ], [ + iconv_t cd = NULL; + const char **src = NULL; + size_t *srcleft = NULL; + char **dst = NULL; + size_t *dstleft = NULL; + + (void)iconv(cd, src, srcleft, dst, dstleft); + ], [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_ICONV_2ND_CONST], [], [Have iconv using const]) + ], [AC_MSG_RESULT(no)]) + CFLAGS=$saved_CFLAGS + CPPFLAGS=$saved_CPPFLAGS + + # libiconv is often integrated into libc. If a with-* option + # caused a non libc-based iconv.h to be catched instead of + # the libc-based iconv.h, then we need to link with -liconv + AC_MSG_CHECKING(if -liconv is required) + saved_CPPFLAGS=$CPPFLAGS + saved_LIBS=$LIBS + CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD" + AC_TRY_LINK([ + #include + ], [ + (void)iconv_open("ascii", "ascii"); + ], + [AC_MSG_RESULT(no)], + [ + LIBS="$LIBS -liconv" + AC_TRY_LINK([ + #include + ], [ + (void)iconv_open("ascii", "ascii"); + ], + [ + AC_MSG_RESULT(yes) + saved_LIBS=$LIBS + ], [ + AC_MSG_ERROR([cannot use iconv]) + ]) + ]) + CPPFLAGS=$saved_CPPFLAGS + LIBS=$saved_LIBS +fi + +AC_MSG_CHECKING(if --enable-stats option is specified) +AC_ARG_ENABLE(stats, + [ --enable-stats enable statistics logging function], + [], [enable_stats=no]) +if test "x$enable_stats" = "xyes"; then + AC_DEFINE([ENABLE_STATS], [], [Enable statictics]) +fi +AC_MSG_RESULT($enable_stats) + +AC_MSG_CHECKING(if --enable-dpd option is specified) +AC_ARG_ENABLE(dpd, + [ --enable-dpd enable dead peer detection], + [], [enable_dpd=no]) +if test "x$enable_dpd" = "xyes"; then + AC_DEFINE([ENABLE_DPD], [], [Enable dead peer detection]) +fi +AC_MSG_RESULT($enable_dpd) + +AC_MSG_CHECKING(if --enable-samode-unspec option is specified) +AC_ARG_ENABLE(samode-unspec, + [ --enable-samode-unspec enable to use unspecified a mode of SA], + [], [enable_samode_unspec=no]) +if test "x$enable_samode_unspec" = "xyes"; then + case $host_os in + *linux*) + cat << EOC + +ERROR: --enable-samode-unspec is not supported under linux +because linux kernel do not support it. This option is disabled +to prevent mysterious problems. + +If you REALLY know what your are doing, remove this check. +EOC + exit 1; + ;; + esac + AC_DEFINE([ENABLE_SAMODE_UNSPECIFIED], [], [Enable samode-unspec]) +fi +AC_MSG_RESULT($enable_samode_unspec) + +# Checks if IPv6 is requested +AC_MSG_CHECKING([whether to enable ipv6]) +AC_ARG_ENABLE(ipv6, +[ --disable-ipv6 disable ipv6 support], +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + ipv6=no + ;; + *) AC_MSG_RESULT(yes) + ipv6=yes + ;; + esac ], + + AC_TRY_RUN([ /* AF_INET6 avalable check */ +#include +#include +main() +{ + exit(0); + if (socket(AF_INET6, SOCK_STREAM, 0) < 0) + exit(1); + else + exit(0); +} +], + AC_MSG_RESULT(yes) + AC_DEFINE([INET6], [], [Support IPv6]) + ipv6=yes, + AC_MSG_RESULT(no) + ipv6=no, + AC_MSG_RESULT(no) + ipv6=no +)) + +if test "$ipv6" = "yes"; then + AC_DEFINE([INET6], [], [Support IPv6]) + AC_MSG_CHECKING(for advanced API support) + AC_TRY_COMPILE([#ifndef INET6 +#define INET6 +#endif +#include +#include ], + [struct in6_pktinfo a;], + [AC_MSG_RESULT(yes) + AC_DEFINE([INET6_ADVAPI], [], [Use advanced IPv6 API])], + [AC_MSG_RESULT(no)]) +fi + +RACOON_CHECK_BUGGY_GETADDRINFO +if test "$buggygetaddrinfo" = "yes"; then + AC_MSG_ERROR([Broken getaddrinfo() is no longer supported. Aborting.]) +fi + +# Check if kernel support is available for NAT-T, defaults to no. +kernel_natt="no" + +AC_MSG_CHECKING(kernel NAT-Traversal support) +case $host_os in +linux*) +# Linux kernel NAT-T check +AC_EGREP_CPP(yes, +[#include +#ifdef SADB_X_EXT_NAT_T_TYPE +yes +#endif +], [kernel_natt="yes"]) + ;; +freebsd*|netbsd*) +# NetBSD case +# Same check for FreeBSD +AC_CHECK_MEMBER(struct sadb_x_nat_t_type.sadb_x_nat_t_type_len, + [kernel_natt="yes"],, [ +#define _KERNEL +#include +#include +]) + ;; +esac +AC_MSG_RESULT($kernel_natt) + +AC_MSG_CHECKING(whether to support NAT-T) +AC_ARG_ENABLE(natt, + [ --enable-natt enable NAT-Traversal (yes/no/kernel)], + [ if test "$enable_natt" = "kernel"; then enable_natt=$kernel_natt; fi ], + [ enable_natt=no ]) +AC_MSG_RESULT($enable_natt) + +if test "$enable_natt" = "yes"; then + if test "$kernel_natt" = "no" ; then + AC_MSG_ERROR([NAT-T requested, but no kernel support! Aborting.]) + else + AC_DEFINE([ENABLE_NATT], [], [Enable NAT-Traversal]) + NATT_OBJS="nattraversal.o" + AC_SUBST(NATT_OBJS) + fi +fi + +# Set up defines for supported NAT-T versions. +natt_versions_default="00,02,rfc" +AC_MSG_CHECKING(which NAT-T versions to support) +AC_ARG_ENABLE(natt_versions, + [ --enable-natt-versions=list list of supported NAT-T versions delimited by coma.], + [ test "$enable_natt_versions" = "yes" && enable_natt_versions=$natt_versions_default ], + [ enable_natt_versions=$natt_versions_default ]) +if test "$enable_natt" = "yes"; then + AC_MSG_RESULT($enable_natt_versions) + for i in `echo $enable_natt_versions | tr ',cfr' ' CFR'`; do + case $i in + 0|00) AC_DEFINE([ENABLE_NATT_00], [], [Enable NAT-Traversal draft 00]) ;; + 1|01) AC_DEFINE([ENABLE_NATT_01], [], [Enable NAT-Traversal draft 01]) ;; + 2|02) AC_DEFINE([ENABLE_NATT_02], [], [Enable NAT-Traversal draft 02]) ;; + 3|03) AC_DEFINE([ENABLE_NATT_03], [], [Enable NAT-Traversal draft 03]) ;; + 4|04) AC_DEFINE([ENABLE_NATT_04], [], [Enable NAT-Traversal draft 04]) ;; + 5|05) AC_DEFINE([ENABLE_NATT_05], [], [Enable NAT-Traversal draft 05]) ;; + 6|06) AC_DEFINE([ENABLE_NATT_06], [], [Enable NAT-Traversal draft 06]) ;; + 7|07) AC_DEFINE([ENABLE_NATT_07], [], [Enable NAT-Traversal draft 07]) ;; + 8|08) AC_DEFINE([ENABLE_NATT_08], [], [Enable NAT-Traversal draft 08]) ;; + RFC) AC_DEFINE([ENABLE_NATT_RFC], [], [Enable NAT-Traversal RFC version]) ;; + *) AC_MSG_ERROR([Unknown NAT-T version. Aborting.]) ;; + esac + done + unset i +else + AC_MSG_RESULT([none]) +fi + +AC_MSG_CHECKING(if --enable-broken-natt option is specified) +AC_ARG_ENABLE(broken-natt, + [ --enable-broken-natt broken in-kernel NAT-T], + [], [enable_broken_natt=no]) +if test "x$enable_broken_natt" = "xyes"; then + AC_DEFINE([BROKEN_NATT], [], [in-kernel NAT-T is broken]) +fi +AC_MSG_RESULT($enable_broken_natt) + +AC_MSG_CHECKING(whether we support FWD policy) +case $host in + *linux*) + AC_TRY_COMPILE([ + #include + #include + ], [ + int fwd = IPSEC_DIR_FWD; + ], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_POLICY_FWD], [], [Have forward policy])], + [AC_MSG_RESULT(no)]) + ;; + *) + AC_MSG_RESULT(no) + ;; +esac + +AC_CHECK_TYPE([ipsec_policy_t], + [AC_DEFINE([HAVE_IPSEC_POLICY_T], [], [Have ipsec_policy_t])], + [], + [ + #include + #include + ]) + +# Check if kernel support is available for Security Context, defaults to no. +kernel_secctx="no" + +AC_MSG_CHECKING(kernel Security Context support) +case $host_os in +linux*) +# Linux kernel Security Context check +AC_EGREP_CPP(yes, +[#include +#ifdef SADB_X_EXT_SEC_CTX +yes +#endif +], [kernel_secctx="yes"]) + ;; +esac +AC_MSG_RESULT($kernel_secctx) + +AC_CHECK_HEADER(selinux/selinux.h, + [AC_CHECK_LIB(selinux, avc_init, [selinux_support=yes], + [selinux_support=no])], [selinux_support=no]) + +AC_MSG_CHECKING(whether to support Security Context) +AC_ARG_ENABLE(security-context, + [ --enable-security-context enable Security Context(yes/no/kernel)], + [if test "$enable_security_context" = "kernel"; then + enable_security_context=$kernel_secctx; fi], + [enable_security_context=$kernel_secctx]) +AC_MSG_RESULT($enable_security_context) + +if test "$enable_security_context" = "yes"; then + if test "$kernel_secctx" = "no" ; then + AC_MSG_ERROR([Security Context requested, but no kernel support! Aborting.]) + else + if test "$selinux_support" = "no"; then + AC_MSG_ERROR([Security Context requested, but no selinux support! Aborting.]) + else + AC_DEFINE([HAVE_SECCTX], [], [Enable Security Context]) + SECCTX_OBJS="security.o" + AC_SUBST(SECCTX_OBJS) + LIBS="$LIBS -lselinux" + fi + fi +fi + +RACOON_PATH_LIBS([clock_gettime], [rt]) + +AC_MSG_CHECKING(for monotonic system clock) +AC_TRY_COMPILE( + [#include ], + [clock_gettime(CLOCK_MONOTONIC, NULL);], + [AC_DEFINE([HAVE_CLOCK_MONOTONIC], [], [Have a monotonic clock]) + AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no)]) + +CFLAGS="$CFLAGS $CFLAGS_ADD" +CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD" + +case $host in + *linux*) + # Remove KERNEL_INCLUDE from CPPFLAGS. It will + # be symlinked to src/include-glibc/linux in + # compile time. + CPPFLAGS=`echo $CPPFLAGS | sed "s,-I$KERNEL_INCLUDE,,"` + ;; +esac + +include_racoondir=${includedir}/racoon +AC_SUBST(include_racoondir) + +AC_CONFIG_FILES([ + Makefile + package_version.h + src/Makefile + src/include-glibc/Makefile + src/libipsec/Makefile + src/setkey/Makefile + src/racoon/Makefile + src/racoon/samples/psk.txt + src/racoon/samples/racoon.conf + rpm/Makefile + rpm/suse/Makefile + rpm/suse/ipsec-tools.spec + ]) +AC_OUTPUT diff --git a/ipsec-tools/depcomp b/ipsec-tools/depcomp new file mode 100755 index 00000000..bd0ac089 --- /dev/null +++ b/ipsec-tools/depcomp @@ -0,0 +1,688 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2011-12-04.11; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# 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. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test "$stat" = 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/ \1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/ / + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/ipsec-tools/install-sh b/ipsec-tools/install-sh new file mode 100755 index 00000000..a9244eb0 --- /dev/null +++ b/ipsec-tools/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-01-19.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for `test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/ipsec-tools/ltmain.sh b/ipsec-tools/ltmain.sh new file mode 100644 index 00000000..63ae69dc --- /dev/null +++ b/ipsec-tools/ltmain.sh @@ -0,0 +1,9655 @@ + +# libtool (GNU libtool) 2.4.2 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --no-warn don't display warning messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.4.2 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . +# GNU libtool home page: . +# General help using GNU software: . + +PROGRAM=libtool +PACKAGE=libtool +VERSION=2.4.2 +TIMESTAMP="" +package_revision=1.3337 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $opt_debug + + $SED -n '/(C)/!b go + :more + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + +# func_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_warning=: +opt_verbose=: +opt_silent=false +opt_verbose=false + + +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do + opt="$1" + shift + case $opt in + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) + opt_silent=false +func_append preserve_args " $opt" + ;; + --no-warning|--no-warn) + opt_warning=false +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" + shift + ;; + + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + + # Separate optargs to long options: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; + esac + done + + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$absdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Remove ${wl} instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + func_resolve_sysroot "$deplib" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$opt_mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/ipsec-tools/missing b/ipsec-tools/missing new file mode 100755 index 00000000..86a8fc31 --- /dev/null +++ b/ipsec-tools/missing @@ -0,0 +1,331 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2012-01-06.13; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# 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, or (at your option) +# any later version. + +# 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. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/ipsec-tools/package_version.h.in b/ipsec-tools/package_version.h.in new file mode 100644 index 00000000..c876c31c --- /dev/null +++ b/ipsec-tools/package_version.h.in @@ -0,0 +1,5 @@ +#define TOP_PACKAGE "@PACKAGE@" +#define TOP_PACKAGE_NAME "@PACKAGE_NAME@" +#define TOP_PACKAGE_VERSION "@PACKAGE_VERSION@" +#define TOP_PACKAGE_STRING "@PACKAGE_STRING@" +#define TOP_PACKAGE_URL "http://ipsec-tools.sourceforge.net" diff --git a/ipsec-tools/rpm/Makefile.am b/ipsec-tools/rpm/Makefile.am new file mode 100644 index 00000000..b01b2ef3 --- /dev/null +++ b/ipsec-tools/rpm/Makefile.am @@ -0,0 +1,18 @@ +SUBDIRS = suse + +EXTRA_DIST = \ + ipsec-tools.spec.in + +all-local: ipsec-tools.spec + +## We borrow guile's convention and use @-...-@ as the substitution +## brackets here, instead of the usual @...@. This prevents autoconf +## from substituting the values directly into the left-hand sides of +## the sed substitutions. *sigh* +ipsec-tools.spec: ipsec-tools.spec.in Makefile + rm -f $@.tmp + sed < $< > $@.tmp \ + -e 's:@-VERSION-@:${VERSION}:' + mv $@.tmp $@ + +CLEANFILES = ipsec-tools.spec diff --git a/ipsec-tools/rpm/Makefile.in b/ipsec-tools/rpm/Makefile.in new file mode 100644 index 00000000..c3568724 --- /dev/null +++ b/ipsec-tools/rpm/Makefile.in @@ -0,0 +1,632 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = rpm +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acracoon.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGURE_AMFLAGS = @CONFIGURE_AMFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTOBJS = @CRYPTOBJS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_CRYPTO = @EXTRA_CRYPTO@ +FGREP = @FGREP@ +FRAG_OBJS = @FRAG_OBJS@ +GLIBC_BUGS = @GLIBC_BUGS@ +GREP = @GREP@ +HYBRID_OBJS = @HYBRID_OBJS@ +INCLUDE_GLIBC = @INCLUDE_GLIBC@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_OPTS = @INSTALL_OPTS@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KERNEL_INCLUDE = @KERNEL_INCLUDE@ +KRB5_CONFIG = @KRB5_CONFIG@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NATT_OBJS = @NATT_OBJS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RPM = @RPM@ +SECCTX_OBJS = @SECCTX_OBJS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +include_racoondir = @include_racoondir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = suse +EXTRA_DIST = \ + ipsec-tools.spec.in + +CLEANFILES = ipsec-tools.spec +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign rpm/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign rpm/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile all-local +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ + check check-am clean clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + + +all-local: ipsec-tools.spec + +ipsec-tools.spec: ipsec-tools.spec.in Makefile + rm -f $@.tmp + sed < $< > $@.tmp \ + -e 's:@-VERSION-@:${VERSION}:' + mv $@.tmp $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ipsec-tools/rpm/ipsec-tools.spec.in b/ipsec-tools/rpm/ipsec-tools.spec.in new file mode 100644 index 00000000..5eb5f72f --- /dev/null +++ b/ipsec-tools/rpm/ipsec-tools.spec.in @@ -0,0 +1,60 @@ +Summary: User-space IPsec tools for the Linux IPsec implementation +Name: ipsec-tools +Version: @-VERSION-@ +Release: 1 +Epoch: 1 +License: BSD +Group: System Environment/Base +URL: http://ipsec-tools.sourceforge.net/ +Source: http://prdownloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz +Requires: kernel >= 2.5.54 + +#BuildRequires: kernel-source >= 2.5.54 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + +%description +IPsec-Tools is a port of the KAME Project's IPsec tools to the Linux +IPsec implementation. IPsec-Tools provides racoon, an IKE daemon; libipsec, +a PFKey implementation; and setkey, a security policy and security +association database configuration utility. + +%prep +%setup -q + +%build +./configure --prefix=/usr --sysconfdir=/etc --exec-prefix=/ --mandir=%{_mandir} --libdir=/%{_lib} +make + +%install +rm -rf %{buildroot} +mkdir %{buildroot} +make install DESTDIR=%{buildroot} + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%clean +rm -rf %{buildroot} + +%files +%defattr(-,root,root) +%doc NEWS README ChangeLog +%dir %{_sysconfdir}/racoon +%config %{_sysconfdir}/racoon/* +/sbin/* +/%{_lib}/* +%{_includedir}/* +%{_mandir}/man[358]/* +%{_sbindir}/racoon + +%changelog +* Fri Mar 07 2003 Derek Atkins 0.2.1-1 +- Insert into code base. Dynamically generate the version string. + +* Fri Mar 07 2003 Chris Ricker 0.2.1-1 +- Rev to 0.2.1 release +- Remove unneeded patch + +* Thu Mar 06 2003 Chris Ricker 0.2-1 +- initial package diff --git a/ipsec-tools/rpm/suse/Makefile.am b/ipsec-tools/rpm/suse/Makefile.am new file mode 100644 index 00000000..e00df586 --- /dev/null +++ b/ipsec-tools/rpm/suse/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = ipsec-tools.spec.in ipsec-tools.spec racoon.init sysconfig.racoon diff --git a/ipsec-tools/rpm/suse/Makefile.in b/ipsec-tools/rpm/suse/Makefile.in new file mode 100644 index 00000000..c20d766e --- /dev/null +++ b/ipsec-tools/rpm/suse/Makefile.in @@ -0,0 +1,442 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = rpm/suse +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(srcdir)/ipsec-tools.spec.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acracoon.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = ipsec-tools.spec +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGURE_AMFLAGS = @CONFIGURE_AMFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTOBJS = @CRYPTOBJS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_CRYPTO = @EXTRA_CRYPTO@ +FGREP = @FGREP@ +FRAG_OBJS = @FRAG_OBJS@ +GLIBC_BUGS = @GLIBC_BUGS@ +GREP = @GREP@ +HYBRID_OBJS = @HYBRID_OBJS@ +INCLUDE_GLIBC = @INCLUDE_GLIBC@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_OPTS = @INSTALL_OPTS@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KERNEL_INCLUDE = @KERNEL_INCLUDE@ +KRB5_CONFIG = @KRB5_CONFIG@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NATT_OBJS = @NATT_OBJS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RPM = @RPM@ +SECCTX_OBJS = @SECCTX_OBJS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +include_racoondir = @include_racoondir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = ipsec-tools.spec.in ipsec-tools.spec racoon.init sysconfig.racoon +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign rpm/suse/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign rpm/suse/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +ipsec-tools.spec: $(top_builddir)/config.status $(srcdir)/ipsec-tools.spec.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ipsec-tools/rpm/suse/ipsec-tools.spec b/ipsec-tools/rpm/suse/ipsec-tools.spec new file mode 100644 index 00000000..fe132cea --- /dev/null +++ b/ipsec-tools/rpm/suse/ipsec-tools.spec @@ -0,0 +1,110 @@ +# +# spec file for package ipsec-tools +# +# Copyright (c) 2005 SUSE LINUX AG, Nuernberg, Germany. +# This file and all modifications and additions to the pristine +# package are under the same license as the package itself. +# +# Please submit bugfixes or comments via http://www.suse.de/feedback/ +# + +# norootforbuild +# neededforbuild kernel-source openssl openssl-devel readline-devel + +BuildRequires: aaa_base acl attr bash bind-utils bison bzip2 coreutils cpio cpp cracklib cvs cyrus-sasl db devs diffutils e2fsprogs file filesystem fillup findutils flex gawk gdbm-devel glibc glibc-devel glibc-locale gpm grep groff gzip info insserv less libacl libattr libgcc libselinux libstdc++ libxcrypt libzio m4 make man mktemp module-init-tools ncurses ncurses-devel net-tools netcfg openldap2-client openssl pam pam-modules patch permissions popt procinfo procps psmisc pwdutils rcs readline sed strace syslogd sysvinit tar tcpd texinfo timezone unzip util-linux vim zlib zlib-devel autoconf automake binutils gcc gdbm gettext kernel-source libtool openssl-devel perl readline-devel rpm + +Name: ipsec-tools +Version: 0.8.2 +Release: 0 +License: Other License(s), see package, BSD +Group: Productivity/Networking/Security +Provides: racoon +PreReq: %insserv_prereq %fillup_prereq +Autoreqprov: on +Summary: IPsec Utilities +Source: http://prdownloads.sourceforge.net/ipsec-tools/ipsec-tools-%{version}.tar.bz2 +Source1: racoon.init +Source2: sysconfig.racoon +URL: http://ipsec-tools.sourceforge.net/ +Prefix: /usr +BuildRoot: %{_tmppath}/%{name}-%{version}-build + +%description +This is the IPsec-Tools package. This package is needed to really make +use of the IPsec functionality in the version 2.5 and 2.6 Linux +kernels. This package builds: + +- libipsec, a PFKeyV2 library + +- setkey, a program to directly manipulate policies and SAs + +- racoon, an IKEv1 keying daemon + +These sources can be found at the IPsec-Tools home page at: +http://ipsec-tools.sourceforge.net/ + + + +Authors: +-------- + Derek Atkins + Michal Ludvig + +%prep +%setup + +%build +%{suse_update_config -f . src/racoon} +CFLAGS="$RPM_OPT_FLAGS" \ +./configure --prefix=/usr --disable-shared \ + --mandir=%{_mandir} --infodir=%{_infodir} --libdir=%{_libdir} \ + --libexecdir=%{_libdir} --sysconfdir=/etc/racoon \ + --sharedstatedir=/var/run --localstatedir=/var \ + --enable-dpd --enable-hybrid --enable-frag +make +make check + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/etc/init.d +install -m 0755 $RPM_SOURCE_DIR/racoon.init $RPM_BUILD_ROOT/etc/init.d/racoon +ln -sf /etc/init.d/racoon $RPM_BUILD_ROOT/usr/sbin/rcracoon +mkdir -p $RPM_BUILD_ROOT/var/adm/fillup-templates +install -m 644 $RPM_SOURCE_DIR/sysconfig.racoon $RPM_BUILD_ROOT/var/adm/fillup-templates/ +mkdir -p $RPM_BUILD_ROOT/usr/share/doc/packages/%{name}/ +cp -rv src/racoon/samples $RPM_BUILD_ROOT/usr/share/doc/packages/%{name}/ +cp -v src/setkey/sample* $RPM_BUILD_ROOT/usr/share/doc/packages/%{name}/ + +%post +%{fillup_and_insserv racoon} + +%postun +%{insserv_cleanup} + +%clean +if test ! -z "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/"; then + rm -rf $RPM_BUILD_ROOT +fi + +%files +%defattr(-,root,root) +%dir /etc/racoon +%config(noreplace) /etc/racoon/psk.txt +%config(noreplace) /etc/racoon/racoon.conf +%config(noreplace) /etc/racoon/setkey.conf +%config /etc/init.d/racoon +/usr/sbin/rcracoon +%dir /usr/include/libipsec/ +%doc /usr/share/doc/packages/%{name}/ +/var/adm/fillup-templates/sysconfig.racoon +/usr/include/libipsec/libpfkey.h +/usr/%{_lib}/libipsec.a +/usr/%{_lib}/libipsec.la +/usr/sbin/racoon +/usr/sbin/racoonctl +/usr/sbin/setkey +/usr/sbin/plainrsa-gen +%{_mandir}/man*/* + +%changelog -n ipsec-tools diff --git a/ipsec-tools/rpm/suse/ipsec-tools.spec.in b/ipsec-tools/rpm/suse/ipsec-tools.spec.in new file mode 100644 index 00000000..77ef6c83 --- /dev/null +++ b/ipsec-tools/rpm/suse/ipsec-tools.spec.in @@ -0,0 +1,110 @@ +# +# spec file for package ipsec-tools +# +# Copyright (c) 2005 SUSE LINUX AG, Nuernberg, Germany. +# This file and all modifications and additions to the pristine +# package are under the same license as the package itself. +# +# Please submit bugfixes or comments via http://www.suse.de/feedback/ +# + +# norootforbuild +# neededforbuild kernel-source openssl openssl-devel readline-devel + +BuildRequires: aaa_base acl attr bash bind-utils bison bzip2 coreutils cpio cpp cracklib cvs cyrus-sasl db devs diffutils e2fsprogs file filesystem fillup findutils flex gawk gdbm-devel glibc glibc-devel glibc-locale gpm grep groff gzip info insserv less libacl libattr libgcc libselinux libstdc++ libxcrypt libzio m4 make man mktemp module-init-tools ncurses ncurses-devel net-tools netcfg openldap2-client openssl pam pam-modules patch permissions popt procinfo procps psmisc pwdutils rcs readline sed strace syslogd sysvinit tar tcpd texinfo timezone unzip util-linux vim zlib zlib-devel autoconf automake binutils gcc gdbm gettext kernel-source libtool openssl-devel perl readline-devel rpm + +Name: ipsec-tools +Version: @VERSION@ +Release: 0 +License: Other License(s), see package, BSD +Group: Productivity/Networking/Security +Provides: racoon +PreReq: %insserv_prereq %fillup_prereq +Autoreqprov: on +Summary: IPsec Utilities +Source: http://prdownloads.sourceforge.net/ipsec-tools/ipsec-tools-%{version}.tar.bz2 +Source1: racoon.init +Source2: sysconfig.racoon +URL: http://ipsec-tools.sourceforge.net/ +Prefix: /usr +BuildRoot: %{_tmppath}/%{name}-%{version}-build + +%description +This is the IPsec-Tools package. This package is needed to really make +use of the IPsec functionality in the version 2.5 and 2.6 Linux +kernels. This package builds: + +- libipsec, a PFKeyV2 library + +- setkey, a program to directly manipulate policies and SAs + +- racoon, an IKEv1 keying daemon + +These sources can be found at the IPsec-Tools home page at: +http://ipsec-tools.sourceforge.net/ + + + +Authors: +-------- + Derek Atkins + Michal Ludvig + +%prep +%setup + +%build +%{suse_update_config -f . src/racoon} +CFLAGS="$RPM_OPT_FLAGS" \ +./configure --prefix=/usr --disable-shared \ + --mandir=%{_mandir} --infodir=%{_infodir} --libdir=%{_libdir} \ + --libexecdir=%{_libdir} --sysconfdir=/etc/racoon \ + --sharedstatedir=/var/run --localstatedir=/var \ + --enable-dpd --enable-hybrid --enable-frag +make +make check + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/etc/init.d +install -m 0755 $RPM_SOURCE_DIR/racoon.init $RPM_BUILD_ROOT/etc/init.d/racoon +ln -sf /etc/init.d/racoon $RPM_BUILD_ROOT/usr/sbin/rcracoon +mkdir -p $RPM_BUILD_ROOT/var/adm/fillup-templates +install -m 644 $RPM_SOURCE_DIR/sysconfig.racoon $RPM_BUILD_ROOT/var/adm/fillup-templates/ +mkdir -p $RPM_BUILD_ROOT/usr/share/doc/packages/%{name}/ +cp -rv src/racoon/samples $RPM_BUILD_ROOT/usr/share/doc/packages/%{name}/ +cp -v src/setkey/sample* $RPM_BUILD_ROOT/usr/share/doc/packages/%{name}/ + +%post +%{fillup_and_insserv racoon} + +%postun +%{insserv_cleanup} + +%clean +if test ! -z "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/"; then + rm -rf $RPM_BUILD_ROOT +fi + +%files +%defattr(-,root,root) +%dir /etc/racoon +%config(noreplace) /etc/racoon/psk.txt +%config(noreplace) /etc/racoon/racoon.conf +%config(noreplace) /etc/racoon/setkey.conf +%config /etc/init.d/racoon +/usr/sbin/rcracoon +%dir /usr/include/libipsec/ +%doc /usr/share/doc/packages/%{name}/ +/var/adm/fillup-templates/sysconfig.racoon +/usr/include/libipsec/libpfkey.h +/usr/%{_lib}/libipsec.a +/usr/%{_lib}/libipsec.la +/usr/sbin/racoon +/usr/sbin/racoonctl +/usr/sbin/setkey +/usr/sbin/plainrsa-gen +%{_mandir}/man*/* + +%changelog -n ipsec-tools diff --git a/ipsec-tools/rpm/suse/racoon.init b/ipsec-tools/rpm/suse/racoon.init new file mode 100644 index 00000000..15321ce8 --- /dev/null +++ b/ipsec-tools/rpm/suse/racoon.init @@ -0,0 +1,168 @@ +#! /bin/sh +# Copyright (c) 2001-2002 SuSE GmbH Nuernberg, Germany. +# +# Author: Michal Ludvig , 2004 +# +# /etc/init.d/ipsec-tools +# and its symbolic link +# /usr/sbin/rcipsec-tools +# +# System startup script for the IPsec key management daemon +# +### BEGIN INIT INFO +# Provides: racoon +# Required-Start: $remote_fs $named $syslog +# Required-Stop: $remote_fs $named $syslog +# Default-Start: 3 5 +# Default-Stop: 0 1 2 6 +# Description: IPsec key management daemon +### END INIT INFO + +SETKEY="IPsec policies" +SETKEY_BIN=/usr/sbin/setkey +SETKEY_CONF=/etc/racoon/setkey.conf + +RACOON="IPsec IKE daemon (racoon)" +RACOON_BIN=/usr/sbin/racoon +RACOON_CONF=/etc/racoon/racoon.conf +RACOON_PIDFILE=/var/run/racoon.pid + +test -x $SETKEY_BIN || exit 5 +test -x $RACOON_BIN || exit 5 + +test -f /etc/sysconfig/racoon && . /etc/sysconfig/racoon + +# Shell functions sourced from /etc/rc.status: +# rc_check check and set local and overall rc status +# rc_status check and set local and overall rc status +# rc_status -v ditto but be verbose in local rc status +# rc_status -v -r ditto and clear the local rc status +# rc_failed set local and overall rc status to failed +# rc_failed set local and overall rc status to +# rc_reset clear local rc status (overall remains) +# rc_exit exit appropriate to overall rc status +. /etc/rc.status + +# First reset status of this service +rc_reset + +# Return values acc. to LSB for all commands but status: +# 0 - success +# 1 - generic or unspecified error +# 2 - invalid or excess argument(s) +# 3 - unimplemented feature (e.g. "reload") +# 4 - insufficient privilege +# 5 - program is not installed +# 6 - program is not configured +# 7 - program is not running +# +# Note that starting an already running service, stopping +# or restarting a not-running service as well as the restart +# with force-reload (in case signalling is not supported) are +# considered a success. + +case "$1" in + start) + # Setting up SPD policies is not required. + if [ -f $SETKEY_CONF ]; then + echo -n "Setting up $SETKEY" + $SETKEY_BIN $SETKEY_OPTIONS -f $SETKEY_CONF + rc_status -v + rc_reset + fi + + echo -n "Starting $RACOON " + ## If there is no conf file, skip starting of ddtd + ## and return with "program not configured" + if ! [ -f $RACOON_CONF ]; then + echo -e -n "... no configuration file found" + rc_status -s + # service is not configured + rc_failed 6 + rc_exit + fi + + # startproc should return 0, even if service is + # already running to match LSB spec. + startproc $RACOON_BIN $RACOON_OPTIONS -f $RACOON_CONF + rc_status -v + ;; + + stop) + echo -n "Shutting down $RACOON" + ## Stop daemon with killproc(8) and if this fails + ## set echo the echo return value. + + killproc -p $RACOON_PIDFILE -TERM $RACOON_BIN + + # Remember status and be verbose + rc_status -v + rc_reset + + # Flush SPD policies if required + if [ -n "$SETKEY_FLUSH_OPTIONS" ]; then + echo -n "Flushing $SETKEY" + $SETKEY_BIN $SETKEY_FLUSH_OPTIONS + rc_status -v + fi + ;; + try-restart) + ## Stop the service and if this succeeds (i.e. the + ## service was running before), start it again. + $0 stop && $0 start + + # Remember status and be quiet + rc_status + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + $0 start + + # Remember status and be quiet + rc_status + ;; + force-reload) + ## Signal the daemon to reload its config. Most daemons + ## do this on signal 1 (SIGHUP). + ## If it does not support it, restart. + + echo -n "Reload service $RACOON" + killproc -p $RACOON_PIDFILE -HUP $RACOON_BIN + rc_status -v + ;; + reload) + ## Like force-reload, but if daemon does not support + ## signalling, do nothing (!) + + echo -n "Reload service $RACOON" + killproc -p $RACOON_PIDFILE -HUP $RACOON_BIN + rc_status -v + ;; + status) + echo -n "Checking for $RACOON: " + ## Check status with checkproc(8), if process is running + ## checkproc will return with exit status 0. + + # Status has a slightly different for the status command: + # 0 - service running + # 1 - service dead, but /var/run/ pid file exists + # 2 - service dead, but /var/lock/ lock file exists + # 3 - service not running + + checkproc -p $RACOON_PIDFILE $RACOON_BIN + rc_status -v + ;; + probe) + ## Optional: Probe for the necessity of a reload, + ## give out the argument which is required for a reload. + + test "$RACOON_CONF" -nt "$RACOON_PIDFILE" && echo reload + ;; + *) + echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}" + exit 1 + ;; +esac +rc_exit diff --git a/ipsec-tools/rpm/suse/sysconfig.racoon b/ipsec-tools/rpm/suse/sysconfig.racoon new file mode 100644 index 00000000..48d9fc75 --- /dev/null +++ b/ipsec-tools/rpm/suse/sysconfig.racoon @@ -0,0 +1,24 @@ +## Path: Network/IPsec +## Description: IPsec keying daemon (IKE) +## Type: string +## Default: "-v" +# +# Start-up flags for the racoon dameon. +# +RACOON_OPTIONS="-v" + +## Path: Network/IPsec +## Description: Tool for manipulation IPsec SPD and SA databases +## Type: string +## Default: "" +# +# Additional flags uset when inserting SPD rules. +# +SETKEY_OPTIONS="" + +## Type: string +## Default: "-FP" +# +# Flags to flush SPD on racoon exit. +# +SETKEY_FLUSH_OPTIONS="-FP" diff --git a/ipsec-tools/src/Makefile.am b/ipsec-tools/src/Makefile.am new file mode 100644 index 00000000..6d0d7802 --- /dev/null +++ b/ipsec-tools/src/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = @INCLUDE_GLIBC@ libipsec setkey racoon + +DIST_SUBDIRS = include-glibc libipsec setkey racoon diff --git a/ipsec-tools/src/Makefile.in b/ipsec-tools/src/Makefile.in new file mode 100644 index 00000000..4b235826 --- /dev/null +++ b/ipsec-tools/src/Makefile.in @@ -0,0 +1,619 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acracoon.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGURE_AMFLAGS = @CONFIGURE_AMFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTOBJS = @CRYPTOBJS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_CRYPTO = @EXTRA_CRYPTO@ +FGREP = @FGREP@ +FRAG_OBJS = @FRAG_OBJS@ +GLIBC_BUGS = @GLIBC_BUGS@ +GREP = @GREP@ +HYBRID_OBJS = @HYBRID_OBJS@ +INCLUDE_GLIBC = @INCLUDE_GLIBC@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_OPTS = @INSTALL_OPTS@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KERNEL_INCLUDE = @KERNEL_INCLUDE@ +KRB5_CONFIG = @KRB5_CONFIG@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NATT_OBJS = @NATT_OBJS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RPM = @RPM@ +SECCTX_OBJS = @SECCTX_OBJS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +include_racoondir = @include_racoondir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = @INCLUDE_GLIBC@ libipsec setkey racoon +DIST_SUBDIRS = include-glibc libipsec setkey racoon +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ipsec-tools/src/include-glibc/Makefile.am b/ipsec-tools/src/include-glibc/Makefile.am new file mode 100644 index 00000000..77ac48a6 --- /dev/null +++ b/ipsec-tools/src/include-glibc/Makefile.am @@ -0,0 +1,14 @@ + +.includes: ${top_builddir}/config.status + ln -snf $(KERNEL_INCLUDE)/linux + touch .includes + +all: .includes + +EXTRA_DIST = \ + glibc-bugs.h \ + net/pfkeyv2.h \ + netinet/ipsec.h \ + sys/queue.h + +DISTCLEANFILES = .includes linux diff --git a/ipsec-tools/src/include-glibc/Makefile.in b/ipsec-tools/src/include-glibc/Makefile.in new file mode 100644 index 00000000..c3cdd6c9 --- /dev/null +++ b/ipsec-tools/src/include-glibc/Makefile.in @@ -0,0 +1,452 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/include-glibc +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acracoon.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGURE_AMFLAGS = @CONFIGURE_AMFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTOBJS = @CRYPTOBJS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_CRYPTO = @EXTRA_CRYPTO@ +FGREP = @FGREP@ +FRAG_OBJS = @FRAG_OBJS@ +GLIBC_BUGS = @GLIBC_BUGS@ +GREP = @GREP@ +HYBRID_OBJS = @HYBRID_OBJS@ +INCLUDE_GLIBC = @INCLUDE_GLIBC@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_OPTS = @INSTALL_OPTS@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KERNEL_INCLUDE = @KERNEL_INCLUDE@ +KRB5_CONFIG = @KRB5_CONFIG@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NATT_OBJS = @NATT_OBJS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RPM = @RPM@ +SECCTX_OBJS = @SECCTX_OBJS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +include_racoondir = @include_racoondir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = \ + glibc-bugs.h \ + net/pfkeyv2.h \ + netinet/ipsec.h \ + sys/queue.h + +DISTCLEANFILES = .includes linux +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/include-glibc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/include-glibc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + + +.includes: ${top_builddir}/config.status + ln -snf $(KERNEL_INCLUDE)/linux + touch .includes + +all: .includes + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ipsec-tools/src/include-glibc/glibc-bugs.h b/ipsec-tools/src/include-glibc/glibc-bugs.h new file mode 100644 index 00000000..a992d2fb --- /dev/null +++ b/ipsec-tools/src/include-glibc/glibc-bugs.h @@ -0,0 +1,12 @@ +/* $NetBSD: glibc-bugs.h,v 1.4 2006/09/09 16:22:08 manu Exp $ */ + +#ifndef __GLIBC_BUGS_H__ +#define __GLIBC_BUGS_H__ 1 + +#define _XOPEN_SOURCE 500 +#define _BSD_SOURCE + +#include +#include + +#endif diff --git a/ipsec-tools/src/include-glibc/net/pfkeyv2.h b/ipsec-tools/src/include-glibc/net/pfkeyv2.h new file mode 100644 index 00000000..47812d82 --- /dev/null +++ b/ipsec-tools/src/include-glibc/net/pfkeyv2.h @@ -0,0 +1,75 @@ +/* $NetBSD: pfkeyv2.h,v 1.4.40.1 2013/05/23 05:44:28 tteras Exp $ */ + +#ifndef __NET_PFKEYV2_H_ +#define __NET_PFKEYV2_H_ 1 + +#include +#include + +/* Private allocations for authentication algorithms */ +#define SADB_AALG_SHA2_256 SADB_X_AALG_SHA2_256HMAC +#define SADB_X_AALG_SHA2_256 SADB_X_AALG_SHA2_256HMAC +#define SADB_AALG_SHA2_384 SADB_X_AALG_SHA2_384HMAC +#define SADB_X_AALG_SHA2_384 SADB_X_AALG_SHA2_384HMAC +#define SADB_AALG_SHA2_512 SADB_X_AALG_SHA2_512HMAC +#define SADB_X_AALG_SHA2_512 SADB_X_AALG_SHA2_512HMAC +#define SADB_AALG_RIPEMD160HMAC SADB_X_AALG_RIPEMD160HMAC +#define SADB_X_AALG_MD5 249 +#define SADB_X_AALG_SHA 250 + +/* private allocations - based on RFC2407/IANA assignment */ +#ifdef SADB_X_EALG_CASTCBC +#define SADB_X_EALG_CAST128CBC SADB_X_EALG_CASTCBC +#else +#define SADB_X_EALG_CAST128CBC 5 +#endif +#define SADB_X_EALG_RIJNDAELCBC SADB_X_EALG_AESCBC +#define SADB_X_EALG_AES SADB_X_EALG_AESCBC + + +#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_MAX 4 + + +#define SADB_X_EXT_NONE 0x0000 /* i.e. new format. */ +#define SADB_X_EXT_OLD 0x0001 /* old format. */ + +#define SADB_X_EXT_IV4B 0x0010 /* IV length of 4 bytes in use */ +#define SADB_X_EXT_DERIV 0x0020 /* DES derived */ +#define SADB_X_EXT_CYCSEQ 0x0040 /* allowing to cyclic sequence. */ + + /* three of followings are exclusive flags each them */ +#define SADB_X_EXT_PSEQ 0x0000 /* sequencial padding for ESP */ +#define SADB_X_EXT_PRAND 0x0100 /* random padding for ESP */ +#define SADB_X_EXT_PZERO 0x0200 /* zero padding for ESP */ +#define SADB_X_EXT_PMASK 0x0300 /* mask for padding flag */ + +#define SADB_X_EXT_RAWCPI 0x0080 /* use well known CPI (IPComp) */ + + +#define PFKEY_SOFT_LIFETIME_RATE 80 + +#define SADB_X_LIFETIME_ALLOCATIONS 0 +#define SADB_X_LIFETIME_BYTES 1 +#define SADB_X_LIFETIME_ADDTIME 2 +#define SADB_X_LIFETIME_USETIME 3 + + +#define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) +#define PFKEY_EXTLEN(msg) \ + PFKEY_UNUNIT64(((struct sadb_ext *)(msg))->sadb_ext_len) +#define PFKEY_ADDR_PREFIX(ext) \ + (((struct sadb_address *)(ext))->sadb_address_prefixlen) +#define PFKEY_ADDR_PROTO(ext) \ + (((struct sadb_address *)(ext))->sadb_address_proto) +#define PFKEY_ADDR_SADDR(ext) \ + ((struct sockaddr *)((caddr_t)(ext) + sizeof(struct sadb_address))) + +/* in 64bits */ +#define PFKEY_UNUNIT64(a) ((a) << 3) +#define PFKEY_UNIT64(a) ((a) >> 3) + +#endif diff --git a/ipsec-tools/src/include-glibc/netinet/ipsec.h b/ipsec-tools/src/include-glibc/netinet/ipsec.h new file mode 100644 index 00000000..cbaf6125 --- /dev/null +++ b/ipsec-tools/src/include-glibc/netinet/ipsec.h @@ -0,0 +1,4 @@ +/* $NetBSD: ipsec.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +#include +#include diff --git a/ipsec-tools/src/include-glibc/sys/queue.h b/ipsec-tools/src/include-glibc/sys/queue.h new file mode 100644 index 00000000..4a5ec75c --- /dev/null +++ b/ipsec-tools/src/include-glibc/sys/queue.h @@ -0,0 +1,454 @@ +/* $NetBSD: queue.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + * $FreeBSD: src/sys/sys/queue.h,v 1.58 2004/04/07 04:19:49 imp Exp $ + * + * 04/24/2004 Backport to v1.45 functionality for ipsec-tools + * Heiko Hund + */ + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +//#include + +/* + * This file defines four types of data structures: singly-linked lists, + * singly-linked tail queues, lists and tail queues. + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A singly-linked tail queue is headed by a pair of pointers, one to the + * head of the list and the other to the tail of the list. The elements are + * singly linked for minimum space and pointer manipulation overhead at the + * expense of O(n) removal for arbitrary elements. New elements can be added + * to the list after an existing element, at the head of the list, or at the + * end of the list. Elements being removed from the head of the tail queue + * should use the explicit macro for this purpose for optimum efficiency. + * A singly-linked tail queue may only be traversed in the forward direction. + * Singly-linked tail queues are ideal for applications with large datasets + * and few or no removals or for implementing a FIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * For details on the use of these macros, see the queue(3) manual page. + * + * + * SLIST LIST STAILQ TAILQ + * _HEAD + + + + + * _HEAD_INITIALIZER + + + + + * _ENTRY + + + + + * _INIT + + + + + * _EMPTY + + + + + * _FIRST + + + + + * _NEXT + + + + + * _PREV - - - + + * _LAST - - + + + * _FOREACH + + + + + * _FOREACH_REVERSE - - - + + * _INSERT_HEAD + + + + + * _INSERT_BEFORE - + - + + * _INSERT_AFTER + + + + + * _INSERT_TAIL - - + + + * _REMOVE_HEAD + - + - + * _REMOVE + + + + + * + */ + +/* + * Singly-linked List declarations. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) + +#define SLIST_FIRST(head) ((head)->slh_first) + +#define SLIST_FOREACH(var, head, field) \ + for ((var) = SLIST_FIRST((head)); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_INIT(head) do { \ + SLIST_FIRST((head)) = NULL; \ +} while (0) + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ + SLIST_NEXT((slistelm), field) = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ + SLIST_FIRST((head)) = (elm); \ +} while (0) + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if (SLIST_FIRST((head)) == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = SLIST_FIRST((head)); \ + while (SLIST_NEXT(curelm, field) != (elm)) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_NEXT(curelm, field) = \ + SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ + } \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ +} while (0) + +/* + * Singly-linked Tail queue declarations. + */ +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first;/* first element */ \ + struct type **stqh_last;/* addr of last next element */ \ +} + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) + +#define STAILQ_FIRST(head) ((head)->stqh_first) + +#define STAILQ_FOREACH(var, head, field) \ + for((var) = STAILQ_FIRST((head)); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) + +#define STAILQ_INIT(head) do { \ + STAILQ_FIRST((head)) = NULL; \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_NEXT((tqelm), field) = (elm); \ +} while (0) + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_FIRST((head)) = (elm); \ +} while (0) + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + STAILQ_NEXT((elm), field) = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) + +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY(head) ? \ + NULL : \ + ((struct type *) \ + ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) + +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if (STAILQ_FIRST((head)) == (elm)) { \ + STAILQ_REMOVE_HEAD(head, field); \ + } \ + else { \ + struct type *curelm = STAILQ_FIRST((head)); \ + while (STAILQ_NEXT(curelm, field) != (elm)) \ + curelm = STAILQ_NEXT(curelm, field); \ + if ((STAILQ_NEXT(curelm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ + } \ +} while (0) + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if ((STAILQ_FIRST((head)) = \ + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ + if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +/* + * List declarations. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for ((var) = LIST_FIRST((head)); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_INIT(head) do { \ + LIST_FIRST((head)) = NULL; \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ + LIST_NEXT((listelm), field)->field.le_prev = \ + &LIST_NEXT((elm), field); \ + LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + LIST_NEXT((elm), field) = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ + LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &LIST_FIRST((head)); \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL) \ + LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ +} while (0) + +/* + * Tail queue declarations. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * Tail queue functions. + */ +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_FOREACH(var, head, field) \ + for ((var) = TAILQ_FIRST((head)); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_INIT(head) do { \ + TAILQ_FIRST((head)) = NULL; \ + (head)->tqh_last = &TAILQ_FIRST((head)); \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + TAILQ_NEXT((listelm), field) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + TAILQ_NEXT((elm), field) = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ + TAILQ_FIRST((head))->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + TAILQ_FIRST((head)) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + TAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ +} while (0) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field)) != NULL) \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ +} while (0) + + +#ifdef _KERNEL + +/* + * XXX insque() and remque() are an old way of handling certain queues. + * They bogusly assumes that all queue heads look alike. + */ + +struct quehead { + struct quehead *qh_link; + struct quehead *qh_rlink; +}; + +#ifdef __GNUC__ + +static __inline void +insque(void *a, void *b) +{ + struct quehead *element = (struct quehead *)a, + *head = (struct quehead *)b; + + element->qh_link = head->qh_link; + element->qh_rlink = head; + head->qh_link = element; + element->qh_link->qh_rlink = element; +} + +static __inline void +remque(void *a) +{ + struct quehead *element = (struct quehead *)a; + + element->qh_link->qh_rlink = element->qh_rlink; + element->qh_rlink->qh_link = element->qh_link; + element->qh_rlink = 0; +} + +#else /* !__GNUC__ */ + +void insque __P((void *a, void *b)); +void remque __P((void *a)); + +#endif /* __GNUC__ */ + +#endif /* _KERNEL */ + +#endif /* !_SYS_QUEUE_H_ */ diff --git a/ipsec-tools/src/libipsec/Makefile.am b/ipsec-tools/src/libipsec/Makefile.am new file mode 100644 index 00000000..6a4e3b3e --- /dev/null +++ b/ipsec-tools/src/libipsec/Makefile.am @@ -0,0 +1,39 @@ + +#bin_PROGRAMS = test-policy test-policy-priority +lib_LTLIBRARIES = libipsec.la + +libipsecdir = $(includedir)/libipsec +libipsec_HEADERS = libpfkey.h + +man3_MANS = ipsec_set_policy.3 ipsec_strerror.3 + +AM_CFLAGS = @GLIBC_BUGS@ +AM_YFLAGS = -d -p __libipsec +AM_LFLAGS = -P__libipsec -olex.yy.c + +BUILT_SOURCES = policy_parse.h + +libipsec_la_SOURCES = \ + ipsec_dump_policy.c \ + ipsec_get_policylen.c \ + ipsec_strerror.c \ + key_debug.c \ + pfkey.c \ + pfkey_dump.c \ + policy_parse.y \ + policy_token.l + +# version is current:revision:age. +# See: http://www.gnu.org/manual/libtool-1.4.2/html_chapter/libtool_6.html#SEC32 +libipsec_la_LDFLAGS = -version-info 0:1:0 +libipsec_la_LIBADD = $(LEXLIB) + +noinst_HEADERS = ipsec_strerror.h + +#test_policy_SOURCES = test-policy.c +#test_policy_LDFLAGS = libipsec.la + +#test_policy_priority_SOURCES = test-policy-priority.c +#test_policy_priority_LDFLAGS = libipsec.la + +EXTRA_DIST = ${man3_MANS} test-policy.c diff --git a/ipsec-tools/src/libipsec/Makefile.in b/ipsec-tools/src/libipsec/Makefile.in new file mode 100644 index 00000000..936b26a6 --- /dev/null +++ b/ipsec-tools/src/libipsec/Makefile.in @@ -0,0 +1,794 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libipsec +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + policy_parse.h policy_parse.c policy_token.c \ + $(top_srcdir)/depcomp $(top_srcdir)/ylwrap $(libipsec_HEADERS) \ + $(noinst_HEADERS) +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acracoon.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" \ + "$(DESTDIR)$(libipsecdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libipsec_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libipsec_la_OBJECTS = ipsec_dump_policy.lo ipsec_get_policylen.lo \ + ipsec_strerror.lo key_debug.lo pfkey.lo pfkey_dump.lo \ + policy_parse.lo policy_token.lo +libipsec_la_OBJECTS = $(am_libipsec_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libipsec_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libipsec_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) +LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) +AM_V_LEX = $(am__v_LEX_@AM_V@) +am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) +am__v_LEX_0 = @echo " LEX " $@; +am__v_LEX_1 = +YLWRAP = $(top_srcdir)/ylwrap +am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ + -e s/c++$$/h++/ -e s/c$$/h/ +YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) +LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) +AM_V_YACC = $(am__v_YACC_@AM_V@) +am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) +am__v_YACC_0 = @echo " YACC " $@; +am__v_YACC_1 = +SOURCES = $(libipsec_la_SOURCES) +DIST_SOURCES = $(libipsec_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +man3dir = $(mandir)/man3 +NROFF = nroff +MANS = $(man3_MANS) +HEADERS = $(libipsec_HEADERS) $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGURE_AMFLAGS = @CONFIGURE_AMFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTOBJS = @CRYPTOBJS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_CRYPTO = @EXTRA_CRYPTO@ +FGREP = @FGREP@ +FRAG_OBJS = @FRAG_OBJS@ +GLIBC_BUGS = @GLIBC_BUGS@ +GREP = @GREP@ +HYBRID_OBJS = @HYBRID_OBJS@ +INCLUDE_GLIBC = @INCLUDE_GLIBC@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_OPTS = @INSTALL_OPTS@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KERNEL_INCLUDE = @KERNEL_INCLUDE@ +KRB5_CONFIG = @KRB5_CONFIG@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NATT_OBJS = @NATT_OBJS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RPM = @RPM@ +SECCTX_OBJS = @SECCTX_OBJS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +include_racoondir = @include_racoondir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +#bin_PROGRAMS = test-policy test-policy-priority +lib_LTLIBRARIES = libipsec.la +libipsecdir = $(includedir)/libipsec +libipsec_HEADERS = libpfkey.h +man3_MANS = ipsec_set_policy.3 ipsec_strerror.3 +AM_CFLAGS = @GLIBC_BUGS@ +AM_YFLAGS = -d -p __libipsec +AM_LFLAGS = -P__libipsec -olex.yy.c +BUILT_SOURCES = policy_parse.h +libipsec_la_SOURCES = \ + ipsec_dump_policy.c \ + ipsec_get_policylen.c \ + ipsec_strerror.c \ + key_debug.c \ + pfkey.c \ + pfkey_dump.c \ + policy_parse.y \ + policy_token.l + + +# version is current:revision:age. +# See: http://www.gnu.org/manual/libtool-1.4.2/html_chapter/libtool_6.html#SEC32 +libipsec_la_LDFLAGS = -version-info 0:1:0 +libipsec_la_LIBADD = $(LEXLIB) +noinst_HEADERS = ipsec_strerror.h + +#test_policy_SOURCES = test-policy.c +#test_policy_LDFLAGS = libipsec.la + +#test_policy_priority_SOURCES = test-policy-priority.c +#test_policy_priority_LDFLAGS = libipsec.la +EXTRA_DIST = ${man3_MANS} test-policy.c +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .l .lo .o .obj .y +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/libipsec/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/libipsec/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +policy_parse.h: policy_parse.c + @if test ! -f $@; then rm -f policy_parse.c; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) policy_parse.c; else :; fi + +libipsec.la: $(libipsec_la_OBJECTS) $(libipsec_la_DEPENDENCIES) $(EXTRA_libipsec_la_DEPENDENCIES) + $(AM_V_CCLD)$(libipsec_la_LINK) -rpath $(libdir) $(libipsec_la_OBJECTS) $(libipsec_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipsec_dump_policy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipsec_get_policylen.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipsec_strerror.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/key_debug.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pfkey.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pfkey_dump.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/policy_parse.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/policy_token.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +.l.c: + $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) + +.y.c: + $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man3: $(man3_MANS) + @$(NORMAL_INSTALL) + @list1='$(man3_MANS)'; \ + list2=''; \ + test -n "$(man3dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.3[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ + done; } + +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list='$(man3_MANS)'; test -n "$(man3dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) +install-libipsecHEADERS: $(libipsec_HEADERS) + @$(NORMAL_INSTALL) + @list='$(libipsec_HEADERS)'; test -n "$(libipsecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libipsecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libipsecdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libipsecdir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(libipsecdir)" || exit $$?; \ + done + +uninstall-libipsecHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(libipsec_HEADERS)'; test -n "$(libipsecdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libipsecdir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) $(MANS) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(libipsecdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -rm -f policy_parse.c + -rm -f policy_parse.h + -rm -f policy_token.c + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-libipsecHEADERS install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man3 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES uninstall-libipsecHEADERS \ + uninstall-man + +uninstall-man: uninstall-man3 + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-libipsecHEADERS \ + install-man install-man3 install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-libLTLIBRARIES \ + uninstall-libipsecHEADERS uninstall-man uninstall-man3 + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ipsec-tools/src/libipsec/ipsec_dump_policy.c b/ipsec-tools/src/libipsec/ipsec_dump_policy.c new file mode 100644 index 00000000..4d0eb773 --- /dev/null +++ b/ipsec-tools/src/libipsec/ipsec_dump_policy.c @@ -0,0 +1,421 @@ +/* $NetBSD: ipsec_dump_policy.c,v 1.9 2010/12/03 15:01:11 tteras Exp $ */ + +/* Id: ipsec_dump_policy.c,v 1.10 2005/06/29 09:12:37 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include PATH_IPSEC_H + +#include + +#include +#include +#include +#include + +#include "ipsec_strerror.h" +#include "libpfkey.h" + +static const char *ipsp_dir_strs[] = { + "any", "in", "out", "fwd", +#ifdef __linux__ + "in(socket)", "out(socket)" +#endif +}; + +static const char *ipsp_policy_strs[] = { + "discard", "none", "ipsec", "entrust", "bypass", +}; + +static char *ipsec_dump_ipsecrequest __P((char *, size_t, + struct sadb_x_ipsecrequest *, size_t, int)); +static char *ipsec_dump_policy1 __P((void *, const char *, int)); +static int set_addresses __P((char *, size_t, struct sockaddr *, + struct sockaddr *, int)); +static char *set_address __P((char *, size_t, struct sockaddr *, int)); + +/* + * policy is sadb_x_policy buffer. + * Must call free() later. + * When delimiter == NULL, alternatively ' '(space) is applied. + */ +char * +ipsec_dump_policy(policy, delimiter) + ipsec_policy_t policy; + __ipsec_const char *delimiter; +{ + return ipsec_dump_policy1(policy, delimiter, 0); +} + +char * +ipsec_dump_policy_withports(policy, delimiter) + void *policy; + const char *delimiter; +{ + return ipsec_dump_policy1(policy, delimiter, 1); +} + +static char * +ipsec_dump_policy1(policy, delimiter, withports) + void *policy; + const char *delimiter; + int withports; +{ + struct sadb_x_policy *xpl = policy; + struct sadb_x_ipsecrequest *xisr; + size_t off, buflen; + char *buf; + char isrbuf[1024]; + char *newbuf; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + int32_t priority_offset; + char *priority_str; + char operator; +#endif + + /* sanity check */ + if (policy == NULL) + return NULL; + if (xpl->sadb_x_policy_exttype != SADB_X_EXT_POLICY) { + __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; + return NULL; + } + + /* set delimiter */ + if (delimiter == NULL) + delimiter = " "; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + if (xpl->sadb_x_policy_priority == 0) + { + priority_offset = 0; + priority_str = ""; + } + /* find which constant the priority is closest to */ + else if (xpl->sadb_x_policy_priority < + (u_int32_t) (PRIORITY_DEFAULT / 4) * 3) + { + priority_offset = xpl->sadb_x_policy_priority - PRIORITY_HIGH; + priority_str = "prio high"; + } + else if (xpl->sadb_x_policy_priority >= + (u_int32_t) (PRIORITY_DEFAULT / 4) * 3 && + xpl->sadb_x_policy_priority < + (u_int32_t) (PRIORITY_DEFAULT / 4) * 5) + { + priority_offset = xpl->sadb_x_policy_priority - PRIORITY_DEFAULT; + priority_str = "prio def"; + } + else + { + priority_offset = xpl->sadb_x_policy_priority - PRIORITY_LOW; + priority_str = "prio low"; + } + + /* fix sign to match the way it is input */ + priority_offset *= -1; + if (priority_offset < 0) + { + operator = '-'; + priority_offset *= -1; + } + else + { + operator = '+'; + } +#endif + + switch (xpl->sadb_x_policy_dir) { + case IPSEC_DIR_ANY: + case IPSEC_DIR_INBOUND: + case IPSEC_DIR_OUTBOUND: +#ifdef HAVE_POLICY_FWD + case IPSEC_DIR_FWD: + case IPSEC_DIR_FWD + 1: + case IPSEC_DIR_FWD + 2: +#endif + break; + default: + __ipsec_errcode = EIPSEC_INVAL_DIR; + return NULL; + } + + switch (xpl->sadb_x_policy_type) { + case IPSEC_POLICY_DISCARD: + case IPSEC_POLICY_NONE: + case IPSEC_POLICY_IPSEC: + case IPSEC_POLICY_BYPASS: + case IPSEC_POLICY_ENTRUST: + break; + default: + __ipsec_errcode = EIPSEC_INVAL_POLICY; + return NULL; + } + + buflen = strlen(ipsp_dir_strs[xpl->sadb_x_policy_dir]) + + 1 /* space */ +#ifdef HAVE_PFKEY_POLICY_PRIORITY + + strlen(priority_str) + + ((priority_offset != 0) ? 13 : 0) /* [space operator space int] */ + + ((strlen(priority_str) != 0) ? 1 : 0) /* space */ +#endif + + strlen(ipsp_policy_strs[xpl->sadb_x_policy_type]) + + 1; /* NUL */ + + if ((buf = malloc(buflen)) == NULL) { + __ipsec_errcode = EIPSEC_NO_BUFS; + return NULL; + } +#ifdef HAVE_PFKEY_POLICY_PRIORITY + if (priority_offset != 0) + { + snprintf(buf, buflen, "%s %s %c %u %s", + ipsp_dir_strs[xpl->sadb_x_policy_dir], priority_str, operator, + priority_offset, ipsp_policy_strs[xpl->sadb_x_policy_type]); + } + else if (strlen (priority_str) != 0) + { + snprintf(buf, buflen, "%s %s %s", + ipsp_dir_strs[xpl->sadb_x_policy_dir], priority_str, + ipsp_policy_strs[xpl->sadb_x_policy_type]); + } + else + { + snprintf(buf, buflen, "%s %s", + ipsp_dir_strs[xpl->sadb_x_policy_dir], + ipsp_policy_strs[xpl->sadb_x_policy_type]); + } +#else + snprintf(buf, buflen, "%s %s", ipsp_dir_strs[xpl->sadb_x_policy_dir], + ipsp_policy_strs[xpl->sadb_x_policy_type]); +#endif + + if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) { + __ipsec_errcode = EIPSEC_NO_ERROR; + return buf; + } + + /* count length of buffer for use */ + off = sizeof(*xpl); + while (off < PFKEY_EXTLEN(xpl)) { + xisr = (void *)((caddr_t)(void *)xpl + off); + off += xisr->sadb_x_ipsecrequest_len; + } + + /* validity check */ + if (off != PFKEY_EXTLEN(xpl)) { + __ipsec_errcode = EIPSEC_INVAL_SADBMSG; + free(buf); + return NULL; + } + + off = sizeof(*xpl); + while (off < PFKEY_EXTLEN(xpl)) { + int offset; + xisr = (void *)((caddr_t)(void *)xpl + off); + + if (ipsec_dump_ipsecrequest(isrbuf, sizeof(isrbuf), xisr, + PFKEY_EXTLEN(xpl) - off, withports) == NULL) { + free(buf); + return NULL; + } + + offset = strlen(buf); + buflen = offset + strlen(delimiter) + strlen(isrbuf) + 1; + newbuf = (char *)realloc(buf, buflen); + if (newbuf == NULL) { + __ipsec_errcode = EIPSEC_NO_BUFS; + free(buf); + return NULL; + } + buf = newbuf; + snprintf(buf+offset, buflen-offset, "%s%s", delimiter, isrbuf); + + off += xisr->sadb_x_ipsecrequest_len; + } + + __ipsec_errcode = EIPSEC_NO_ERROR; + return buf; +} + +static char * +ipsec_dump_ipsecrequest(buf, len, xisr, bound, withports) + char *buf; + size_t len; + struct sadb_x_ipsecrequest *xisr; + size_t bound; /* boundary */ + int withports; +{ + const char *proto, *mode, *level; + char abuf[NI_MAXHOST * 2 + 2]; + + if (xisr->sadb_x_ipsecrequest_len > bound) { + __ipsec_errcode = EIPSEC_INVAL_PROTO; + return NULL; + } + + switch (xisr->sadb_x_ipsecrequest_proto) { + case IPPROTO_ESP: + proto = "esp"; + break; + case IPPROTO_AH: + proto = "ah"; + break; + case IPPROTO_IPCOMP: + proto = "ipcomp"; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_PROTO; + return NULL; + } + + switch (xisr->sadb_x_ipsecrequest_mode) { + case IPSEC_MODE_ANY: + mode = "any"; + break; + case IPSEC_MODE_TRANSPORT: + mode = "transport"; + break; + case IPSEC_MODE_TUNNEL: + mode = "tunnel"; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_MODE; + return NULL; + } + + abuf[0] = '\0'; + if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) { + struct sockaddr *sa1, *sa2; + caddr_t p; + + p = (void *)(xisr + 1); + sa1 = (void *)p; + sa2 = (void *)(p + sysdep_sa_len(sa1)); + if (sizeof(*xisr) + sysdep_sa_len(sa1) + sysdep_sa_len(sa2) != + xisr->sadb_x_ipsecrequest_len) { + __ipsec_errcode = EIPSEC_INVAL_ADDRESS; + return NULL; + } + if (set_addresses(abuf, sizeof(abuf), + sa1, sa2, withports) != 0) { + __ipsec_errcode = EIPSEC_INVAL_ADDRESS; + return NULL; + } + } + + switch (xisr->sadb_x_ipsecrequest_level) { + case IPSEC_LEVEL_DEFAULT: + level = "default"; + break; + case IPSEC_LEVEL_USE: + level = "use"; + break; + case IPSEC_LEVEL_REQUIRE: + level = "require"; + break; + case IPSEC_LEVEL_UNIQUE: + level = "unique"; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_LEVEL; + return NULL; + } + + if (xisr->sadb_x_ipsecrequest_reqid == 0) + snprintf(buf, len, "%s/%s/%s/%s", proto, mode, abuf, level); + else { + int ch; + + if (xisr->sadb_x_ipsecrequest_reqid > IPSEC_MANUAL_REQID_MAX) + ch = '#'; + else + ch = ':'; + snprintf(buf, len, "%s/%s/%s/%s%c%u", proto, mode, abuf, level, + ch, xisr->sadb_x_ipsecrequest_reqid); + } + + return buf; +} + +static int +set_addresses(buf, len, sa1, sa2, withports) + char *buf; + size_t len; + struct sockaddr *sa1; + struct sockaddr *sa2; + int withports; +{ + char tmp1[NI_MAXHOST], tmp2[NI_MAXHOST]; + + if (set_address(tmp1, sizeof(tmp1), sa1, withports) == NULL || + set_address(tmp2, sizeof(tmp2), sa2, withports) == NULL) + return -1; + if (strlen(tmp1) + 1 + strlen(tmp2) + 1 > len) + return -1; + snprintf(buf, len, "%s-%s", tmp1, tmp2); + return 0; +} + +static char * +set_address(buf, len, sa, withports) + char *buf; + size_t len; + struct sockaddr *sa; + int withports; +{ + const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; + char host[NI_MAXHOST]; + char serv[NI_MAXSERV]; + + if (len < 1) + return NULL; + buf[0] = '\0'; + if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), host, sizeof(host), + serv, sizeof(serv), niflags) != 0) + return NULL; + + if (withports) + snprintf(buf, len, "%s[%s]", host, serv); + else + snprintf(buf, len, "%s", host); + + return buf; +} diff --git a/ipsec-tools/src/libipsec/ipsec_get_policylen.c b/ipsec-tools/src/libipsec/ipsec_get_policylen.c new file mode 100644 index 00000000..5a497780 --- /dev/null +++ b/ipsec-tools/src/libipsec/ipsec_get_policylen.c @@ -0,0 +1,54 @@ +/* $NetBSD: ipsec_get_policylen.c,v 1.7 2007/07/18 12:07:50 vanhu Exp $ */ + +/* $KAME: ipsec_get_policylen.c,v 1.5 2000/05/07 05:25:03 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include PATH_IPSEC_H + +#include + +#include "libpfkey.h" +#include "ipsec_strerror.h" + +int +ipsec_get_policylen(policy) + ipsec_policy_t policy; +{ + return policy ? PFKEY_EXTLEN(policy) : -1; +} diff --git a/ipsec-tools/src/libipsec/ipsec_set_policy.3 b/ipsec-tools/src/libipsec/ipsec_set_policy.3 new file mode 100644 index 00000000..f3832b53 --- /dev/null +++ b/ipsec-tools/src/libipsec/ipsec_set_policy.3 @@ -0,0 +1,310 @@ +.\" $NetBSD: ipsec_set_policy.3,v 1.15 2010/03/05 06:47:58 tteras Exp $ +.\" +.\" $KAME: ipsec_set_policy.3,v 1.16 2003/01/06 21:59:03 sumikawa Exp $ +.\" +.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the project nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd May 5, 1998 +.Dt IPSEC_SET_POLICY 3 +.Os +.Sh NAME +.Nm ipsec_set_policy , +.Nm ipsec_get_policylen , +.Nm ipsec_dump_policy +.Nd manipulate IPsec policy specification structure from human-readable policy string +.\" +.Sh LIBRARY +.Lb libipsec +.Sh SYNOPSIS +.In netinet6/ipsec.h +.Ft "char *" +.Fn ipsec_set_policy "char *policy" "int len" +.Ft int +.Fn ipsec_get_policylen "char *buf" +.Ft "char *" +.Fn ipsec_dump_policy "char *buf" "char *delim" +.Sh DESCRIPTION +.Fn ipsec_set_policy +generates an IPsec policy specification structure, namely +.Li struct sadb_x_policy +and/or +.Li struct sadb_x_ipsecrequest +from a human-readable policy specification. +The policy specification must be given as a C string +.Fa policy +and its length +.Fa len . +.Fn ipsec_set_policy +will return a buffer with the corresponding IPsec policy specification structure. +The buffer is dynamically allocated, and must be +.Xr free 3 Ap d +by the caller. +.Pp +You can get the length of the generated buffer with +.Fn ipsec_get_policylen +(i.e. for calling +.Xr setsockopt 2 ) . +.Pp +.Fn ipsec_dump_policy +converts an IPsec policy structure into human-readable form. +Therefore, +.Fn ipsec_dump_policy +can be regarded as the inverse function to +.Fn ipsec_set_policy . +.Fa buf +points to an IPsec policy structure, +.Li struct sadb_x_policy . +.Fa delim +is a delimiter string, which is usually a blank character. +If you set +.Fa delim +to +.Dv NULL , +a single whitespace is assumed. +.Fn ipsec_dump_policy +returns a pointer to a dynamically allocated string. +It is the caller's responsibility to +.Xr free 3 +it. +.Pp +.Fa policy +is formatted as either of the following: +.Bl -tag -width "discard" +.It Ar direction [priority specification] Li discard +.Ar direction +must be +.Li in , +.Li out , +or +.Li fwd . +.Ar direction +specifies in which direction the policy needs to be applied. +The non-standard direction +.Li fwd +is substituted with +.Li in +on platforms which do not support forward policies. +.Pp +.Ar priority specification +is used to control the placement of the policy within the SPD. +The policy position is determined by +a signed integer where higher priorities indicate the policy is placed +closer to the beginning of the list and lower priorities indicate the +policy is placed closer to the end of the list. +Policies with equal +priorities are added at the end of the group of such policies. +.Pp +Priority can only +be specified when libipsec has been compiled against kernel headers that +support policy priorities (Linux \*[Gt]= 2.6.6). +It takes one of the following formats: +.Bl -tag -width "discard" +.It Ar {priority,prio} offset +.Ar offset +is an integer in the range \-2147483647..214783648. +.It Ar {priority,prio} base {+,-} offset +.Ar base +is either +.Li low (-1073741824) , +.Li def (0) , +or +.Li high (1073741824) . +.Pp +.Ar offset +is an unsigned integer. +It can be up to 1073741824 for +positive offsets, and up to 1073741823 for negative offsets. +.El +.Pp +The interpretation of policy priority in these functions and the +kernel DOES differ. +The relationship between the two can be described as +p(kernel) = 0x80000000 - p(func) +.Pp +With +.Li discard +policy, packets will be dropped if they match the policy. +.It Ar direction [priority specification] Li entrust +.Li entrust +means to consult the SPD defined by +.Xr setkey 8 . +.It Ar direction [priority specification] Li bypass +.Li bypass +means to bypass the IPsec processing. +.Pq the packet will be transmitted in clear . +This is for privileged sockets. +.It Ar direction Bo Ar priority specification Bc Li ipsec Ar request ... +.Li ipsec +means that the matching packets are subject to IPsec processing. +.Li ipsec +can be followed by one or more +.Ar request +strings, which are formatted as below: +.Bl -tag -width "discard" +.It Ar protocol Li / Ar mode Li / Ar src Li - Ar dst Op Ar /level +.Ar protocol +is either +.Li ah , +.Li esp , +or +.Li ipcomp . +.Pp +.Ar mode +is either +.Li transport +or +.Li tunnel . +.Pp +.Ar src +and +.Ar dst +specifies the IPsec endpoint. +.Ar src +always means the +.Dq sending node +and +.Ar dst +always means the +.Dq receiving node . +Therefore, when +.Ar direction +is +.Li in , +.Ar dst +is this node +and +.Ar src +is the other node +.Pq peer . +If +.Ar mode +is +.Li transport , +Both +.Ar src +and +.Ar dst +can be omitted. +.Pp +.Ar level +must be set to one of the following: +.Li default , use , require , +or +.Li unique . +.Li default +means that the kernel should consult the system default policy +defined by +.Xr sysctl 8 , +such as +.Li net.inet.ipsec.esp_trans_deflev . +See +.Xr ipsec 4 +regarding the system default. +.Li use +means that a relevant SA can be used when available, +since the kernel may perform IPsec operation against packets when possible. +In this case, packets can be transmitted in clear +.Pq when SA is not available , +or encrypted +.Pq when SA is available . +.Li require +means that a relevant SA is required, +since the kernel must perform IPsec operation against packets. +.Li unique +is the same as +.Li require , +but adds the restriction that the SA for outbound traffic is used +only for this policy. +You may need the identifier in order to relate the policy and the SA +when you define the SA by manual keying. +You can put the decimal number as the identifier after +.Li unique +like +.Li unique : number . +.Li number +must be between 1 and 32767 . +If the +.Ar request +string is kept unambiguous, +.Ar level +and slash prior to +.Ar level +can be omitted. +However, it is encouraged to specify them explicitly +to avoid unintended behavior. +If +.Ar level +is omitted, it will be interpreted as +.Li default . +.El +.Pp +Note that there are slight differences to the specification of +.Xr setkey 8 . +In the specification of +.Xr setkey 8 , +both +.Li entrust +and +.Li bypass +are not used. +Refer to +.Xr setkey 8 +for details. +.Pp +Here are several examples +.Pq long lines are wrapped for readability : +.Bd -literal -offset indent +in discard +out ipsec esp/transport//require +in ipsec ah/transport//require +out ipsec esp/tunnel/10.1.1.2-10.1.1.1/use +in ipsec ipcomp/transport//use + esp/transport//use +.Ed +.El +.Sh RETURN VALUES +.Fn ipsec_set_policy +returns a pointer to the allocated buffer with the policy specification +if successful; otherwise a +.Dv NULL +pointer is returned. +.Fn ipsec_get_policylen +returns a positive value +.Pq meaning the buffer size +on success, and a negative value on errors. +.Fn ipsec_dump_policy +returns a pointer to a dynamically allocated region on success, +and +.Dv NULL +on errors. +.Sh SEE ALSO +.Xr ipsec_strerror 3 , +.Xr ipsec 4 , +.Xr setkey 8 +.Sh HISTORY +The functions first appeared in the WIDE/KAME IPv6 protocol stack kit. diff --git a/ipsec-tools/src/libipsec/ipsec_strerror.3 b/ipsec-tools/src/libipsec/ipsec_strerror.3 new file mode 100644 index 00000000..c2e86cd7 --- /dev/null +++ b/ipsec-tools/src/libipsec/ipsec_strerror.3 @@ -0,0 +1,88 @@ +.\" $NetBSD: ipsec_strerror.3,v 1.10 2006/09/09 16:22:09 manu Exp $ +.\" +.\" $KAME: ipsec_strerror.3,v 1.9 2001/08/17 07:21:36 itojun Exp $ +.\" +.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the project nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd May 6, 1998 +.Dt IPSEC_STRERROR 3 +.Os +.\" +.Sh NAME +.Nm ipsec_strerror +.Nd error messages for the IPsec policy manipulation library +.\" +.Sh LIBRARY +.Lb libipsec +.Sh SYNOPSIS +.In netinet6/ipsec.h +.Ft "const char *" +.Fn ipsec_strerror void +.\" +.Sh DESCRIPTION +.Pa netinet6/ipsec.h +declares +.Pp +.Dl extern int ipsec_errcode ; +.Pp +which is used to pass an error code from the IPsec policy manipulation +library to a program. +.Fn ipsec_strerror +can be used to obtain the error message string for the error code. +.Pp +The array pointed to is not to be modified by the calling program. +Since +.Fn ipsec_strerror +uses +.Xr strerror 3 +as underlying function, calling +.Xr strerror 3 +after +.Fn ipsec_strerror +will make the return value from +.Fn ipsec_strerror +invalid or overwritten. +.\" +.Sh RETURN VALUES +.Fn ipsec_strerror +always returns a pointer to a C string. +The C string must not be overwritten by the calling program. +.\" +.Sh SEE ALSO +.Xr ipsec_set_policy 3 +.\" +.Sh HISTORY +.Fn ipsec_strerror +first appeared in the WIDE/KAME IPv6 protocol stack kit. +.\" +.Sh BUGS +.Fn ipsec_strerror +will return its result which may be overwritten by subsequent calls. +.Pp +.Va ipsec_errcode +is not thread safe. diff --git a/ipsec-tools/src/libipsec/ipsec_strerror.c b/ipsec-tools/src/libipsec/ipsec_strerror.c new file mode 100644 index 00000000..ca26d0e8 --- /dev/null +++ b/ipsec-tools/src/libipsec/ipsec_strerror.c @@ -0,0 +1,96 @@ +/* $NetBSD: ipsec_strerror.c,v 1.6 2010/04/07 14:53:52 vanhu Exp $ */ + +/* $KAME: ipsec_strerror.c,v 1.7 2000/07/30 00:45:12 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include +#include PATH_IPSEC_H + +#include "ipsec_strerror.h" + +int __ipsec_errcode; + +static const char *ipsec_errlist[] = { +"Success", /*EIPSEC_NO_ERROR*/ +"Not supported", /*EIPSEC_NOT_SUPPORTED*/ +"Invalid argument", /*EIPSEC_INVAL_ARGUMENT*/ +"Invalid sadb message", /*EIPSEC_INVAL_SADBMSG*/ +"Invalid version", /*EIPSEC_INVAL_VERSION*/ +"Invalid security policy", /*EIPSEC_INVAL_POLICY*/ +"Invalid address specification", /*EIPSEC_INVAL_ADDRESS*/ +"Invalid ipsec protocol", /*EIPSEC_INVAL_PROTO*/ +"Invalid ipsec mode", /*EIPSEC_INVAL_MODE*/ +"Invalid ipsec level", /*EIPSEC_INVAL_LEVEL*/ +"Invalid SA type", /*EIPSEC_INVAL_SATYPE*/ +"Invalid message type", /*EIPSEC_INVAL_MSGTYPE*/ +"Invalid extension type", /*EIPSEC_INVAL_EXTTYPE*/ +"Invalid algorithm type", /*EIPSEC_INVAL_ALGS*/ +"Invalid key length", /*EIPSEC_INVAL_KEYLEN*/ +"Invalid address family", /*EIPSEC_INVAL_FAMILY*/ +"Invalid prefix length", /*EIPSEC_INVAL_PREFIXLEN*/ +"Invalid direction", /*EIPSEC_INVAL_DIR*/ +"SPI range violation", /*EIPSEC_INVAL_SPI*/ +"No protocol specified", /*EIPSEC_NO_PROTO*/ +"No algorithm specified", /*EIPSEC_NO_ALGS*/ +"No buffers available", /*EIPSEC_NO_BUFS*/ +"Must get supported algorithms list first", /*EIPSEC_DO_GET_SUPP_LIST*/ +"Protocol mismatch", /*EIPSEC_PROTO_MISMATCH*/ +"Family mismatch", /*EIPSEC_FAMILY_MISMATCH*/ +"Too few arguments", /*EIPSEC_FEW_ARGUMENTS*/ +NULL, /*EIPSEC_SYSTEM_ERROR*/ +"Priority offset not in valid range [-2147483647, 2147483648]", /*EIPSEC_INVAL_PRIORITY_OFFSET*/ +"Priority offset from base not in valid range [0, 1073741823] for negative offsets and [0, 1073741824] for positive offsets", /* EIPSEC_INVAL_PRIORITY_OFFSET */ +"Policy priority not compiled in", /*EIPSEC_PRIORITY_NOT_COMPILED*/ +"Unknown error", /*EIPSEC_MAX*/ +}; + +const char *ipsec_strerror(void) +{ + if (__ipsec_errcode < 0 || __ipsec_errcode > EIPSEC_MAX) + __ipsec_errcode = EIPSEC_MAX; + + return ipsec_errlist[__ipsec_errcode]; +} + +void __ipsec_set_strerror(const char *str) +{ + __ipsec_errcode = EIPSEC_SYSTEM_ERROR; + ipsec_errlist[EIPSEC_SYSTEM_ERROR] = str; + + return; +} diff --git a/ipsec-tools/src/libipsec/ipsec_strerror.h b/ipsec-tools/src/libipsec/ipsec_strerror.h new file mode 100644 index 00000000..2b4264f7 --- /dev/null +++ b/ipsec-tools/src/libipsec/ipsec_strerror.h @@ -0,0 +1,73 @@ +/* $NetBSD: ipsec_strerror.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: ipsec_strerror.h,v 1.4 2004/06/07 09:18:46 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _IPSEC_STRERROR_H +#define _IPSEC_STRERROR_H + +extern int __ipsec_errcode; +extern void __ipsec_set_strerror __P((const char *)); + +#define EIPSEC_NO_ERROR 0 /*success*/ +#define EIPSEC_NOT_SUPPORTED 1 /*not supported*/ +#define EIPSEC_INVAL_ARGUMENT 2 /*invalid argument*/ +#define EIPSEC_INVAL_SADBMSG 3 /*invalid sadb message*/ +#define EIPSEC_INVAL_VERSION 4 /*invalid version*/ +#define EIPSEC_INVAL_POLICY 5 /*invalid security policy*/ +#define EIPSEC_INVAL_ADDRESS 6 /*invalid address specification*/ +#define EIPSEC_INVAL_PROTO 7 /*invalid ipsec protocol*/ +#define EIPSEC_INVAL_MODE 8 /*Invalid ipsec mode*/ +#define EIPSEC_INVAL_LEVEL 9 /*invalid ipsec level*/ +#define EIPSEC_INVAL_SATYPE 10 /*invalid SA type*/ +#define EIPSEC_INVAL_MSGTYPE 11 /*invalid message type*/ +#define EIPSEC_INVAL_EXTTYPE 12 /*invalid extension type*/ +#define EIPSEC_INVAL_ALGS 13 /*Invalid algorithm type*/ +#define EIPSEC_INVAL_KEYLEN 14 /*invalid key length*/ +#define EIPSEC_INVAL_FAMILY 15 /*invalid address family*/ +#define EIPSEC_INVAL_PREFIXLEN 16 /*SPI range violation*/ +#define EIPSEC_INVAL_DIR 17 /*Invalid direciton*/ +#define EIPSEC_INVAL_SPI 18 /*invalid prefixlen*/ +#define EIPSEC_NO_PROTO 19 /*no protocol specified*/ +#define EIPSEC_NO_ALGS 20 /*No algorithm specified*/ +#define EIPSEC_NO_BUFS 21 /*no buffers available*/ +#define EIPSEC_DO_GET_SUPP_LIST 22 /*must get supported algorithm first*/ +#define EIPSEC_PROTO_MISMATCH 23 /*protocol mismatch*/ +#define EIPSEC_FAMILY_MISMATCH 24 /*family mismatch*/ +#define EIPSEC_FEW_ARGUMENTS 25 /*Too few arguments*/ +#define EIPSEC_SYSTEM_ERROR 26 /*system error*/ +#define EIPSEC_INVAL_PRIORITY_OFFSET 27 /*priority offset out of range*/ +#define EIPSEC_INVAL_PRIORITY_BASE_OFFSET 28 /* priority base offset too + large */ +#define EIPSEC_PRIORITY_NOT_COMPILED 29 /*no priority support in libipsec*/ +#define EIPSEC_MAX 30 /*unknown error*/ + +#endif /* _IPSEC_STRERROR_H */ diff --git a/ipsec-tools/src/libipsec/key_debug.c b/ipsec-tools/src/libipsec/key_debug.c new file mode 100644 index 00000000..e381a984 --- /dev/null +++ b/ipsec-tools/src/libipsec/key_debug.c @@ -0,0 +1,899 @@ +/* $NetBSD: key_debug.c,v 1.9 2008/12/05 06:02:20 tteras Exp $ */ + +/* $KAME: key_debug.c,v 1.29 2001/08/16 14:25:41 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef _KERNEL +#if defined(__FreeBSD__) && __FreeBSD__ >= 3 +#include "opt_inet.h" +#include "opt_inet6.h" +#include "opt_ipsec.h" +#endif +#ifdef __NetBSD__ +#include "opt_inet.h" +#endif +#endif + +#if HAVE_STDINT_H +#include +#endif + +#include +#include +#ifdef _KERNEL +#include +#include +#include +#endif +#include + +#include +#include PATH_IPSEC_H + +#ifndef _KERNEL +#include +#include +#include +#endif /* !_KERNEL */ + +#include "config.h" +#include "libpfkey.h" + +static void kdebug_sadb_prop __P((struct sadb_ext *)); +static void kdebug_sadb_identity __P((struct sadb_ext *)); +static void kdebug_sadb_supported __P((struct sadb_ext *)); +static void kdebug_sadb_lifetime __P((struct sadb_ext *)); +static void kdebug_sadb_sa __P((struct sadb_ext *)); +static void kdebug_sadb_address __P((struct sadb_ext *)); +static void kdebug_sadb_key __P((struct sadb_ext *)); +static void kdebug_sadb_x_sa2 __P((struct sadb_ext *)); +static void kdebug_sadb_x_policy __P((struct sadb_ext *ext)); +static void kdebug_sockaddr __P((struct sockaddr *addr)); + +#ifdef SADB_X_EXT_NAT_T_TYPE +static void kdebug_sadb_x_nat_t_type __P((struct sadb_ext *ext)); +static void kdebug_sadb_x_nat_t_port __P((struct sadb_ext *ext)); +#endif + +#ifdef SADB_X_EXT_PACKET +static void kdebug_sadb_x_packet __P((struct sadb_ext *)); +#endif + +#ifdef SADB_X_EXT_KMADDRESS +static void kdebug_sadb_x_kmaddress __P((struct sadb_ext *)); +#endif + +#ifdef _KERNEL +static void kdebug_secreplay __P((struct secreplay *)); +#endif + +#ifndef _KERNEL +#define panic(param) { printf(param); exit(1); } +#endif + +#include "libpfkey.h" +/* NOTE: host byte order */ + +/* %%%: about struct sadb_msg */ +void +kdebug_sadb(base) + struct sadb_msg *base; +{ + struct sadb_ext *ext; + int tlen, extlen; + + /* sanity check */ + if (base == NULL) + panic("kdebug_sadb: NULL pointer was passed.\n"); + + printf("sadb_msg{ version=%u type=%u errno=%u satype=%u\n", + base->sadb_msg_version, base->sadb_msg_type, + base->sadb_msg_errno, base->sadb_msg_satype); + printf(" len=%u reserved=%u seq=%u pid=%u\n", + base->sadb_msg_len, base->sadb_msg_reserved, + base->sadb_msg_seq, base->sadb_msg_pid); + + tlen = PFKEY_UNUNIT64(base->sadb_msg_len) - sizeof(struct sadb_msg); + ext = (void *)((caddr_t)(void *)base + sizeof(struct sadb_msg)); + + while (tlen > 0) { + printf("sadb_ext{ len=%u type=%u }\n", + ext->sadb_ext_len, ext->sadb_ext_type); + + if (ext->sadb_ext_len == 0) { + printf("kdebug_sadb: invalid ext_len=0 was passed.\n"); + return; + } + if (ext->sadb_ext_len > tlen) { + printf("kdebug_sadb: ext_len exceeds end of buffer.\n"); + return; + } + + switch (ext->sadb_ext_type) { + case SADB_EXT_SA: + kdebug_sadb_sa(ext); + break; + case SADB_EXT_LIFETIME_CURRENT: + case SADB_EXT_LIFETIME_HARD: + case SADB_EXT_LIFETIME_SOFT: + kdebug_sadb_lifetime(ext); + break; + case SADB_EXT_ADDRESS_SRC: + case SADB_EXT_ADDRESS_DST: + case SADB_EXT_ADDRESS_PROXY: + kdebug_sadb_address(ext); + break; + case SADB_EXT_KEY_AUTH: + case SADB_EXT_KEY_ENCRYPT: + kdebug_sadb_key(ext); + break; + case SADB_EXT_IDENTITY_SRC: + case SADB_EXT_IDENTITY_DST: + kdebug_sadb_identity(ext); + break; + case SADB_EXT_SENSITIVITY: + break; + case SADB_EXT_PROPOSAL: + kdebug_sadb_prop(ext); + break; + case SADB_EXT_SUPPORTED_AUTH: + case SADB_EXT_SUPPORTED_ENCRYPT: + kdebug_sadb_supported(ext); + break; + case SADB_EXT_SPIRANGE: + case SADB_X_EXT_KMPRIVATE: + break; + case SADB_X_EXT_POLICY: + kdebug_sadb_x_policy(ext); + break; + case SADB_X_EXT_SA2: + kdebug_sadb_x_sa2(ext); + break; +#ifdef SADB_X_EXT_NAT_T_TYPE + case SADB_X_EXT_NAT_T_TYPE: + kdebug_sadb_x_nat_t_type(ext); + break; + case SADB_X_EXT_NAT_T_SPORT: + case SADB_X_EXT_NAT_T_DPORT: + kdebug_sadb_x_nat_t_port(ext); + break; + case SADB_X_EXT_NAT_T_OA: + kdebug_sadb_address(ext); + break; +#endif +#ifdef SADB_X_EXT_PACKET + case SADB_X_EXT_PACKET: + kdebug_sadb_x_packet(ext); + break; +#endif +#ifdef SADB_X_EXT_KMADDRESS + case SADB_X_EXT_KMADDRESS: + kdebug_sadb_x_kmaddress(ext); + break; +#endif + default: + printf("kdebug_sadb: invalid ext_type %u was passed.\n", + ext->sadb_ext_type); + return; + } + + extlen = PFKEY_UNUNIT64(ext->sadb_ext_len); + tlen -= extlen; + ext = (void *)((caddr_t)(void *)ext + extlen); + } + + return; +} + +static void +kdebug_sadb_prop(ext) + struct sadb_ext *ext; +{ + struct sadb_prop *prop = (void *)ext; + struct sadb_comb *comb; + int len; + + /* sanity check */ + if (ext == NULL) + panic("kdebug_sadb_prop: NULL pointer was passed.\n"); + + len = (PFKEY_UNUNIT64(prop->sadb_prop_len) - sizeof(*prop)) + / sizeof(*comb); + comb = (void *)(prop + 1); + printf("sadb_prop{ replay=%u\n", prop->sadb_prop_replay); + + while (len--) { + printf("sadb_comb{ auth=%u encrypt=%u " + "flags=0x%04x reserved=0x%08x\n", + comb->sadb_comb_auth, comb->sadb_comb_encrypt, + comb->sadb_comb_flags, comb->sadb_comb_reserved); + + printf(" auth_minbits=%u auth_maxbits=%u " + "encrypt_minbits=%u encrypt_maxbits=%u\n", + comb->sadb_comb_auth_minbits, + comb->sadb_comb_auth_maxbits, + comb->sadb_comb_encrypt_minbits, + comb->sadb_comb_encrypt_maxbits); + + printf(" soft_alloc=%u hard_alloc=%u " + "soft_bytes=%lu hard_bytes=%lu\n", + comb->sadb_comb_soft_allocations, + comb->sadb_comb_hard_allocations, + (unsigned long)comb->sadb_comb_soft_bytes, + (unsigned long)comb->sadb_comb_hard_bytes); + + printf(" soft_alloc=%lu hard_alloc=%lu " + "soft_bytes=%lu hard_bytes=%lu }\n", + (unsigned long)comb->sadb_comb_soft_addtime, + (unsigned long)comb->sadb_comb_hard_addtime, + (unsigned long)comb->sadb_comb_soft_usetime, + (unsigned long)comb->sadb_comb_hard_usetime); + comb++; + } + printf("}\n"); + + return; +} + +static void +kdebug_sadb_identity(ext) + struct sadb_ext *ext; +{ + struct sadb_ident *id = (void *)ext; + int len; + + /* sanity check */ + if (ext == NULL) + panic("kdebug_sadb_identity: NULL pointer was passed.\n"); + + len = PFKEY_UNUNIT64(id->sadb_ident_len) - sizeof(*id); + printf("sadb_ident_%s{", + id->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC ? "src" : "dst"); + switch (id->sadb_ident_type) { + default: + printf(" type=%d id=%lu", + id->sadb_ident_type, (u_long)id->sadb_ident_id); + if (len) { +#ifdef _KERNEL + ipsec_hexdump((caddr_t)(id + 1), len); /*XXX cast ?*/ +#else + char *p, *ep; + printf("\n str=\""); + p = (void *)(id + 1); + ep = p + len; + for (/*nothing*/; *p && p < ep; p++) { + if (isprint((int)*p)) + printf("%c", *p & 0xff); + else + printf("\\%03o", *p & 0xff); + } +#endif + printf("\""); + } + break; + } + + printf(" }\n"); + + return; +} + +static void +kdebug_sadb_supported(ext) + struct sadb_ext *ext; +{ + struct sadb_supported *sup = (void *)ext; + struct sadb_alg *alg; + int len; + + /* sanity check */ + if (ext == NULL) + panic("kdebug_sadb_supported: NULL pointer was passed.\n"); + + len = (PFKEY_UNUNIT64(sup->sadb_supported_len) - sizeof(*sup)) + / sizeof(*alg); + alg = (void *)(sup + 1); + printf("sadb_sup{\n"); + while (len--) { + printf(" { id=%d ivlen=%d min=%d max=%d }\n", + alg->sadb_alg_id, alg->sadb_alg_ivlen, + alg->sadb_alg_minbits, alg->sadb_alg_maxbits); + alg++; + } + printf("}\n"); + + return; +} + +static void +kdebug_sadb_lifetime(ext) + struct sadb_ext *ext; +{ + struct sadb_lifetime *lft = (void *)ext; + + /* sanity check */ + if (ext == NULL) + printf("kdebug_sadb_lifetime: NULL pointer was passed.\n"); + + printf("sadb_lifetime{ alloc=%u, bytes=%u\n", + lft->sadb_lifetime_allocations, + (u_int32_t)lft->sadb_lifetime_bytes); + printf(" addtime=%u, usetime=%u }\n", + (u_int32_t)lft->sadb_lifetime_addtime, + (u_int32_t)lft->sadb_lifetime_usetime); + + return; +} + +static void +kdebug_sadb_sa(ext) + struct sadb_ext *ext; +{ + struct sadb_sa *sa = (void *)ext; + + /* sanity check */ + if (ext == NULL) + panic("kdebug_sadb_sa: NULL pointer was passed.\n"); + + printf("sadb_sa{ spi=%u replay=%u state=%u\n", + (u_int32_t)ntohl(sa->sadb_sa_spi), sa->sadb_sa_replay, + sa->sadb_sa_state); + printf(" auth=%u encrypt=%u flags=0x%08x }\n", + sa->sadb_sa_auth, sa->sadb_sa_encrypt, sa->sadb_sa_flags); + + return; +} + +static void +kdebug_sadb_address(ext) + struct sadb_ext *ext; +{ + struct sadb_address *addr = (void *)ext; + + /* sanity check */ + if (ext == NULL) + panic("kdebug_sadb_address: NULL pointer was passed.\n"); + + printf("sadb_address{ proto=%u prefixlen=%u reserved=0x%02x%02x }\n", + addr->sadb_address_proto, addr->sadb_address_prefixlen, + ((u_char *)(void *)&addr->sadb_address_reserved)[0], + ((u_char *)(void *)&addr->sadb_address_reserved)[1]); + + kdebug_sockaddr((void *)((caddr_t)(void *)ext + sizeof(*addr))); + + return; +} + +static void +kdebug_sadb_key(ext) + struct sadb_ext *ext; +{ + struct sadb_key *key = (void *)ext; + + /* sanity check */ + if (ext == NULL) + panic("kdebug_sadb_key: NULL pointer was passed.\n"); + + printf("sadb_key{ bits=%u reserved=%u\n", + key->sadb_key_bits, key->sadb_key_reserved); + printf(" key="); + + /* sanity check 2 */ + if (((uint32_t)key->sadb_key_bits >> 3) > + (PFKEY_UNUNIT64(key->sadb_key_len) - sizeof(struct sadb_key))) { + printf("kdebug_sadb_key: key length mismatch, bit:%d len:%ld.\n", + (uint32_t)key->sadb_key_bits >> 3, + (long)PFKEY_UNUNIT64(key->sadb_key_len) - sizeof(struct sadb_key)); + } + + ipsec_hexdump(key + sizeof(struct sadb_key), + (int)((uint32_t)key->sadb_key_bits >> 3)); + printf(" }\n"); + return; +} + +static void +kdebug_sadb_x_sa2(ext) + struct sadb_ext *ext; +{ + struct sadb_x_sa2 *sa2 = (void *)ext; + + /* sanity check */ + if (ext == NULL) + panic("kdebug_sadb_x_sa2: NULL pointer was passed.\n"); + + printf("sadb_x_sa2{ mode=%u reqid=%u\n", + sa2->sadb_x_sa2_mode, sa2->sadb_x_sa2_reqid); + printf(" reserved1=%u reserved2=%u sequence=%u }\n", + sa2->sadb_x_sa2_reserved1, sa2->sadb_x_sa2_reserved2, + sa2->sadb_x_sa2_sequence); + + return; +} + +void +kdebug_sadb_x_policy(ext) + struct sadb_ext *ext; +{ + struct sadb_x_policy *xpl = (void *)ext; + struct sockaddr *addr; + + /* sanity check */ + if (ext == NULL) + panic("kdebug_sadb_x_policy: NULL pointer was passed.\n"); + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + printf("sadb_x_policy{ type=%u dir=%u id=%x priority=%u }\n", +#else + printf("sadb_x_policy{ type=%u dir=%u id=%x }\n", +#endif + xpl->sadb_x_policy_type, xpl->sadb_x_policy_dir, +#ifdef HAVE_PFKEY_POLICY_PRIORITY + xpl->sadb_x_policy_id, xpl->sadb_x_policy_priority); +#else + xpl->sadb_x_policy_id); +#endif + + if (xpl->sadb_x_policy_type == IPSEC_POLICY_IPSEC) { + int tlen; + struct sadb_x_ipsecrequest *xisr; + + tlen = PFKEY_UNUNIT64(xpl->sadb_x_policy_len) - sizeof(*xpl); + xisr = (void *)(xpl + 1); + + while (tlen > 0) { + printf(" { len=%u proto=%u mode=%u level=%u reqid=%u\n", + xisr->sadb_x_ipsecrequest_len, + xisr->sadb_x_ipsecrequest_proto, + xisr->sadb_x_ipsecrequest_mode, + xisr->sadb_x_ipsecrequest_level, + xisr->sadb_x_ipsecrequest_reqid); + + if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) { + addr = (void *)(xisr + 1); + kdebug_sockaddr(addr); + addr = (void *)((caddr_t)(void *)addr + + sysdep_sa_len(addr)); + kdebug_sockaddr(addr); + } + + printf(" }\n"); + + /* prevent infinite loop */ + if (xisr->sadb_x_ipsecrequest_len == 0) { + printf("kdebug_sadb_x_policy: wrong policy struct.\n"); + return; + } + /* prevent overflow */ + if (xisr->sadb_x_ipsecrequest_len > tlen) { + printf("invalid ipsec policy length\n"); + return; + } + + tlen -= xisr->sadb_x_ipsecrequest_len; + + xisr = (void *)((caddr_t)(void *)xisr + + xisr->sadb_x_ipsecrequest_len); + } + + if (tlen != 0) + panic("kdebug_sadb_x_policy: wrong policy struct.\n"); + } + + return; +} + +#ifdef SADB_X_EXT_NAT_T_TYPE +static void +kdebug_sadb_x_nat_t_type(struct sadb_ext *ext) +{ + struct sadb_x_nat_t_type *ntt = (void *)ext; + + /* sanity check */ + if (ext == NULL) + panic("kdebug_sadb_x_nat_t_type: NULL pointer was passed.\n"); + + printf("sadb_x_nat_t_type{ type=%u }\n", ntt->sadb_x_nat_t_type_type); + + return; +} + +static void +kdebug_sadb_x_nat_t_port(struct sadb_ext *ext) +{ + struct sadb_x_nat_t_port *ntp = (void *)ext; + + /* sanity check */ + if (ext == NULL) + panic("kdebug_sadb_x_nat_t_port: NULL pointer was passed.\n"); + + printf("sadb_x_nat_t_port{ port=%u }\n", ntohs(ntp->sadb_x_nat_t_port_port)); + + return; +} +#endif + +#ifdef SADB_X_EXT_PACKET +static void +kdebug_sadb_x_packet(ext) + struct sadb_ext *ext; +{ + struct sadb_x_packet *pkt = (struct sadb_x_packet *)ext; + + /* sanity check */ + if (ext == NULL) + panic("kdebug_sadb_x_packet: NULL pointer was passed.\n"); + + printf("sadb_x_packet{ copylen=%u\n", pkt->sadb_x_packet_copylen); + printf(" packet="); + ipsec_hexdump((caddr_t)pkt + sizeof(struct sadb_x_packet), + pkt->sadb_x_packet_copylen); + printf(" }\n"); + return; +} +#endif + +#ifdef SADB_X_EXT_KMADDRESS +static void +kdebug_sadb_x_kmaddress(ext) + struct sadb_ext *ext; +{ + struct sadb_x_kmaddress *kma = (struct sadb_x_kmaddress *)ext; + struct sockaddr * sa; + sa_family_t family; + int len, sa_len; + + /* sanity check */ + if (ext == NULL) + panic("kdebug_sadb_x_kmaddress: NULL pointer was passed.\n"); + + len = (PFKEY_UNUNIT64(kma->sadb_x_kmaddress_len) - sizeof(*kma)); + + printf("sadb_x_kmaddress{ reserved=0x%02x%02x%02x%02x }\n", + ((u_char *)(void *)&kma->sadb_x_kmaddress_reserved)[0], + ((u_char *)(void *)&kma->sadb_x_kmaddress_reserved)[1], + ((u_char *)(void *)&kma->sadb_x_kmaddress_reserved)[2], + ((u_char *)(void *)&kma->sadb_x_kmaddress_reserved)[3]); + + sa = (struct sockaddr *)(kma + 1); + if (len < sizeof(struct sockaddr) || (sa_len = sysdep_sa_len(sa)) > len) + panic("kdebug_sadb_x_kmaddress: not enough data to read" + " first sockaddr.\n"); + kdebug_sockaddr((void *)sa); /* local address */ + family = sa->sa_family; + + len -= sa_len; + sa = (struct sockaddr *)((char *)sa + sa_len); + if (len < sizeof(struct sockaddr) || sysdep_sa_len(sa) > len) + panic("kdebug_sadb_x_kmaddress: not enough data to read" + " second sockaddr.\n"); + kdebug_sockaddr((void *)sa); /* remote address */ + + if (family != sa->sa_family) + printf("kdebug_sadb_x_kmaddress: !!!! Please, note the " + "unexpected mismatch in address family.\n"); +} +#endif + + +#ifdef _KERNEL +/* %%%: about SPD and SAD */ +void +kdebug_secpolicy(sp) + struct secpolicy *sp; +{ + /* sanity check */ + if (sp == NULL) + panic("kdebug_secpolicy: NULL pointer was passed.\n"); + + printf("secpolicy{ refcnt=%u state=%u policy=%u\n", + sp->refcnt, sp->state, sp->policy); + + kdebug_secpolicyindex(&sp->spidx); + + switch (sp->policy) { + case IPSEC_POLICY_DISCARD: + printf(" type=discard }\n"); + break; + case IPSEC_POLICY_NONE: + printf(" type=none }\n"); + break; + case IPSEC_POLICY_IPSEC: + { + struct ipsecrequest *isr; + for (isr = sp->req; isr != NULL; isr = isr->next) { + + printf(" level=%u\n", isr->level); + kdebug_secasindex(&isr->saidx); + + if (isr->sav != NULL) + kdebug_secasv(isr->sav); + } + printf(" }\n"); + } + break; + case IPSEC_POLICY_BYPASS: + printf(" type=bypass }\n"); + break; + case IPSEC_POLICY_ENTRUST: + printf(" type=entrust }\n"); + break; + default: + printf("kdebug_secpolicy: Invalid policy found. %d\n", + sp->policy); + break; + } + + return; +} + +void +kdebug_secpolicyindex(spidx) + struct secpolicyindex *spidx; +{ + /* sanity check */ + if (spidx == NULL) + panic("kdebug_secpolicyindex: NULL pointer was passed.\n"); + + printf("secpolicyindex{ dir=%u prefs=%u prefd=%u ul_proto=%u\n", + spidx->dir, spidx->prefs, spidx->prefd, spidx->ul_proto); + + ipsec_hexdump((caddr_t)&spidx->src, + sysdep_sa_len((struct sockaddr *)&spidx->src)); + printf("\n"); + ipsec_hexdump((caddr_t)&spidx->dst, + sysdep_sa_len((struct sockaddr *)&spidx->dst)); + printf("}\n"); + + return; +} + +void +kdebug_secasindex(saidx) + struct secasindex *saidx; +{ + /* sanity check */ + if (saidx == NULL) + panic("kdebug_secpolicyindex: NULL pointer was passed.\n"); + + printf("secasindex{ mode=%u proto=%u\n", + saidx->mode, saidx->proto); + + ipsec_hexdump((caddr_t)&saidx->src, + sysdep_sa_len((struct sockaddr *)&saidx->src)); + printf("\n"); + ipsec_hexdump((caddr_t)&saidx->dst, + sysdep_sa_len((struct sockaddr *)&saidx->dst)); + printf("\n"); + + return; +} + +void +kdebug_secasv(sav) + struct secasvar *sav; +{ + /* sanity check */ + if (sav == NULL) + panic("kdebug_secasv: NULL pointer was passed.\n"); + + printf("secas{"); + kdebug_secasindex(&sav->sah->saidx); + + printf(" refcnt=%u state=%u auth=%u enc=%u\n", + sav->refcnt, sav->state, sav->alg_auth, sav->alg_enc); + printf(" spi=%u flags=%u\n", + (u_int32_t)ntohl(sav->spi), sav->flags); + + if (sav->key_auth != NULL) + kdebug_sadb_key((struct sadb_ext *)sav->key_auth); + if (sav->key_enc != NULL) + kdebug_sadb_key((struct sadb_ext *)sav->key_enc); + if (sav->iv != NULL) { + printf(" iv="); + ipsec_hexdump(sav->iv, sav->ivlen ? sav->ivlen : 8); + printf("\n"); + } + + if (sav->replay != NULL) + kdebug_secreplay(sav->replay); + if (sav->lft_c != NULL) + kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_c); + if (sav->lft_h != NULL) + kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_h); + if (sav->lft_s != NULL) + kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_s); + +#if notyet + /* XXX: misc[123] ? */ +#endif + + return; +} + +static void +kdebug_secreplay(rpl) + struct secreplay *rpl; +{ + int len, l; + + /* sanity check */ + if (rpl == NULL) + panic("kdebug_secreplay: NULL pointer was passed.\n"); + + printf(" secreplay{ count=%u wsize=%u seq=%u lastseq=%u", + rpl->count, rpl->wsize, rpl->seq, rpl->lastseq); + + if (rpl->bitmap == NULL) { + printf(" }\n"); + return; + } + + printf("\n bitmap { "); + + for (len = 0; len < rpl->wsize; len++) { + for (l = 7; l >= 0; l--) + printf("%u", (((rpl->bitmap)[len] >> l) & 1) ? 1 : 0); + } + printf(" }\n"); + + return; +} + +void +kdebug_mbufhdr(m) + struct mbuf *m; +{ + /* sanity check */ + if (m == NULL) + return; + + printf("mbuf(%p){ m_next:%p m_nextpkt:%p m_data:%p " + "m_len:%d m_type:0x%02x m_flags:0x%02x }\n", + m, m->m_next, m->m_nextpkt, m->m_data, + m->m_len, m->m_type, m->m_flags); + + if (m->m_flags & M_PKTHDR) { + printf(" m_pkthdr{ len:%d rcvif:%p }\n", + m->m_pkthdr.len, m->m_pkthdr.rcvif); + } + +#ifdef __FreeBSD__ + if (m->m_flags & M_EXT) { + printf(" m_ext{ ext_buf:%p ext_free:%p " + "ext_size:%u ext_ref:%p }\n", + m->m_ext.ext_buf, m->m_ext.ext_free, + m->m_ext.ext_size, m->m_ext.ext_ref); + } +#endif + + return; +} + +void +kdebug_mbuf(m0) + struct mbuf *m0; +{ + struct mbuf *m = m0; + int i, j; + + for (j = 0; m; m = m->m_next) { + kdebug_mbufhdr(m); + printf(" m_data:\n"); + for (i = 0; i < m->m_len; i++) { + if (i && i % 32 == 0) + printf("\n"); + if (i % 4 == 0) + printf(" "); + printf("%02x", mtod(m, u_char *)[i]); + j++; + } + printf("\n"); + } + + return; +} +#endif /* _KERNEL */ + +static void +kdebug_sockaddr(addr) + struct sockaddr *addr; +{ + struct sockaddr_in *sin4; +#ifdef INET6 + struct sockaddr_in6 *sin6; +#endif + + /* sanity check */ + if (addr == NULL) + panic("kdebug_sockaddr: NULL pointer was passed.\n"); + + /* NOTE: We deal with port number as host byte order. */ + printf("sockaddr{ len=%u family=%u", sysdep_sa_len(addr), addr->sa_family); + + switch (addr->sa_family) { + case AF_INET: + sin4 = (void *)addr; + printf(" port=%u\n", ntohs(sin4->sin_port)); + ipsec_hexdump(&sin4->sin_addr, sizeof(sin4->sin_addr)); + break; +#ifdef INET6 + case AF_INET6: + sin6 = (void *)addr; + printf(" port=%u\n", ntohs(sin6->sin6_port)); + printf(" flowinfo=0x%08x, scope_id=0x%08x\n", + sin6->sin6_flowinfo, sin6->sin6_scope_id); + ipsec_hexdump(&sin6->sin6_addr, sizeof(sin6->sin6_addr)); + break; +#endif + } + + printf(" }\n"); + + return; +} + +void +ipsec_bindump(buf, len) + caddr_t buf; + int len; +{ + int i; + + for (i = 0; i < len; i++) + printf("%c", (unsigned char)buf[i]); + + return; +} + + +void +ipsec_hexdump(buf, len) + const void *buf; + int len; +{ + int i; + + for (i = 0; i < len; i++) { + if (i != 0 && i % 32 == 0) printf("\n"); + if (i % 4 == 0) printf(" "); + printf("%02x", ((const unsigned char *)buf)[i]); + } +#if 0 + if (i % 32 != 0) printf("\n"); +#endif + + return; +} diff --git a/ipsec-tools/src/libipsec/libpfkey.h b/ipsec-tools/src/libipsec/libpfkey.h new file mode 100644 index 00000000..a213aac7 --- /dev/null +++ b/ipsec-tools/src/libipsec/libpfkey.h @@ -0,0 +1,238 @@ +/* $NetBSD: libpfkey.h,v 1.18 2010/12/03 14:32:52 tteras Exp $ */ + +/* Id: libpfkey.h,v 1.13 2005/12/04 20:26:43 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _LIBPFKEY_H +#define _LIBPFKEY_H + +#ifndef KAME_LIBPFKEY_H +#define KAME_LIBPFKEY_H + +#define PRIORITY_LOW 0xC0000000 +#define PRIORITY_DEFAULT 0x80000000 +#define PRIORITY_HIGH 0x40000000 + +#define PRIORITY_OFFSET_POSITIVE_MAX 0x3fffffff +#define PRIORITY_OFFSET_NEGATIVE_MAX 0x40000000 + +struct sadb_msg; +extern void pfkey_sadump __P((struct sadb_msg *)); +extern void pfkey_sadump_withports __P((struct sadb_msg *)); +extern void pfkey_spdump __P((struct sadb_msg *)); +extern void pfkey_spdump_withports __P((struct sadb_msg *)); + +struct sockaddr; +struct sadb_alg; + +/* Accomodate different prototypes in */ +#include +#include PATH_IPSEC_H + +#ifndef HAVE_IPSEC_POLICY_T +typedef caddr_t ipsec_policy_t; +#define __ipsec_const +#else +#define __ipsec_const const +#endif + +struct pfkey_send_sa_args { + int so; /* socket */ + u_int type; + u_int satype; + u_int mode; + struct sockaddr *src; /* IP src address for SA */ + struct sockaddr *dst; /* IP dst address for SA */ + u_int32_t spi; /* SA's spi */ + u_int32_t reqid; + u_int wsize; + caddr_t keymat; + u_int e_type, e_keylen; /* Encryption alg and keylen */ + u_int a_type, a_keylen; /* Authentication alg and key */ + u_int flags; + u_int32_t l_alloc; + u_int32_t l_bytes; + u_int32_t l_addtime; + u_int32_t l_usetime; + u_int32_t seq; + u_int8_t l_natt_type; + u_int16_t l_natt_sport, l_natt_dport; + struct sockaddr *l_natt_oa; + u_int16_t l_natt_frag; + u_int8_t ctxdoi, ctxalg; /* Security context DOI and algorithm */ + caddr_t ctxstr; /* Security context string */ + u_int16_t ctxstrlen; /* length of security context string */ +}; + +/* The options built into libipsec */ +extern int libipsec_opt; +#define LIBIPSEC_OPT_NATT 0x01 +#define LIBIPSEC_OPT_FRAG 0x02 +#define LIBIPSEC_OPT_SEC_CTX 0x04 + +/* IPsec Library Routines */ + +int ipsec_check_keylen __P((u_int, u_int, u_int)); +int ipsec_check_keylen2 __P((u_int, u_int, u_int)); +int ipsec_get_keylen __P((u_int, u_int, struct sadb_alg *)); +char *ipsec_dump_policy_withports __P((void *, const char *)); +void ipsec_hexdump __P((const void *, int)); +const char *ipsec_strerror __P((void)); +void kdebug_sadb __P((struct sadb_msg *)); +ipsec_policy_t ipsec_set_policy __P((__ipsec_const char *, int)); +int ipsec_get_policylen __P((ipsec_policy_t)); +char *ipsec_dump_policy __P((ipsec_policy_t, __ipsec_const char *)); + +/* PFKey Routines */ + +u_int pfkey_set_softrate __P((u_int, u_int)); +u_int pfkey_get_softrate __P((u_int)); +int pfkey_send_getspi __P((int, u_int, u_int, struct sockaddr *, + struct sockaddr *, u_int32_t, u_int32_t, u_int32_t, u_int32_t)); +int pfkey_send_getspi_nat __P((int, u_int, u_int, + struct sockaddr *, struct sockaddr *, u_int8_t, u_int16_t, u_int16_t, + u_int32_t, u_int32_t, u_int32_t, u_int32_t)); + +int pfkey_send_update2 __P((struct pfkey_send_sa_args *)); +int pfkey_send_add2 __P((struct pfkey_send_sa_args *)); +int pfkey_send_delete __P((int, u_int, u_int, + struct sockaddr *, struct sockaddr *, u_int32_t)); +int pfkey_send_delete_all __P((int, u_int, u_int, + struct sockaddr *, struct sockaddr *)); +int pfkey_send_get __P((int, u_int, u_int, + struct sockaddr *, struct sockaddr *, u_int32_t)); +int pfkey_send_register __P((int, u_int)); +int pfkey_recv_register __P((int)); +int pfkey_set_supported __P((struct sadb_msg *, int)); +int pfkey_send_flush __P((int, u_int)); +int pfkey_send_dump __P((int, u_int)); +int pfkey_send_promisc_toggle __P((int, int)); +int pfkey_send_spdadd __P((int, struct sockaddr *, u_int, + struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t)); +int pfkey_send_spdadd2 __P((int, struct sockaddr *, u_int, + struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t, + caddr_t, int, u_int32_t)); +int pfkey_send_spdupdate __P((int, struct sockaddr *, u_int, + struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t)); +int pfkey_send_spdupdate2 __P((int, struct sockaddr *, u_int, + struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t, + caddr_t, int, u_int32_t)); +int pfkey_send_spddelete __P((int, struct sockaddr *, u_int, + struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t)); +int pfkey_send_spddelete2 __P((int, u_int32_t)); +int pfkey_send_spdget __P((int, u_int32_t)); +int pfkey_send_spdsetidx __P((int, struct sockaddr *, u_int, + struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t)); +int pfkey_send_spdflush __P((int)); +int pfkey_send_spddump __P((int)); +#ifdef SADB_X_MIGRATE +int pfkey_send_migrate __P((int, struct sockaddr *, struct sockaddr *, + struct sockaddr *, u_int, struct sockaddr *, u_int, u_int, + caddr_t, int, u_int32_t)); +#endif + +/* XXX should be somewhere else !!! + */ +#ifdef SADB_X_EXT_NAT_T_TYPE +#define PFKEY_ADDR_X_PORT(ext) (ntohs(((struct sadb_x_nat_t_port *)ext)->sadb_x_nat_t_port_port)) +#define PFKEY_ADDR_X_NATTYPE(ext) ( ext != NULL && ((struct sadb_x_nat_t_type *)ext)->sadb_x_nat_t_type_type ) +#endif + + +int pfkey_open __P((void)); +void pfkey_close __P((int)); +int pfkey_set_buffer_size __P((int, int)); +struct sadb_msg *pfkey_recv __P((int)); +int pfkey_send __P((int, struct sadb_msg *, int)); +int pfkey_align __P((struct sadb_msg *, caddr_t *)); +int pfkey_check __P((caddr_t *)); + +/* + * Deprecated, available for backward compatibility with third party + * libipsec users. Please use pfkey_send_update2 and pfkey_send_add2 instead + */ +int pfkey_send_update __P((int, u_int, u_int, struct sockaddr *, + struct sockaddr *, u_int32_t, u_int32_t, u_int, + caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t, + u_int64_t, u_int64_t, u_int32_t)); +int pfkey_send_update_nat __P((int, u_int, u_int, struct sockaddr *, + struct sockaddr *, u_int32_t, u_int32_t, u_int, + caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t, + u_int64_t, u_int64_t, u_int32_t, + u_int8_t, u_int16_t, u_int16_t, struct sockaddr *, u_int16_t)); +int pfkey_send_add __P((int, u_int, u_int, struct sockaddr *, + struct sockaddr *, u_int32_t, u_int32_t, u_int, + caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t, + u_int64_t, u_int64_t, u_int32_t)); +int pfkey_send_add_nat __P((int, u_int, u_int, struct sockaddr *, + struct sockaddr *, u_int32_t, u_int32_t, u_int, + caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t, + u_int64_t, u_int64_t, u_int32_t, + u_int8_t, u_int16_t, u_int16_t, struct sockaddr *, u_int16_t)); + +#ifndef __SYSDEP_SA_LEN__ +#define __SYSDEP_SA_LEN__ +#include + +#ifndef IPPROTO_IPV4 +#define IPPROTO_IPV4 IPPROTO_IPIP +#endif + +#ifndef IPPROTO_IPCOMP +#define IPPROTO_IPCOMP IPPROTO_COMP +#endif + +#ifndef IPPROTO_MH +#define IPPROTO_MH 135 +#endif + +static __inline u_int8_t +sysdep_sa_len (const struct sockaddr *sa) +{ +#ifdef __linux__ + switch (sa->sa_family) + { + case AF_INET: + return sizeof (struct sockaddr_in); + case AF_INET6: + return sizeof (struct sockaddr_in6); + } + // log_print ("sysdep_sa_len: unknown sa family %d", sa->sa_family); + return sizeof (struct sockaddr_in); +#else + return sa->sa_len; +#endif +} +#endif + +#endif /* KAME_LIBPFKEY_H */ + +#endif /* _LIBPFKEY_H */ diff --git a/ipsec-tools/src/libipsec/pfkey.c b/ipsec-tools/src/libipsec/pfkey.c new file mode 100644 index 00000000..3114229e --- /dev/null +++ b/ipsec-tools/src/libipsec/pfkey.c @@ -0,0 +1,2674 @@ +/* $NetBSD: pfkey.c,v 1.21.2.1 2011/11/14 13:25:06 tteras Exp $ */ + +/* $KAME: pfkey.c,v 1.47 2003/10/02 19:52:12 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include +#include + +#include "ipsec_strerror.h" +#include "libpfkey.h" + +#define CALLOC(size, cast) (cast)calloc(1, (size)) + +static int findsupportedmap __P((int)); +static int setsupportedmap __P((struct sadb_supported *)); +static struct sadb_alg *findsupportedalg __P((u_int, u_int)); +static int pfkey_send_x1 __P((struct pfkey_send_sa_args *)); +static int pfkey_send_x2 __P((int, u_int, u_int, u_int, + struct sockaddr *, struct sockaddr *, u_int32_t)); +static int pfkey_send_x3 __P((int, u_int, u_int)); +static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int, + struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t, + char *, int, u_int32_t)); +static int pfkey_send_x5 __P((int, u_int, u_int32_t)); + +static caddr_t pfkey_setsadbmsg __P((caddr_t, caddr_t, u_int, u_int, + u_int, u_int32_t, pid_t)); +static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int, + u_int, u_int, u_int32_t)); +static caddr_t pfkey_setsadbaddr __P((caddr_t, caddr_t, u_int, + struct sockaddr *, u_int, u_int)); + +#ifdef SADB_X_EXT_KMADDRESS +static caddr_t pfkey_setsadbkmaddr __P((caddr_t, caddr_t, struct sockaddr *, + struct sockaddr *)); +#endif + +static caddr_t pfkey_setsadbkey __P((caddr_t, caddr_t, u_int, caddr_t, u_int)); +static caddr_t pfkey_setsadblifetime __P((caddr_t, caddr_t, u_int, u_int32_t, + u_int32_t, u_int32_t, u_int32_t)); +static caddr_t pfkey_setsadbxsa2 __P((caddr_t, caddr_t, u_int32_t, u_int32_t)); + +#ifdef SADB_X_EXT_NAT_T_TYPE +static caddr_t pfkey_set_natt_type __P((caddr_t, caddr_t, u_int, u_int8_t)); +static caddr_t pfkey_set_natt_port __P((caddr_t, caddr_t, u_int, u_int16_t)); +#endif +#ifdef SADB_X_EXT_NAT_T_FRAG +static caddr_t pfkey_set_natt_frag __P((caddr_t, caddr_t, u_int, u_int16_t)); +#endif + +#ifdef SADB_X_EXT_SEC_CTX +static caddr_t pfkey_setsecctx __P((caddr_t, caddr_t, u_int, u_int8_t, u_int8_t, + caddr_t, u_int16_t)); +#endif + +int libipsec_opt = 0 +#ifdef SADB_X_EXT_NAT_T_TYPE + | LIBIPSEC_OPT_NATT +#endif +#ifdef SADB_X_EXT_NAT_T_FRAG + | LIBIPSEC_OPT_FRAG +#endif +#ifdef SADB_X_EXT_NAT_T_SEC_CTX + | LIBIPSEC_OPT_SEC_CTX +#endif + ; + +/* + * make and search supported algorithm structure. + */ +static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, +#ifdef SADB_X_SATYPE_TCPSIGNATURE + NULL, +#endif +}; + +static int supported_map[] = { + SADB_SATYPE_AH, + SADB_SATYPE_ESP, + SADB_X_SATYPE_IPCOMP, +#ifdef SADB_X_SATYPE_TCPSIGNATURE + SADB_X_SATYPE_TCPSIGNATURE, +#endif +}; + +static int +findsupportedmap(satype) + int satype; +{ + int i; + + for (i = 0; i < sizeof(supported_map)/sizeof(supported_map[0]); i++) + if (supported_map[i] == satype) + return i; + return -1; +} + +static struct sadb_alg * +findsupportedalg(satype, alg_id) + u_int satype, alg_id; +{ + int algno; + int tlen; + caddr_t p; + + /* validity check */ + algno = findsupportedmap((int)satype); + if (algno == -1) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return NULL; + } + if (ipsec_supported[algno] == NULL) { + __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST; + return NULL; + } + + tlen = ipsec_supported[algno]->sadb_supported_len + - sizeof(struct sadb_supported); + p = (void *)(ipsec_supported[algno] + 1); + while (tlen > 0) { + if (tlen < sizeof(struct sadb_alg)) { + /* invalid format */ + break; + } + if (((struct sadb_alg *)(void *)p)->sadb_alg_id == alg_id) + return (void *)p; + + tlen -= sizeof(struct sadb_alg); + p += sizeof(struct sadb_alg); + } + + __ipsec_errcode = EIPSEC_NOT_SUPPORTED; + return NULL; +} + +static int +setsupportedmap(sup) + struct sadb_supported *sup; +{ + struct sadb_supported **ipsup; + + switch (sup->sadb_supported_exttype) { + case SADB_EXT_SUPPORTED_AUTH: + ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_AH)]; + break; + case SADB_EXT_SUPPORTED_ENCRYPT: + ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_ESP)]; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_SATYPE; + return -1; + } + + if (*ipsup) + free(*ipsup); + + *ipsup = malloc((size_t)sup->sadb_supported_len); + if (!*ipsup) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + memcpy(*ipsup, sup, (size_t)sup->sadb_supported_len); + + return 0; +} + +/* + * check key length against algorithm specified. + * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the + * augument, and only calls to ipsec_check_keylen2(); + * keylen is the unit of bit. + * OUT: + * -1: invalid. + * 0: valid. + */ +int +ipsec_check_keylen(supported, alg_id, keylen) + u_int supported; + u_int alg_id; + u_int keylen; +{ + u_int satype; + + /* validity check */ + switch (supported) { + case SADB_EXT_SUPPORTED_AUTH: + satype = SADB_SATYPE_AH; + break; + case SADB_EXT_SUPPORTED_ENCRYPT: + satype = SADB_SATYPE_ESP; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + + return ipsec_check_keylen2(satype, alg_id, keylen); +} + +/* + * check key length against algorithm specified. + * satype is one of satype defined at pfkeyv2.h. + * keylen is the unit of bit. + * OUT: + * -1: invalid. + * 0: valid. + */ +int +ipsec_check_keylen2(satype, alg_id, keylen) + u_int satype; + u_int alg_id; + u_int keylen; +{ + struct sadb_alg *alg; + + alg = findsupportedalg(satype, alg_id); + if (!alg) + return -1; + + if (keylen < alg->sadb_alg_minbits || keylen > alg->sadb_alg_maxbits) { + fprintf(stderr, "%d %d %d\n", keylen, alg->sadb_alg_minbits, + alg->sadb_alg_maxbits); + __ipsec_errcode = EIPSEC_INVAL_KEYLEN; + return -1; + } + + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; +} + +/* + * get max/min key length against algorithm specified. + * satype is one of satype defined at pfkeyv2.h. + * keylen is the unit of bit. + * OUT: + * -1: invalid. + * 0: valid. + */ +int +ipsec_get_keylen(supported, alg_id, alg0) + u_int supported, alg_id; + struct sadb_alg *alg0; +{ + struct sadb_alg *alg; + u_int satype; + + /* validity check */ + if (!alg0) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + + switch (supported) { + case SADB_EXT_SUPPORTED_AUTH: + satype = SADB_SATYPE_AH; + break; + case SADB_EXT_SUPPORTED_ENCRYPT: + satype = SADB_SATYPE_ESP; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + + alg = findsupportedalg(satype, alg_id); + if (!alg) + return -1; + + memcpy(alg0, alg, sizeof(*alg0)); + + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; +} + +/* + * set the rate for SOFT lifetime against HARD one. + * If rate is more than 100 or equal to zero, then set to 100. + */ +static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE; +static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE; +static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE; +static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE; + +u_int +pfkey_set_softrate(type, rate) + u_int type, rate; +{ + __ipsec_errcode = EIPSEC_NO_ERROR; + + if (rate > 100 || rate == 0) + rate = 100; + + switch (type) { + case SADB_X_LIFETIME_ALLOCATIONS: + soft_lifetime_allocations_rate = rate; + return 0; + case SADB_X_LIFETIME_BYTES: + soft_lifetime_bytes_rate = rate; + return 0; + case SADB_X_LIFETIME_ADDTIME: + soft_lifetime_addtime_rate = rate; + return 0; + case SADB_X_LIFETIME_USETIME: + soft_lifetime_usetime_rate = rate; + return 0; + } + + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return 1; +} + +/* + * get current rate for SOFT lifetime against HARD one. + * ATTENTION: ~0 is returned if invalid type was passed. + */ +u_int +pfkey_get_softrate(type) + u_int type; +{ + switch (type) { + case SADB_X_LIFETIME_ALLOCATIONS: + return soft_lifetime_allocations_rate; + case SADB_X_LIFETIME_BYTES: + return soft_lifetime_bytes_rate; + case SADB_X_LIFETIME_ADDTIME: + return soft_lifetime_addtime_rate; + case SADB_X_LIFETIME_USETIME: + return soft_lifetime_usetime_rate; + } + + return (u_int)~0; +} + +/* + * sending SADB_GETSPI message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_getspi_nat(int so, u_int satype, u_int mode, struct sockaddr *src, + struct sockaddr *dst, u_int8_t natt_type, u_int16_t sport, + u_int16_t dport, u_int32_t min, u_int32_t max, u_int32_t reqid, + u_int32_t seq) +{ + struct sadb_msg *newmsg; + caddr_t ep; + int len; + int need_spirange = 0; + caddr_t p; + int plen; + + /* validity check */ + if (src == NULL || dst == NULL) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + if (src->sa_family != dst->sa_family) { + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + return -1; + } + if (min > max || (min > 0 && min <= 255)) { + __ipsec_errcode = EIPSEC_INVAL_SPI; + return -1; + } + switch (src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_FAMILY; + return -1; + } + + /* create new sadb_msg to send. */ + len = sizeof(struct sadb_msg) + + sizeof(struct sadb_x_sa2) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(src)) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(dst)); + + if (min > 255 && max < (u_int)~0) { + need_spirange++; + len += sizeof(struct sadb_spirange); + } + +#ifdef SADB_X_EXT_NAT_T_TYPE + if(natt_type||sport||dport){ + len += sizeof(struct sadb_x_nat_t_type); + len += sizeof(struct sadb_x_nat_t_port); + len += sizeof(struct sadb_x_nat_t_port); + } +#endif + + if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + ep = ((caddr_t)(void *)newmsg) + len; + + p = pfkey_setsadbmsg((void *)newmsg, ep, SADB_GETSPI, + (u_int)len, satype, seq, getpid()); + if (!p) { + free(newmsg); + return -1; + } + + p = pfkey_setsadbxsa2(p, ep, mode, reqid); + if (!p) { + free(newmsg); + return -1; + } + + /* set sadb_address for source */ + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, + IPSEC_ULPROTO_ANY); + if (!p) { + free(newmsg); + return -1; + } + + /* set sadb_address for destination */ + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, + IPSEC_ULPROTO_ANY); + if (!p) { + free(newmsg); + return -1; + } + +#ifdef SADB_X_EXT_NAT_T_TYPE + /* Add nat-t messages */ + if (natt_type) { + p = pfkey_set_natt_type(p, ep, SADB_X_EXT_NAT_T_TYPE, + natt_type); + if (!p) { + free(newmsg); + return -1; + } + + p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_SPORT, + sport); + if (!p) { + free(newmsg); + return -1; + } + + p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_DPORT, + dport); + if (!p) { + free(newmsg); + return -1; + } + } +#endif + + /* proccessing spi range */ + if (need_spirange) { + struct sadb_spirange spirange; + + if (p + sizeof(spirange) > ep) { + free(newmsg); + return -1; + } + + memset(&spirange, 0, sizeof(spirange)); + spirange.sadb_spirange_len = PFKEY_UNIT64(sizeof(spirange)); + spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE; + spirange.sadb_spirange_min = min; + spirange.sadb_spirange_max = max; + + memcpy(p, &spirange, sizeof(spirange)); + + p += sizeof(spirange); + } + if (p != ep) { + free(newmsg); + return -1; + } + + /* send message */ + len = pfkey_send(so, newmsg, len); + free(newmsg); + + if (len < 0) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return len; +} + +int +pfkey_send_getspi(int so, u_int satype, u_int mode, struct sockaddr *src, + struct sockaddr *dst, u_int32_t min, u_int32_t max, u_int32_t reqid, + u_int32_t seq) +{ + return pfkey_send_getspi_nat(so, satype, mode, src, dst, 0, 0, 0, + min, max, reqid, seq); +} + +/* + * sending SADB_UPDATE message to the kernel. + * The length of key material is a_keylen + e_keylen. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_update2(struct pfkey_send_sa_args *sa_parms) +{ + int len; + + sa_parms->type = SADB_UPDATE; + if ((len = pfkey_send_x1(sa_parms)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_ADD message to the kernel. + * The length of key material is a_keylen + e_keylen. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_add2(struct pfkey_send_sa_args *sa_parms) +{ + int len; + + sa_parms->type = SADB_ADD; + if ((len = pfkey_send_x1(sa_parms)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_DELETE message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_delete(int so, u_int satype, u_int mode, struct sockaddr *src, + struct sockaddr *dst, u_int32_t spi) +{ + int len; + if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_DELETE without spi to the kernel. This is + * the "delete all" request (an extension also present in + * Solaris). + * + * OUT: + * positive: success and return length sent + * -1 : error occured, and set errno + */ +/*ARGSUSED*/ +int +pfkey_send_delete_all(int so, u_int satype, u_int mode, struct sockaddr *src, + struct sockaddr *dst) +{ + struct sadb_msg *newmsg; + int len; + caddr_t p; + int plen; + caddr_t ep; + + /* validity check */ + if (src == NULL || dst == NULL) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + if (src->sa_family != dst->sa_family) { + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + return -1; + } + switch (src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_FAMILY; + return -1; + } + + /* create new sadb_msg to reply. */ + len = sizeof(struct sadb_msg) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(src)) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(dst)); + + if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + ep = ((caddr_t)(void *)newmsg) + len; + + p = pfkey_setsadbmsg((void *)newmsg, ep, SADB_DELETE, (u_int)len, + satype, 0, getpid()); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, + IPSEC_ULPROTO_ANY); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, + IPSEC_ULPROTO_ANY); + if (!p || p != ep) { + free(newmsg); + return -1; + } + + /* send message */ + len = pfkey_send(so, newmsg, len); + free(newmsg); + + if (len < 0) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return len; +} + +/* + * sending SADB_GET message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_get(int so, u_int satype, u_int mode, struct sockaddr *src, + struct sockaddr *dst, u_int32_t spi) +{ + int len; + if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_REGISTER message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_register(int so, u_int satype) +{ + int len, algno; + + if (satype == PF_UNSPEC) { + for (algno = 0; + algno < sizeof(supported_map)/sizeof(supported_map[0]); + algno++) { + if (ipsec_supported[algno]) { + free(ipsec_supported[algno]); + ipsec_supported[algno] = NULL; + } + } + } else { + algno = findsupportedmap((int)satype); + if (algno == -1) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + + if (ipsec_supported[algno]) { + free(ipsec_supported[algno]); + ipsec_supported[algno] = NULL; + } + } + + if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0) + return -1; + + return len; +} + +/* + * receiving SADB_REGISTER message from the kernel, and copy buffer for + * sadb_supported returned into ipsec_supported. + * OUT: + * 0: success and return length sent. + * -1: error occured, and set errno. + */ +int +pfkey_recv_register(int so) +{ + pid_t pid = getpid(); + struct sadb_msg *newmsg; + int error = -1; + + /* receive message */ + for (;;) { + if ((newmsg = pfkey_recv(so)) == NULL) + return -1; + if (newmsg->sadb_msg_type == SADB_REGISTER && + newmsg->sadb_msg_pid == pid) + break; + free(newmsg); + } + + /* check and fix */ + newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len); + + error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len); + free(newmsg); + + if (error == 0) + __ipsec_errcode = EIPSEC_NO_ERROR; + + return error; +} + +/* + * receiving SADB_REGISTER message from the kernel, and copy buffer for + * sadb_supported returned into ipsec_supported. + * NOTE: sadb_msg_len must be host order. + * IN: + * tlen: msg length, it's to makeing sure. + * OUT: + * 0: success and return length sent. + * -1: error occured, and set errno. + */ +int +pfkey_set_supported(struct sadb_msg *msg, int tlen) +{ + struct sadb_supported *sup; + caddr_t p; + caddr_t ep; + + /* validity */ + if (msg->sadb_msg_len != tlen) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + + p = (void *)msg; + ep = p + tlen; + + p += sizeof(struct sadb_msg); + + while (p < ep) { + sup = (void *)p; + if (ep < p + sizeof(*sup) || + PFKEY_EXTLEN(sup) < sizeof(*sup) || + ep < p + sup->sadb_supported_len) { + /* invalid format */ + break; + } + + switch (sup->sadb_supported_exttype) { + case SADB_EXT_SUPPORTED_AUTH: + case SADB_EXT_SUPPORTED_ENCRYPT: + break; + default: + __ipsec_errcode = EIPSEC_INVAL_SATYPE; + return -1; + } + + /* fixed length */ + sup->sadb_supported_len = PFKEY_EXTLEN(sup); + + /* set supported map */ + if (setsupportedmap(sup) != 0) + return -1; + + p += sup->sadb_supported_len; + } + + if (p != ep) { + __ipsec_errcode = EIPSEC_INVAL_SATYPE; + return -1; + } + + __ipsec_errcode = EIPSEC_NO_ERROR; + + return 0; +} + +/* + * sending SADB_FLUSH message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_flush(int so, u_int satype) +{ + int len; + + if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_DUMP message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_dump(int so, u_int satype) +{ + int len; + + if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_X_PROMISC message to the kernel. + * NOTE that this function handles promisc mode toggle only. + * IN: + * flag: set promisc off if zero, set promisc on if non-zero. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + * 0 : error occured, and set errno. + * others: a pointer to new allocated buffer in which supported + * algorithms is. + */ +int +pfkey_send_promisc_toggle(int so, int flag) +{ + int len; + + if ((len = pfkey_send_x3(so, SADB_X_PROMISC, + (u_int)(flag ? 1 : 0))) < 0) + return -1; + + return len; +} + +/* + * sending SADB_X_SPDADD message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spdadd(int so, struct sockaddr *src, u_int prefs, + struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy, + int policylen, u_int32_t seq) +{ + int len; + + if ((len = pfkey_send_x4(so, SADB_X_SPDADD, + src, prefs, dst, prefd, proto, + (u_int64_t)0, (u_int64_t)0, + policy, policylen, seq)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_X_SPDADD message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spdadd2(int so, struct sockaddr *src, u_int prefs, + struct sockaddr *dst, u_int prefd, u_int proto, u_int64_t ltime, + u_int64_t vtime, caddr_t policy, int policylen, u_int32_t seq) +{ + int len; + + if ((len = pfkey_send_x4(so, SADB_X_SPDADD, + src, prefs, dst, prefd, proto, + ltime, vtime, + policy, policylen, seq)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_X_SPDUPDATE message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spdupdate(int so, struct sockaddr *src, u_int prefs, + struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy, + int policylen, u_int32_t seq) +{ + int len; + + if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, + src, prefs, dst, prefd, proto, + (u_int64_t)0, (u_int64_t)0, + policy, policylen, seq)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_X_SPDUPDATE message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spdupdate2(int so, struct sockaddr *src, u_int prefs, + struct sockaddr *dst, u_int prefd, u_int proto, u_int64_t ltime, + u_int64_t vtime, caddr_t policy, int policylen, u_int32_t seq) +{ + int len; + + if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, + src, prefs, dst, prefd, proto, + ltime, vtime, + policy, policylen, seq)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_X_SPDDELETE message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spddelete(int so, struct sockaddr *src, u_int prefs, + struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy, + int policylen, u_int32_t seq) +{ + int len; + + if (policylen != sizeof(struct sadb_x_policy)) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + + if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE, + src, prefs, dst, prefd, proto, + (u_int64_t)0, (u_int64_t)0, + policy, policylen, seq)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_X_SPDDELETE message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spddelete2(int so, u_int32_t spid) +{ + int len; + + if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_X_SPDGET message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spdget(int so, u_int32_t spid) +{ + int len; + + if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_X_SPDSETIDX message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spdsetidx(int so, struct sockaddr *src, u_int prefs, + struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy, + int policylen, u_int32_t seq) +{ + int len; + + if (policylen != sizeof(struct sadb_x_policy)) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + + if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX, + src, prefs, dst, prefd, proto, + (u_int64_t)0, (u_int64_t)0, + policy, policylen, seq)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_SPDFLUSH message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spdflush(int so) +{ + int len; + + if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_SPDDUMP message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spddump(int so) +{ + int len; + + if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0) + return -1; + + return len; +} + + +#ifdef SADB_X_MIGRATE +/* + * sending SADB_X_MIGRATE message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_migrate(int so, struct sockaddr *local, struct sockaddr *remote, + struct sockaddr *src, u_int prefs, struct sockaddr *dst, u_int prefd, + u_int proto, caddr_t policy, int policylen, u_int32_t seq) +{ + struct sadb_msg *newmsg; + int len; + caddr_t p; + int plen; + caddr_t ep; + + /* validity check */ + if (src == NULL || dst == NULL) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + if (src->sa_family != dst->sa_family) { + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + return -1; + } + + if (local == NULL || remote == NULL) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } +#ifdef SADB_X_EXT_KMADDRESS + if (local->sa_family != remote->sa_family) { + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + return -1; + } +#endif + + switch (src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_FAMILY; + return -1; + } + if (prefs > plen || prefd > plen) { + __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; + return -1; + } + + /* create new sadb_msg to reply. */ + len = sizeof(struct sadb_msg) +#ifdef SADB_X_EXT_KMADDRESS + + sizeof(struct sadb_x_kmaddress) + + PFKEY_ALIGN8(2*sysdep_sa_len(local)) +#endif + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(src)) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(dst)) + + policylen; + + if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + ep = ((caddr_t)newmsg) + len; + + p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_X_MIGRATE, (u_int)len, + SADB_SATYPE_UNSPEC, seq, getpid()); + if (!p) { + free(newmsg); + return -1; + } +#ifdef SADB_X_EXT_KMADDRESS + p = pfkey_setsadbkmaddr(p, ep, local, remote); + if (!p) { + free(newmsg); + return -1; + } +#endif + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto); + if (!p || p + policylen != ep) { + free(newmsg); + return -1; + } + memcpy(p, policy, policylen); + + /* send message */ + len = pfkey_send(so, newmsg, len); + free(newmsg); + + if (len < 0) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return len; +} +#endif + + +/* sending SADB_ADD or SADB_UPDATE message to the kernel */ +static int +pfkey_send_x1(struct pfkey_send_sa_args *sa_parms) +{ + struct sadb_msg *newmsg; + int len; + caddr_t p; + int plen; + caddr_t ep; + + /* validity check */ + if (sa_parms->src == NULL || sa_parms->dst == NULL) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + if (sa_parms->src->sa_family != sa_parms->dst->sa_family) { + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + return -1; + } + switch (sa_parms->src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_FAMILY; + return -1; + } + + switch (sa_parms->satype) { + case SADB_SATYPE_ESP: + if (sa_parms->e_type == SADB_EALG_NONE) { + __ipsec_errcode = EIPSEC_NO_ALGS; + return -1; + } + break; + case SADB_SATYPE_AH: + if (sa_parms->e_type != SADB_EALG_NONE) { + __ipsec_errcode = EIPSEC_INVAL_ALGS; + return -1; + } + if (sa_parms->a_type == SADB_AALG_NONE) { + __ipsec_errcode = EIPSEC_NO_ALGS; + return -1; + } + break; + case SADB_X_SATYPE_IPCOMP: + if (sa_parms->e_type == SADB_X_CALG_NONE) { + __ipsec_errcode = EIPSEC_INVAL_ALGS; + return -1; + } + if (sa_parms->a_type != SADB_AALG_NONE) { + __ipsec_errcode = EIPSEC_NO_ALGS; + return -1; + } + break; +#ifdef SADB_X_AALG_TCP_MD5 + case SADB_X_SATYPE_TCPSIGNATURE: + if (sa_parms->e_type != SADB_EALG_NONE) { + __ipsec_errcode = EIPSEC_INVAL_ALGS; + return -1; + } + if (sa_parms->a_type != SADB_X_AALG_TCP_MD5) { + __ipsec_errcode = EIPSEC_INVAL_ALGS; + return -1; + } + break; +#endif + default: + __ipsec_errcode = EIPSEC_INVAL_SATYPE; + return -1; + } + + /* create new sadb_msg to reply. */ + len = sizeof(struct sadb_msg) + + sizeof(struct sadb_sa) + + sizeof(struct sadb_x_sa2) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(sa_parms->src)) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(sa_parms->dst)) + + sizeof(struct sadb_lifetime) + + sizeof(struct sadb_lifetime); + + if (sa_parms->e_type != SADB_EALG_NONE && + sa_parms->satype != SADB_X_SATYPE_IPCOMP) + len += (sizeof(struct sadb_key) + + PFKEY_ALIGN8(sa_parms->e_keylen)); + if (sa_parms->a_type != SADB_AALG_NONE) + len += (sizeof(struct sadb_key) + + PFKEY_ALIGN8(sa_parms->a_keylen)); + +#ifdef SADB_X_EXT_SEC_CTX + if (sa_parms->ctxstr != NULL) + len += (sizeof(struct sadb_x_sec_ctx) + + PFKEY_ALIGN8(sa_parms->ctxstrlen)); +#endif + +#ifdef SADB_X_EXT_NAT_T_TYPE + /* add nat-t packets */ + if (sa_parms->l_natt_type) { + switch(sa_parms->satype) { + case SADB_SATYPE_ESP: + case SADB_X_SATYPE_IPCOMP: + break; + default: + __ipsec_errcode = EIPSEC_NO_ALGS; + return -1; + } + + len += sizeof(struct sadb_x_nat_t_type); + len += sizeof(struct sadb_x_nat_t_port); + len += sizeof(struct sadb_x_nat_t_port); + if (sa_parms->l_natt_oa) + len += sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(sa_parms->l_natt_oa)); +#ifdef SADB_X_EXT_NAT_T_FRAG + if (sa_parms->l_natt_frag) + len += sizeof(struct sadb_x_nat_t_frag); +#endif + } +#endif + + if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + ep = ((caddr_t)(void *)newmsg) + len; + + p = pfkey_setsadbmsg((void *)newmsg, ep, sa_parms->type, (u_int)len, + sa_parms->satype, sa_parms->seq, getpid()); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbsa(p, ep, sa_parms->spi, sa_parms->wsize, + sa_parms->a_type, sa_parms->e_type, + sa_parms->flags); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbxsa2(p, ep, sa_parms->mode, sa_parms->reqid); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, sa_parms->src, + (u_int)plen, IPSEC_ULPROTO_ANY); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, sa_parms->dst, + (u_int)plen, IPSEC_ULPROTO_ANY); + if (!p) { + free(newmsg); + return -1; + } + + if (sa_parms->e_type != SADB_EALG_NONE && + sa_parms->satype != SADB_X_SATYPE_IPCOMP) { + p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT, + sa_parms->keymat, sa_parms->e_keylen); + if (!p) { + free(newmsg); + return -1; + } + } + if (sa_parms->a_type != SADB_AALG_NONE) { + p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH, + sa_parms->keymat + sa_parms->e_keylen, + sa_parms->a_keylen); + if (!p) { + free(newmsg); + return -1; + } + } + + /* set sadb_lifetime for destination */ + p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, + sa_parms->l_alloc, sa_parms->l_bytes, + sa_parms->l_addtime, sa_parms->l_usetime); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT, + sa_parms->l_alloc, sa_parms->l_bytes, + sa_parms->l_addtime, sa_parms->l_usetime); + if (!p) { + free(newmsg); + return -1; + } +#ifdef SADB_X_EXT_SEC_CTX + if (sa_parms->ctxstr != NULL) { + p = pfkey_setsecctx(p, ep, SADB_X_EXT_SEC_CTX, sa_parms->ctxdoi, + sa_parms->ctxalg, sa_parms->ctxstr, + sa_parms->ctxstrlen); + if (!p) { + free(newmsg); + return -1; + } + } +#endif + +#ifdef SADB_X_EXT_NAT_T_TYPE + /* Add nat-t messages */ + if (sa_parms->l_natt_type) { + p = pfkey_set_natt_type(p, ep, SADB_X_EXT_NAT_T_TYPE, + sa_parms->l_natt_type); + if (!p) { + free(newmsg); + return -1; + } + + p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_SPORT, + sa_parms->l_natt_sport); + if (!p) { + free(newmsg); + return -1; + } + + p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_DPORT, + sa_parms->l_natt_dport); + if (!p) { + free(newmsg); + return -1; + } + + if (sa_parms->l_natt_oa) { + p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_NAT_T_OA, + sa_parms->l_natt_oa, + (u_int)PFKEY_ALIGN8(sysdep_sa_len(sa_parms->l_natt_oa)), + IPSEC_ULPROTO_ANY); + if (!p) { + free(newmsg); + return -1; + } + } + +#ifdef SADB_X_EXT_NAT_T_FRAG + if (sa_parms->l_natt_frag) { + p = pfkey_set_natt_frag(p, ep, SADB_X_EXT_NAT_T_FRAG, + sa_parms->l_natt_frag); + if (!p) { + free(newmsg); + return -1; + } + } +#endif + } +#endif + + if (p != ep) { + free(newmsg); + return -1; + } + + /* send message */ + len = pfkey_send(sa_parms->so, newmsg, len); + free(newmsg); + + if (len < 0) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return len; +} + +/* sending SADB_DELETE or SADB_GET message to the kernel */ +/*ARGSUSED*/ +static int +pfkey_send_x2(int so, u_int type, u_int satype, u_int mode, + struct sockaddr *src, struct sockaddr *dst, u_int32_t spi) +{ + struct sadb_msg *newmsg; + int len; + caddr_t p; + int plen; + caddr_t ep; + + /* validity check */ + if (src == NULL || dst == NULL) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + if (src->sa_family != dst->sa_family) { + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + return -1; + } + switch (src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_FAMILY; + return -1; + } + + /* create new sadb_msg to reply. */ + len = sizeof(struct sadb_msg) + + sizeof(struct sadb_sa) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(src)) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(dst)); + + if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + ep = ((caddr_t)(void *)newmsg) + len; + + p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, satype, 0, + getpid()); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, + IPSEC_ULPROTO_ANY); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, + IPSEC_ULPROTO_ANY); + if (!p || p != ep) { + free(newmsg); + return -1; + } + + /* send message */ + len = pfkey_send(so, newmsg, len); + free(newmsg); + + if (len < 0) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return len; +} + +/* + * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message + * to the kernel + */ +static int +pfkey_send_x3(int so, u_int type, u_int satype) +{ + struct sadb_msg *newmsg; + int len; + caddr_t p; + caddr_t ep; + + /* validity check */ + switch (type) { + case SADB_X_PROMISC: + if (satype != 0 && satype != 1) { + __ipsec_errcode = EIPSEC_INVAL_SATYPE; + return -1; + } + break; + default: + switch (satype) { + case SADB_SATYPE_UNSPEC: + case SADB_SATYPE_AH: + case SADB_SATYPE_ESP: + case SADB_X_SATYPE_IPCOMP: +#ifdef SADB_X_SATYPE_TCPSIGNATURE + case SADB_X_SATYPE_TCPSIGNATURE: +#endif + break; + default: + __ipsec_errcode = EIPSEC_INVAL_SATYPE; + return -1; + } + } + + /* create new sadb_msg to send. */ + len = sizeof(struct sadb_msg); + + if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + ep = ((caddr_t)(void *)newmsg) + len; + + p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, satype, 0, + getpid()); + if (!p || p != ep) { + free(newmsg); + return -1; + } + + /* send message */ + len = pfkey_send(so, newmsg, len); + free(newmsg); + + if (len < 0) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return len; +} + +/* sending SADB_X_SPDADD message to the kernel */ +static int +pfkey_send_x4(int so, u_int type, struct sockaddr *src, u_int prefs, + struct sockaddr *dst, u_int prefd, u_int proto, u_int64_t ltime, + u_int64_t vtime, char *policy, int policylen, u_int32_t seq) +{ + struct sadb_msg *newmsg; + int len; + caddr_t p; + int plen; + caddr_t ep; + + /* validity check */ + if (src == NULL || dst == NULL) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + if (src->sa_family != dst->sa_family) { + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + return -1; + } + + switch (src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_FAMILY; + return -1; + } + if (prefs > plen || prefd > plen) { + __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; + return -1; + } + + /* create new sadb_msg to reply. */ + len = sizeof(struct sadb_msg) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(src)) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len(src)) + + sizeof(struct sadb_lifetime) + + policylen; + + if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + ep = ((caddr_t)(void *)newmsg) + len; + + p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, + SADB_SATYPE_UNSPEC, seq, getpid()); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, + 0, 0, (u_int)ltime, (u_int)vtime); + if (!p || p + policylen != ep) { + free(newmsg); + return -1; + } + memcpy(p, policy, (size_t)policylen); + + /* send message */ + len = pfkey_send(so, newmsg, len); + free(newmsg); + + if (len < 0) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return len; +} + +/* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */ +static int +pfkey_send_x5(int so, u_int type, u_int32_t spid) +{ + struct sadb_msg *newmsg; + struct sadb_x_policy xpl; + int len; + caddr_t p; + caddr_t ep; + + /* create new sadb_msg to reply. */ + len = sizeof(struct sadb_msg) + + sizeof(xpl); + + if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + ep = ((caddr_t)(void *)newmsg) + len; + + p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, + SADB_SATYPE_UNSPEC, 0, getpid()); + if (!p) { + free(newmsg); + return -1; + } + + if (p + sizeof(xpl) != ep) { + free(newmsg); + return -1; + } + memset(&xpl, 0, sizeof(xpl)); + xpl.sadb_x_policy_len = PFKEY_UNIT64(sizeof(xpl)); + xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY; + xpl.sadb_x_policy_id = spid; + memcpy(p, &xpl, sizeof(xpl)); + + /* send message */ + len = pfkey_send(so, newmsg, len); + free(newmsg); + + if (len < 0) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return len; +} + +/* + * open a socket. + * OUT: + * -1: fail. + * others : success and return value of socket. + */ +int +pfkey_open(void) +{ + int so; + int bufsiz_current, bufsiz_wanted; + int ret; + socklen_t len; + + if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + + /* + * This is a temporary workaround for KAME PR 154. + * Don't really care even if it fails. + */ + /* Try to have 128k. If we have more, do not lower it. */ + bufsiz_wanted = 128 * 1024; + len = sizeof(bufsiz_current); + ret = getsockopt(so, SOL_SOCKET, SO_SNDBUF, + &bufsiz_current, &len); + if ((ret < 0) || (bufsiz_current < bufsiz_wanted)) + (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, + &bufsiz_wanted, sizeof(bufsiz_wanted)); + + /* Try to have have at least 2MB. If we have more, do not lower it. */ + bufsiz_wanted = 2 * 1024 * 1024; + len = sizeof(bufsiz_current); + ret = getsockopt(so, SOL_SOCKET, SO_RCVBUF, + &bufsiz_current, &len); + if (ret < 0) + bufsiz_current = 128 * 1024; + + for (; bufsiz_wanted > bufsiz_current; bufsiz_wanted /= 2) { + if (setsockopt(so, SOL_SOCKET, SO_RCVBUF, + &bufsiz_wanted, sizeof(bufsiz_wanted)) == 0) + break; + } + + __ipsec_errcode = EIPSEC_NO_ERROR; + return so; +} + +int +pfkey_set_buffer_size(int so, int size) +{ + int newsize; + int actual_bufsiz; + socklen_t sizebufsiz; + int desired_bufsiz; + + /* + * on linux you may need to allow the kernel to allocate + * more buffer space by increasing: + * /proc/sys/net/core/rmem_max and wmem_max + */ + if (size > 0) { + actual_bufsiz = 0; + sizebufsiz = sizeof(actual_bufsiz); + desired_bufsiz = size * 1024; + if ((getsockopt(so, SOL_SOCKET, SO_RCVBUF, + &actual_bufsiz, &sizebufsiz) < 0) + || (actual_bufsiz < desired_bufsiz)) { + if (setsockopt(so, SOL_SOCKET, SO_RCVBUF, + &desired_bufsiz, sizeof(desired_bufsiz)) < 0) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + } + } + + /* return actual buffer size */ + actual_bufsiz = 0; + sizebufsiz = sizeof(actual_bufsiz); + getsockopt(so, SOL_SOCKET, SO_RCVBUF, + &actual_bufsiz, &sizebufsiz); + return actual_bufsiz / 1024; +} + +/* + * close a socket. + * OUT: + * 0: success. + * -1: fail. + */ +void +pfkey_close(int so) +{ + (void)close(so); + + __ipsec_errcode = EIPSEC_NO_ERROR; + return; +} + +/* + * receive sadb_msg data, and return pointer to new buffer allocated. + * Must free this buffer later. + * OUT: + * NULL : error occured. + * others : a pointer to sadb_msg structure. + * + * XXX should be rewritten to pass length explicitly + */ +struct sadb_msg * +pfkey_recv(int so) +{ + struct sadb_msg buf, *newmsg; + int len, reallen; + + while ((len = recv(so, (void *)&buf, sizeof(buf), MSG_PEEK)) < 0) { + if (errno == EINTR) + continue; + __ipsec_set_strerror(strerror(errno)); + return NULL; + } + + if (len < sizeof(buf)) { + recv(so, (void *)&buf, sizeof(buf), 0); + __ipsec_errcode = EIPSEC_MAX; + return NULL; + } + + /* read real message */ + reallen = PFKEY_UNUNIT64(buf.sadb_msg_len); + if ((newmsg = CALLOC((size_t)reallen, struct sadb_msg *)) == 0) { + __ipsec_set_strerror(strerror(errno)); + return NULL; + } + + while ((len = recv(so, (void *)newmsg, (socklen_t)reallen, 0)) < 0) { + if (errno == EINTR) + continue; + __ipsec_set_strerror(strerror(errno)); + free(newmsg); + return NULL; + } + + if (len != reallen) { + __ipsec_errcode = EIPSEC_SYSTEM_ERROR; + free(newmsg); + return NULL; + } + + /* don't trust what the kernel says, validate! */ + if (PFKEY_UNUNIT64(newmsg->sadb_msg_len) != len) { + __ipsec_errcode = EIPSEC_SYSTEM_ERROR; + free(newmsg); + return NULL; + } + + __ipsec_errcode = EIPSEC_NO_ERROR; + return newmsg; +} + +/* + * send message to a socket. + * OUT: + * others: success and return length sent. + * -1 : fail. + */ +int +pfkey_send(int so, struct sadb_msg *msg, int len) +{ + if ((len = send(so, (void *)msg, (socklen_t)len, 0)) < 0) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + + __ipsec_errcode = EIPSEC_NO_ERROR; + return len; +} + +/* + * %%% Utilities + * NOTE: These functions are derived from netkey/key.c in KAME. + */ +/* + * set the pointer to each header in this message buffer. + * IN: msg: pointer to message buffer. + * mhp: pointer to the buffer initialized like below: + * caddr_t mhp[SADB_EXT_MAX + 1]; + * OUT: -1: invalid. + * 0: valid. + * + * XXX should be rewritten to obtain length explicitly + */ +int +pfkey_align(struct sadb_msg *msg, caddr_t *mhp) +{ + struct sadb_ext *ext; + int i; + caddr_t p; + caddr_t ep; /* XXX should be passed from upper layer */ + + /* validity check */ + if (msg == NULL || mhp == NULL) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + + /* initialize */ + for (i = 0; i < SADB_EXT_MAX + 1; i++) + mhp[i] = NULL; + + mhp[0] = (void *)msg; + + /* initialize */ + p = (void *) msg; + ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len); + + /* skip base header */ + p += sizeof(struct sadb_msg); + + while (p < ep) { + ext = (void *)p; + if (ep < p + sizeof(*ext) || PFKEY_EXTLEN(ext) < sizeof(*ext) || + ep < p + PFKEY_EXTLEN(ext)) { + /* invalid format */ + break; + } + + /* duplicate check */ + /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/ + if (mhp[ext->sadb_ext_type] != NULL) { + __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; + return -1; + } + + /* set pointer */ + switch (ext->sadb_ext_type) { + case SADB_EXT_SA: + case SADB_EXT_LIFETIME_CURRENT: + case SADB_EXT_LIFETIME_HARD: + case SADB_EXT_LIFETIME_SOFT: + case SADB_EXT_ADDRESS_SRC: + case SADB_EXT_ADDRESS_DST: + case SADB_EXT_ADDRESS_PROXY: + case SADB_EXT_KEY_AUTH: + /* XXX should to be check weak keys. */ + case SADB_EXT_KEY_ENCRYPT: + /* XXX should to be check weak keys. */ + case SADB_EXT_IDENTITY_SRC: + case SADB_EXT_IDENTITY_DST: + case SADB_EXT_SENSITIVITY: + case SADB_EXT_PROPOSAL: + case SADB_EXT_SUPPORTED_AUTH: + case SADB_EXT_SUPPORTED_ENCRYPT: + case SADB_EXT_SPIRANGE: + case SADB_X_EXT_POLICY: + case SADB_X_EXT_SA2: +#ifdef SADB_X_EXT_NAT_T_TYPE + case SADB_X_EXT_NAT_T_TYPE: + case SADB_X_EXT_NAT_T_SPORT: + case SADB_X_EXT_NAT_T_DPORT: + case SADB_X_EXT_NAT_T_OA: +#endif +#ifdef SADB_X_EXT_TAG + case SADB_X_EXT_TAG: +#endif +#ifdef SADB_X_EXT_PACKET + case SADB_X_EXT_PACKET: +#endif +#ifdef SADB_X_EXT_KMADDRESS + case SADB_X_EXT_KMADDRESS: +#endif +#ifdef SADB_X_EXT_SEC_CTX + case SADB_X_EXT_SEC_CTX: +#endif + mhp[ext->sadb_ext_type] = (void *)ext; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; + return -1; + } + + p += PFKEY_EXTLEN(ext); + } + + if (p != ep) { + __ipsec_errcode = EIPSEC_INVAL_SADBMSG; + return -1; + } + + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; +} + +/* + * check basic usage for sadb_msg, + * NOTE: This routine is derived from netkey/key.c in KAME. + * IN: msg: pointer to message buffer. + * mhp: pointer to the buffer initialized like below: + * + * caddr_t mhp[SADB_EXT_MAX + 1]; + * + * OUT: -1: invalid. + * 0: valid. + */ +int +pfkey_check(caddr_t *mhp) +{ + struct sadb_msg *msg; + + /* validity check */ + if (mhp == NULL || mhp[0] == NULL) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + + msg = (void *)mhp[0]; + + /* check version */ + if (msg->sadb_msg_version != PF_KEY_V2) { + __ipsec_errcode = EIPSEC_INVAL_VERSION; + return -1; + } + + /* check type */ + if (msg->sadb_msg_type > SADB_MAX) { + __ipsec_errcode = EIPSEC_INVAL_MSGTYPE; + return -1; + } + + /* check SA type */ + switch (msg->sadb_msg_satype) { + case SADB_SATYPE_UNSPEC: + switch (msg->sadb_msg_type) { + case SADB_GETSPI: + case SADB_UPDATE: + case SADB_ADD: + case SADB_DELETE: + case SADB_GET: + case SADB_ACQUIRE: + case SADB_EXPIRE: +#ifdef SADB_X_NAT_T_NEW_MAPPING + case SADB_X_NAT_T_NEW_MAPPING: +#endif + __ipsec_errcode = EIPSEC_INVAL_SATYPE; + return -1; + } + break; + case SADB_SATYPE_ESP: + case SADB_SATYPE_AH: + case SADB_X_SATYPE_IPCOMP: +#ifdef SADB_X_SATYPE_TCPSIGNATURE + case SADB_X_SATYPE_TCPSIGNATURE: +#endif + switch (msg->sadb_msg_type) { + case SADB_X_SPDADD: + case SADB_X_SPDDELETE: + case SADB_X_SPDGET: + case SADB_X_SPDDUMP: + case SADB_X_SPDFLUSH: + __ipsec_errcode = EIPSEC_INVAL_SATYPE; + return -1; + } +#ifdef SADB_X_NAT_T_NEW_MAPPING + if (msg->sadb_msg_type == SADB_X_NAT_T_NEW_MAPPING && + msg->sadb_msg_satype != SADB_SATYPE_ESP) { + __ipsec_errcode = EIPSEC_INVAL_SATYPE; + return -1; + } +#endif + break; + case SADB_SATYPE_RSVP: + case SADB_SATYPE_OSPFV2: + case SADB_SATYPE_RIPV2: + case SADB_SATYPE_MIP: + __ipsec_errcode = EIPSEC_NOT_SUPPORTED; + return -1; + case 1: /* XXX: What does it do ? */ + if (msg->sadb_msg_type == SADB_X_PROMISC) + break; + /*FALLTHROUGH*/ + default: +#ifdef __linux__ + /* Linux kernel seems to be buggy and return + * uninitialized satype for spd flush message */ + if (msg->sadb_msg_type == SADB_X_SPDFLUSH) + break; +#endif + __ipsec_errcode = EIPSEC_INVAL_SATYPE; + return -1; + } + + /* check field of upper layer protocol and address family */ + if (mhp[SADB_EXT_ADDRESS_SRC] != NULL + && mhp[SADB_EXT_ADDRESS_DST] != NULL) { + struct sadb_address *src0, *dst0; + + src0 = (void *)(mhp[SADB_EXT_ADDRESS_SRC]); + dst0 = (void *)(mhp[SADB_EXT_ADDRESS_DST]); + + if (src0->sadb_address_proto != dst0->sadb_address_proto) { + __ipsec_errcode = EIPSEC_PROTO_MISMATCH; + return -1; + } + + if (PFKEY_ADDR_SADDR(src0)->sa_family + != PFKEY_ADDR_SADDR(dst0)->sa_family) { + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + return -1; + } + + switch (PFKEY_ADDR_SADDR(src0)->sa_family) { + case AF_INET: + case AF_INET6: + break; + default: + __ipsec_errcode = EIPSEC_INVAL_FAMILY; + return -1; + } + + /* + * prefixlen == 0 is valid because there must be the case + * all addresses are matched. + */ + } + + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; +} + +/* + * set data into sadb_msg. + * `buf' must has been allocated sufficiently. + */ +static caddr_t +pfkey_setsadbmsg(caddr_t buf, caddr_t lim, u_int type, u_int tlen, + u_int satype, u_int32_t seq, pid_t pid) +{ + struct sadb_msg *p; + u_int len; + + p = (void *)buf; + len = sizeof(struct sadb_msg); + + if (buf + len > lim) + return NULL; + + memset(p, 0, len); + p->sadb_msg_version = PF_KEY_V2; + p->sadb_msg_type = type; + p->sadb_msg_errno = 0; + p->sadb_msg_satype = satype; + p->sadb_msg_len = PFKEY_UNIT64(tlen); + p->sadb_msg_reserved = 0; + p->sadb_msg_seq = seq; + p->sadb_msg_pid = (u_int32_t)pid; + + return(buf + len); +} + +/* + * copy secasvar data into sadb_address. + * `buf' must has been allocated sufficiently. + */ +static caddr_t +pfkey_setsadbsa(caddr_t buf, caddr_t lim, u_int32_t spi, u_int wsize, + u_int auth, u_int enc, u_int32_t flags) +{ + struct sadb_sa *p; + u_int len; + + p = (void *)buf; + len = sizeof(struct sadb_sa); + + if (buf + len > lim) + return NULL; + + memset(p, 0, len); + p->sadb_sa_len = PFKEY_UNIT64(len); + p->sadb_sa_exttype = SADB_EXT_SA; + p->sadb_sa_spi = spi; + p->sadb_sa_replay = wsize; + p->sadb_sa_state = SADB_SASTATE_LARVAL; + p->sadb_sa_auth = auth; + p->sadb_sa_encrypt = enc; + p->sadb_sa_flags = flags; + + return(buf + len); +} + +/* + * set data into sadb_address. + * `buf' must has been allocated sufficiently. + * prefixlen is in bits. + */ +static caddr_t +pfkey_setsadbaddr(caddr_t buf, caddr_t lim, u_int exttype, + struct sockaddr *saddr, u_int prefixlen, u_int ul_proto) +{ + struct sadb_address *p; + u_int len; + + p = (void *)buf; + len = sizeof(struct sadb_address) + PFKEY_ALIGN8(sysdep_sa_len(saddr)); + + if (buf + len > lim) + return NULL; + + memset(p, 0, len); + p->sadb_address_len = PFKEY_UNIT64(len); + p->sadb_address_exttype = exttype & 0xffff; + p->sadb_address_proto = ul_proto & 0xff; + p->sadb_address_prefixlen = prefixlen; + p->sadb_address_reserved = 0; + + memcpy(p + 1, saddr, (size_t)sysdep_sa_len(saddr)); + + return(buf + len); +} + +#ifdef SADB_X_EXT_KMADDRESS +/* + * set data into sadb_x_kmaddress. + * `buf' must has been allocated sufficiently. + */ +static caddr_t +pfkey_setsadbkmaddr(caddr_t buf, caddr_t lim, struct sockaddr *local, + struct sockaddr *remote) +{ + struct sadb_x_kmaddress *p; + struct sockaddr *sa; + u_int salen = sysdep_sa_len(local); + u_int len; + + /* sanity check */ + if (local->sa_family != remote->sa_family) + return NULL; + + p = (void *)buf; + len = sizeof(struct sadb_x_kmaddress) + PFKEY_ALIGN8(2*salen); + + if (buf + len > lim) + return NULL; + + memset(p, 0, len); + p->sadb_x_kmaddress_len = PFKEY_UNIT64(len); + p->sadb_x_kmaddress_exttype = SADB_X_EXT_KMADDRESS; + p->sadb_x_kmaddress_reserved = 0; + sa = (struct sockaddr *)(p + 1); + memcpy(sa, local, salen); + sa = (struct sockaddr *)((char *)sa + salen); + memcpy(sa, remote, salen); + + return(buf + len); +} +#endif + +/* + * set sadb_key structure after clearing buffer with zero. + * OUT: the pointer of buf + len. + */ +static caddr_t +pfkey_setsadbkey(caddr_t buf, caddr_t lim, u_int type, caddr_t key, + u_int keylen) +{ + struct sadb_key *p; + u_int len; + + p = (void *)buf; + len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); + + if (buf + len > lim) + return NULL; + + memset(p, 0, len); + p->sadb_key_len = PFKEY_UNIT64(len); + p->sadb_key_exttype = type; + p->sadb_key_bits = keylen << 3; + p->sadb_key_reserved = 0; + + memcpy(p + 1, key, keylen); + + return buf + len; +} + +/* + * set sadb_lifetime structure after clearing buffer with zero. + * OUT: the pointer of buf + len. + */ +static caddr_t +pfkey_setsadblifetime(caddr_t buf, caddr_t lim, u_int type, u_int32_t l_alloc, + u_int32_t l_bytes, u_int32_t l_addtime, u_int32_t l_usetime) +{ + struct sadb_lifetime *p; + u_int len; + + p = (void *)buf; + len = sizeof(struct sadb_lifetime); + + if (buf + len > lim) + return NULL; + + memset(p, 0, len); + p->sadb_lifetime_len = PFKEY_UNIT64(len); + p->sadb_lifetime_exttype = type; + + switch (type) { + case SADB_EXT_LIFETIME_SOFT: + p->sadb_lifetime_allocations + = (l_alloc * soft_lifetime_allocations_rate) /100; + p->sadb_lifetime_bytes + = (l_bytes * soft_lifetime_bytes_rate) /100; + p->sadb_lifetime_addtime + = (l_addtime * soft_lifetime_addtime_rate) /100; + p->sadb_lifetime_usetime + = (l_usetime * soft_lifetime_usetime_rate) /100; + break; + case SADB_EXT_LIFETIME_HARD: + p->sadb_lifetime_allocations = l_alloc; + p->sadb_lifetime_bytes = l_bytes; + p->sadb_lifetime_addtime = l_addtime; + p->sadb_lifetime_usetime = l_usetime; + break; + } + + return buf + len; +} + +/* + * copy secasvar data into sadb_address. + * `buf' must has been allocated sufficiently. + */ +static caddr_t +pfkey_setsadbxsa2(caddr_t buf, caddr_t lim, u_int32_t mode0, u_int32_t reqid) +{ + struct sadb_x_sa2 *p; + u_int8_t mode = mode0 & 0xff; + u_int len; + + p = (void *)buf; + len = sizeof(struct sadb_x_sa2); + + if (buf + len > lim) + return NULL; + + memset(p, 0, len); + p->sadb_x_sa2_len = PFKEY_UNIT64(len); + p->sadb_x_sa2_exttype = SADB_X_EXT_SA2; + p->sadb_x_sa2_mode = mode; + p->sadb_x_sa2_reqid = reqid; + + return(buf + len); +} + +#ifdef SADB_X_EXT_NAT_T_TYPE +static caddr_t +pfkey_set_natt_type(caddr_t buf, caddr_t lim, u_int type, u_int8_t l_natt_type) +{ + struct sadb_x_nat_t_type *p; + u_int len; + + p = (void *)buf; + len = sizeof(struct sadb_x_nat_t_type); + + if (buf + len > lim) + return NULL; + + memset(p, 0, len); + p->sadb_x_nat_t_type_len = PFKEY_UNIT64(len); + p->sadb_x_nat_t_type_exttype = type; + p->sadb_x_nat_t_type_type = l_natt_type; + + return(buf + len); +} + +static caddr_t +pfkey_set_natt_port(caddr_t buf, caddr_t lim, u_int type, u_int16_t l_natt_port) +{ + struct sadb_x_nat_t_port *p; + u_int len; + + p = (void *)buf; + len = sizeof(struct sadb_x_nat_t_port); + + if (buf + len > lim) + return NULL; + + memset(p, 0, len); + p->sadb_x_nat_t_port_len = PFKEY_UNIT64(len); + p->sadb_x_nat_t_port_exttype = type; + p->sadb_x_nat_t_port_port = htons(l_natt_port); + + return(buf + len); +} +#endif + +#ifdef SADB_X_EXT_NAT_T_FRAG +static caddr_t +pfkey_set_natt_frag(caddr_t buf, caddr_t lim, u_int type, + u_int16_t l_natt_frag) +{ + struct sadb_x_nat_t_frag *p; + u_int len; + + p = (void *)buf; + len = sizeof(struct sadb_x_nat_t_frag); + + if (buf + len > lim) + return NULL; + + memset(p, 0, len); + p->sadb_x_nat_t_frag_len = PFKEY_UNIT64(len); + p->sadb_x_nat_t_frag_exttype = type; + p->sadb_x_nat_t_frag_fraglen = l_natt_frag; + + return(buf + len); +} +#endif + +#ifdef SADB_X_EXT_SEC_CTX +static caddr_t +pfkey_setsecctx(caddr_t buf, caddr_t lim, u_int type, u_int8_t ctx_doi, + u_int8_t ctx_alg, caddr_t sec_ctx, u_int16_t sec_ctxlen) +{ + struct sadb_x_sec_ctx *p; + u_int len; + + p = (struct sadb_x_sec_ctx *)buf; + len = sizeof(struct sadb_x_sec_ctx) + PFKEY_ALIGN8(sec_ctxlen); + + if (buf + len > lim) + return NULL; + + memset(p, 0, len); + p->sadb_x_sec_len = PFKEY_UNIT64(len); + p->sadb_x_sec_exttype = type; + p->sadb_x_ctx_len = sec_ctxlen; + p->sadb_x_ctx_doi = ctx_doi; + p->sadb_x_ctx_alg = ctx_alg; + + memcpy(p + 1, sec_ctx, sec_ctxlen); + + return buf + len; +} +#endif + +/* + * Deprecated, available for backward compatibility with third party + * libipsec users. Please use pfkey_send_update2 and pfkey_send_add2 instead + */ +int +pfkey_send_update(int so, u_int satype, u_int mode, struct sockaddr *src, + struct sockaddr *dst, u_int32_t spi, u_int32_t reqid, u_int wsize, + caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type, + u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes, + u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq) +{ + struct pfkey_send_sa_args psaa; + + memset(&psaa, 0, sizeof(psaa)); + psaa.so = so; + psaa.type = SADB_UPDATE; + psaa.satype = satype; + psaa.mode = mode; + psaa.wsize = wsize; + psaa.src = src; + psaa.dst = dst; + psaa.spi = spi; + psaa.reqid = reqid; + psaa.keymat = keymat; + psaa.e_type = e_type; + psaa.e_keylen = e_keylen; + psaa.a_type = a_type; + psaa.a_keylen = a_keylen; + psaa.flags = flags; + psaa.l_alloc = l_alloc; + psaa.l_bytes = l_bytes; + psaa.l_addtime = l_addtime; + psaa.l_usetime = l_usetime; + psaa.seq = seq; + + return pfkey_send_update2(&psaa); +} + +int +pfkey_send_update_nat(int so, u_int satype, u_int mode, struct sockaddr *src, + struct sockaddr *dst, u_int32_t spi, u_int32_t reqid, u_int wsize, + caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type, + u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes, + u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq, + u_int8_t l_natt_type, u_int16_t l_natt_sport, u_int16_t l_natt_dport, + struct sockaddr *l_natt_oa, u_int16_t l_natt_frag) +{ + struct pfkey_send_sa_args psaa; + + memset(&psaa, 0, sizeof(psaa)); + psaa.so = so; + psaa.type = SADB_UPDATE; + psaa.satype = satype; + psaa.mode = mode; + psaa.wsize = wsize; + psaa.src = src; + psaa.dst = dst; + psaa.spi = spi; + psaa.reqid = reqid; + psaa.keymat = keymat; + psaa.e_type = e_type; + psaa.e_keylen = e_keylen; + psaa.a_type = a_type; + psaa.a_keylen = a_keylen; + psaa.flags = flags; + psaa.l_alloc = l_alloc; + psaa.l_bytes = l_bytes; + psaa.l_addtime = l_addtime; + psaa.l_usetime = l_usetime; + psaa.seq = seq; + psaa.l_natt_type = l_natt_type; + psaa.l_natt_sport = l_natt_sport; + psaa.l_natt_dport = l_natt_dport; + psaa.l_natt_oa = l_natt_oa; + psaa.l_natt_frag = l_natt_frag; + + return pfkey_send_update2(&psaa); +} + +int +pfkey_send_add(int so, u_int satype, u_int mode, struct sockaddr *src, + struct sockaddr *dst, u_int32_t spi, u_int32_t reqid, u_int wsize, + caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type, + u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes, + u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq) +{ + struct pfkey_send_sa_args psaa; + + memset(&psaa, 0, sizeof(psaa)); + psaa.so = so; + psaa.type = SADB_ADD; + psaa.satype = satype; + psaa.mode = mode; + psaa.wsize = wsize; + psaa.src = src; + psaa.dst = dst; + psaa.spi = spi; + psaa.reqid = reqid; + psaa.keymat = keymat; + psaa.e_type = e_type; + psaa.e_keylen = e_keylen; + psaa.a_type = a_type; + psaa.a_keylen = a_keylen; + psaa.flags = flags; + psaa.l_alloc = l_alloc; + psaa.l_bytes = l_bytes; + psaa.l_addtime = l_addtime; + psaa.l_usetime = l_usetime; + psaa.seq = seq; + + return pfkey_send_add2(&psaa); +} + +int +pfkey_send_add_nat(int so, u_int satype, u_int mode, struct sockaddr *src, + struct sockaddr *dst, u_int32_t spi, u_int32_t reqid, u_int wsize, + caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type, + u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes, + u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq, + u_int8_t l_natt_type, u_int16_t l_natt_sport, u_int16_t l_natt_dport, + struct sockaddr *l_natt_oa, u_int16_t l_natt_frag) +{ + struct pfkey_send_sa_args psaa; + + memset(&psaa, 0, sizeof(psaa)); + psaa.so = so; + psaa.type = SADB_ADD; + psaa.satype = satype; + psaa.mode = mode; + psaa.wsize = wsize; + psaa.src = src; + psaa.dst = dst; + psaa.spi = spi; + psaa.reqid = reqid; + psaa.keymat = keymat; + psaa.e_type = e_type; + psaa.e_keylen = e_keylen; + psaa.a_type = a_type; + psaa.a_keylen = a_keylen; + psaa.flags = flags; + psaa.l_alloc = l_alloc; + psaa.l_bytes = l_bytes; + psaa.l_addtime = l_addtime; + psaa.l_usetime = l_usetime; + psaa.seq = seq; + psaa.l_natt_type = l_natt_type; + psaa.l_natt_sport = l_natt_sport; + psaa.l_natt_dport = l_natt_dport; + psaa.l_natt_oa = l_natt_oa; + psaa.l_natt_frag = l_natt_frag; + + return pfkey_send_add2(&psaa); +} diff --git a/ipsec-tools/src/libipsec/pfkey_dump.c b/ipsec-tools/src/libipsec/pfkey_dump.c new file mode 100644 index 00000000..4627ebc8 --- /dev/null +++ b/ipsec-tools/src/libipsec/pfkey_dump.c @@ -0,0 +1,825 @@ +/* $NetBSD: pfkey_dump.c,v 1.18 2010/12/03 14:32:52 tteras Exp $ */ + +/* $KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include PATH_IPSEC_H +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ipsec_strerror.h" +#include "libpfkey.h" + +/* cope with old kame headers - ugly */ +#ifndef SADB_X_AALG_MD5 +#define SADB_X_AALG_MD5 SADB_AALG_MD5 +#endif +#ifndef SADB_X_AALG_SHA +#define SADB_X_AALG_SHA SADB_AALG_SHA +#endif +#ifndef SADB_X_AALG_NULL +#define SADB_X_AALG_NULL SADB_AALG_NULL +#endif + +#ifndef SADB_X_EALG_BLOWFISHCBC +#define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC +#endif +#ifndef SADB_X_EALG_CAST128CBC +#define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC +#endif +#ifndef SADB_X_EALG_RC5CBC +#ifdef SADB_EALG_RC5CBC +#define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC +#endif +#endif +#if defined(SADB_X_EALG_AES) && ! defined(SADB_X_EALG_AESCBC) +#define SADB_X_EALG_AESCBC SADB_X_EALG_AES +#endif + +#define GETMSGSTR(str, num) \ +do { \ + /*CONSTCOND*/ \ + if (sizeof((str)[0]) == 0 \ + || num >= sizeof(str)/sizeof((str)[0])) \ + printf("%u ", (num)); \ + else if (strlen((str)[(num)]) == 0) \ + printf("%u ", (num)); \ + else \ + printf("%s ", (str)[(num)]); \ +} while (/*CONSTCOND*/0) + +#define GETMSGV2S(v2s, num) \ +do { \ + struct val2str *p; \ + for (p = (v2s); p && p->str; p++) { \ + if (p->val == (num)) \ + break; \ + } \ + if (p && p->str) \ + printf("%s ", p->str); \ + else \ + printf("%u ", (num)); \ +} while (/*CONSTCOND*/0) + +static char *str_ipaddr __P((struct sockaddr *)); +static char *str_ipport __P((struct sockaddr *)); +static char *str_prefport __P((u_int, u_int, u_int, u_int)); +static void str_upperspec __P((u_int, u_int, u_int)); +static char *str_time __P((time_t)); +static void str_lifetime_byte __P((struct sadb_lifetime *, char *)); +static void pfkey_sadump1(struct sadb_msg *, int); +static void pfkey_spdump1(struct sadb_msg *, int); + +struct val2str { + int val; + const char *str; +}; + +/* + * Must to be re-written about following strings. + */ +static char *str_satype[] = { + "unspec", + "unknown", + "ah", + "esp", + "unknown", + "rsvp", + "ospfv2", + "ripv2", + "mip", + "ipcomp", + "policy", + "tcp", +}; + +static char *str_mode[] = { + "any", + "transport", + "tunnel", +}; + +static char *str_state[] = { + "larval", + "mature", + "dying", + "dead", +}; + +static struct val2str str_alg_auth[] = { + { SADB_AALG_NONE, "none", }, + { SADB_AALG_MD5HMAC, "hmac-md5", }, + { SADB_AALG_SHA1HMAC, "hmac-sha1", }, + { SADB_X_AALG_MD5, "md5", }, + { SADB_X_AALG_SHA, "sha", }, + { SADB_X_AALG_NULL, "null", }, +#ifdef SADB_X_AALG_TCP_MD5 + { SADB_X_AALG_TCP_MD5, "tcp-md5", }, +#endif +#ifdef SADB_X_AALG_SHA2_256 + { SADB_X_AALG_SHA2_256, "hmac-sha256", }, +#endif +#ifdef SADB_X_AALG_SHA2_384 + { SADB_X_AALG_SHA2_384, "hmac-sha384", }, +#endif +#ifdef SADB_X_AALG_SHA2_512 + { SADB_X_AALG_SHA2_512, "hmac-sha512", }, +#endif +#ifdef SADB_X_AALG_RIPEMD160HMAC + { SADB_X_AALG_RIPEMD160HMAC, "hmac-ripemd160", }, +#endif +#ifdef SADB_X_AALG_AES_XCBC_MAC + { SADB_X_AALG_AES_XCBC_MAC, "aes-xcbc-mac", }, +#endif + { -1, NULL, }, +}; + +static struct val2str str_alg_enc[] = { + { SADB_EALG_NONE, "none", }, + { SADB_EALG_DESCBC, "des-cbc", }, + { SADB_EALG_3DESCBC, "3des-cbc", }, + { SADB_EALG_NULL, "null", }, +#ifdef SADB_X_EALG_RC5CBC + { SADB_X_EALG_RC5CBC, "rc5-cbc", }, +#endif + { SADB_X_EALG_CAST128CBC, "cast128-cbc", }, + { SADB_X_EALG_BLOWFISHCBC, "blowfish-cbc", }, +#ifdef SADB_X_EALG_AESCBC + { SADB_X_EALG_AESCBC, "aes-cbc", }, +#endif +#ifdef SADB_X_EALG_TWOFISHCBC + { SADB_X_EALG_TWOFISHCBC, "twofish-cbc", }, +#endif +#ifdef SADB_X_EALG_AESCTR + { SADB_X_EALG_AESCTR, "aes-ctr", }, +#endif +#ifdef SADB_X_EALG_CAMELLIACBC + { SADB_X_EALG_CAMELLIACBC, "camellia-cbc", }, +#endif + { -1, NULL, }, +}; + +static struct val2str str_alg_comp[] = { + { SADB_X_CALG_NONE, "none", }, + { SADB_X_CALG_OUI, "oui", }, + { SADB_X_CALG_DEFLATE, "deflate", }, + { SADB_X_CALG_LZS, "lzs", }, + { -1, NULL, }, +}; + +/* + * dump SADB_MSG formated. For debugging, you should use kdebug_sadb(). + */ + +void +pfkey_sadump(m) + struct sadb_msg *m; +{ + pfkey_sadump1(m, 0); +} + +void +pfkey_sadump_withports(m) + struct sadb_msg *m; +{ + pfkey_sadump1(m, 1); +} + +void +pfkey_sadump1(m, withports) + struct sadb_msg *m; + int withports; +{ + caddr_t mhp[SADB_EXT_MAX + 1]; + struct sadb_sa *m_sa; + struct sadb_x_sa2 *m_sa2; + struct sadb_lifetime *m_lftc, *m_lfth, *m_lfts; + struct sadb_address *m_saddr, *m_daddr; +#ifdef notdef + struct sadb_address *m_paddr; +#endif + struct sadb_key *m_auth, *m_enc; +#ifdef notdef + struct sadb_ident *m_sid, *m_did; + struct sadb_sens *m_sens; +#endif +#ifdef SADB_X_EXT_SEC_CTX + struct sadb_x_sec_ctx *m_sec_ctx; +#endif +#ifdef SADB_X_EXT_NAT_T_TYPE + struct sadb_x_nat_t_type *natt_type; + struct sadb_x_nat_t_port *natt_sport, *natt_dport; + struct sadb_address *natt_oa; + + int use_natt = 0; +#endif + struct sockaddr *sa; + + /* check pfkey message. */ + if (pfkey_align(m, mhp)) { + printf("%s\n", ipsec_strerror()); + return; + } + if (pfkey_check(mhp)) { + printf("%s\n", ipsec_strerror()); + return; + } + + m_sa = (void *)mhp[SADB_EXT_SA]; + m_sa2 = (void *)mhp[SADB_X_EXT_SA2]; + m_lftc = (void *)mhp[SADB_EXT_LIFETIME_CURRENT]; + m_lfth = (void *)mhp[SADB_EXT_LIFETIME_HARD]; + m_lfts = (void *)mhp[SADB_EXT_LIFETIME_SOFT]; + m_saddr = (void *)mhp[SADB_EXT_ADDRESS_SRC]; + m_daddr = (void *)mhp[SADB_EXT_ADDRESS_DST]; +#ifdef notdef + m_paddr = (void *)mhp[SADB_EXT_ADDRESS_PROXY]; +#endif + m_auth = (void *)mhp[SADB_EXT_KEY_AUTH]; + m_enc = (void *)mhp[SADB_EXT_KEY_ENCRYPT]; +#ifdef notdef + m_sid = (void *)mhp[SADB_EXT_IDENTITY_SRC]; + m_did = (void *)mhp[SADB_EXT_IDENTITY_DST]; + m_sens = (void *)mhp[SADB_EXT_SENSITIVITY]; +#endif +#ifdef SADB_X_EXT_SEC_CTX + m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; +#endif +#ifdef SADB_X_EXT_NAT_T_TYPE + natt_type = (void *)mhp[SADB_X_EXT_NAT_T_TYPE]; + natt_sport = (void *)mhp[SADB_X_EXT_NAT_T_SPORT]; + natt_dport = (void *)mhp[SADB_X_EXT_NAT_T_DPORT]; + natt_oa = (void *)mhp[SADB_X_EXT_NAT_T_OA]; + + if (natt_type && natt_type->sadb_x_nat_t_type_type) + use_natt = 1; +#endif + /* source address */ + if (m_saddr == NULL) { + printf("no ADDRESS_SRC extension.\n"); + return; + } + sa = (void *)(m_saddr + 1); + if (withports) + printf("%s[%s]", str_ipaddr(sa), str_ipport(sa)); + else + printf("%s", str_ipaddr(sa)); +#ifdef SADB_X_EXT_NAT_T_TYPE + if (use_natt && natt_sport) + printf("[%u]", ntohs(natt_sport->sadb_x_nat_t_port_port)); +#endif + printf(" "); + + /* destination address */ + if (m_daddr == NULL) { + printf(" no ADDRESS_DST extension.\n"); + return; + } + sa = (void *)(m_daddr + 1); + if (withports) + printf("%s[%s]", str_ipaddr(sa), str_ipport(sa)); + else + printf("%s", str_ipaddr(sa)); +#ifdef SADB_X_EXT_NAT_T_TYPE + if (use_natt && natt_dport) + printf("[%u]", ntohs(natt_dport->sadb_x_nat_t_port_port)); +#endif + printf(" "); + + /* SA type */ + if (m_sa == NULL) { + printf("no SA extension.\n"); + return; + } + if (m_sa2 == NULL) { + printf("no SA2 extension.\n"); + return; + } + printf("\n\t"); + +#ifdef SADB_X_EXT_NAT_T_TYPE + if (use_natt && m->sadb_msg_satype == SADB_SATYPE_ESP) + printf("esp-udp "); + else if (use_natt) + printf("natt+"); + + if (!use_natt || m->sadb_msg_satype != SADB_SATYPE_ESP) +#endif + GETMSGSTR(str_satype, m->sadb_msg_satype); + + printf("mode="); + GETMSGSTR(str_mode, m_sa2->sadb_x_sa2_mode); + + printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n", + (u_int32_t)ntohl(m_sa->sadb_sa_spi), + (u_int32_t)ntohl(m_sa->sadb_sa_spi), + (u_int32_t)m_sa2->sadb_x_sa2_reqid, + (u_int32_t)m_sa2->sadb_x_sa2_reqid); + +#ifdef SADB_X_EXT_NAT_T_TYPE + /* other NAT-T information */ + if (use_natt && natt_oa) + printf("\tNAT OA=%s\n", + str_ipaddr((void *)(natt_oa + 1))); +#endif + + /* encryption key */ + if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) { + printf("\tC: "); + GETMSGV2S(str_alg_comp, m_sa->sadb_sa_encrypt); + } else if (m->sadb_msg_satype == SADB_SATYPE_ESP) { + if (m_enc != NULL) { + printf("\tE: "); + GETMSGV2S(str_alg_enc, m_sa->sadb_sa_encrypt); + ipsec_hexdump((caddr_t)(void *)m_enc + sizeof(*m_enc), + m_enc->sadb_key_bits / 8); + printf("\n"); + } + } + + /* authentication key */ + if (m_auth != NULL) { + printf("\tA: "); + GETMSGV2S(str_alg_auth, m_sa->sadb_sa_auth); + ipsec_hexdump((caddr_t)(void *)m_auth + sizeof(*m_auth), + m_auth->sadb_key_bits / 8); + printf("\n"); + } + + /* replay windoe size & flags */ + printf("\tseq=0x%08x replay=%u flags=0x%08x ", + m_sa2->sadb_x_sa2_sequence, + m_sa->sadb_sa_replay, + m_sa->sadb_sa_flags); + + /* state */ + printf("state="); + GETMSGSTR(str_state, m_sa->sadb_sa_state); + printf("\n"); + + /* lifetime */ + if (m_lftc != NULL) { + time_t tmp_time = time(0); + + printf("\tcreated: %s", + str_time((long)m_lftc->sadb_lifetime_addtime)); + printf("\tcurrent: %s\n", str_time(tmp_time)); + printf("\tdiff: %lu(s)", + (u_long)(m_lftc->sadb_lifetime_addtime == 0 ? + 0 : (tmp_time - m_lftc->sadb_lifetime_addtime))); + + printf("\thard: %lu(s)", + (u_long)(m_lfth == NULL ? + 0 : m_lfth->sadb_lifetime_addtime)); + printf("\tsoft: %lu(s)\n", + (u_long)(m_lfts == NULL ? + 0 : m_lfts->sadb_lifetime_addtime)); + + printf("\tlast: %s", + str_time((long)m_lftc->sadb_lifetime_usetime)); + printf("\thard: %lu(s)", + (u_long)(m_lfth == NULL ? + 0 : m_lfth->sadb_lifetime_usetime)); + printf("\tsoft: %lu(s)\n", + (u_long)(m_lfts == NULL ? + 0 : m_lfts->sadb_lifetime_usetime)); + + str_lifetime_byte(m_lftc, "current"); + str_lifetime_byte(m_lfth, "hard"); + str_lifetime_byte(m_lfts, "soft"); + printf("\n"); + + printf("\tallocated: %lu", + (unsigned long)m_lftc->sadb_lifetime_allocations); + printf("\thard: %lu", + (u_long)(m_lfth == NULL ? + 0 : m_lfth->sadb_lifetime_allocations)); + printf("\tsoft: %lu\n", + (u_long)(m_lfts == NULL ? + 0 : m_lfts->sadb_lifetime_allocations)); + } + +#ifdef SADB_X_EXT_SEC_CTX + if (m_sec_ctx != NULL) { + printf("\tsecurity context doi: %u\n", + m_sec_ctx->sadb_x_ctx_doi); + printf("\tsecurity context algorithm: %u\n", + m_sec_ctx->sadb_x_ctx_alg); + printf("\tsecurity context length: %u\n", + m_sec_ctx->sadb_x_ctx_len); + printf("\tsecurity context: %s\n", + (char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)); + } +#endif + + printf("\tsadb_seq=%lu pid=%lu ", + (u_long)m->sadb_msg_seq, + (u_long)m->sadb_msg_pid); + + /* XXX DEBUG */ + printf("refcnt=%u\n", m->sadb_msg_reserved); + + return; +} + +void +pfkey_spdump(m) + struct sadb_msg *m; +{ + pfkey_spdump1(m, 0); +} + +void +pfkey_spdump_withports(m) + struct sadb_msg *m; +{ + pfkey_spdump1(m, 1); +} + +static void +pfkey_spdump1(m, withports) + struct sadb_msg *m; + int withports; +{ + char pbuf[NI_MAXSERV]; + caddr_t mhp[SADB_EXT_MAX + 1]; + struct sadb_address *m_saddr, *m_daddr; +#ifdef SADB_X_EXT_TAG + struct sadb_x_tag *m_tag; +#endif + struct sadb_x_policy *m_xpl; + struct sadb_lifetime *m_lftc = NULL, *m_lfth = NULL; +#ifdef SADB_X_EXT_SEC_CTX + struct sadb_x_sec_ctx *m_sec_ctx; +#endif + struct sockaddr *sa; + u_int16_t sport = 0, dport = 0; + + /* check pfkey message. */ + if (pfkey_align(m, mhp)) { + printf("%s\n", ipsec_strerror()); + return; + } + if (pfkey_check(mhp)) { + printf("%s\n", ipsec_strerror()); + return; + } + + m_saddr = (void *)mhp[SADB_EXT_ADDRESS_SRC]; + m_daddr = (void *)mhp[SADB_EXT_ADDRESS_DST]; +#ifdef SADB_X_EXT_TAG + m_tag = (void *)mhp[SADB_X_EXT_TAG]; +#endif + m_xpl = (void *)mhp[SADB_X_EXT_POLICY]; + m_lftc = (void *)mhp[SADB_EXT_LIFETIME_CURRENT]; + m_lfth = (void *)mhp[SADB_EXT_LIFETIME_HARD]; + +#ifdef SADB_X_EXT_SEC_CTX + m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; +#endif +#ifdef __linux__ + /* *bsd indicates per-socket policies by omiting src and dst + * extensions. Linux always includes them, but we can catch it + * by checkin for policy id. + */ + if (m_xpl->sadb_x_policy_id % 8 >= 3) { + printf("(per-socket policy) "); + } else +#endif + if (m_saddr && m_daddr) { + /* source address */ + sa = (void *)(m_saddr + 1); + switch (sa->sa_family) { + case AF_INET: + case AF_INET6: + if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), NULL, + 0, pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0) + sport = 0; /*XXX*/ + else + sport = atoi(pbuf); + printf("%s%s ", str_ipaddr(sa), + str_prefport((u_int)sa->sa_family, + (u_int)m_saddr->sadb_address_prefixlen, + (u_int)sport, + (u_int)m_saddr->sadb_address_proto)); + break; + default: + printf("unknown-af "); + break; + } + + /* destination address */ + sa = (void *)(m_daddr + 1); + switch (sa->sa_family) { + case AF_INET: + case AF_INET6: + if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), NULL, + 0, pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0) + dport = 0; /*XXX*/ + else + dport = atoi(pbuf); + printf("%s%s ", str_ipaddr(sa), + str_prefport((u_int)sa->sa_family, + (u_int)m_daddr->sadb_address_prefixlen, + (u_int)dport, + (u_int)m_saddr->sadb_address_proto)); + break; + default: + printf("unknown-af "); + break; + } + + /* upper layer protocol */ + if (m_saddr->sadb_address_proto != + m_daddr->sadb_address_proto) { + printf("upper layer protocol mismatched.\n"); + return; + } + str_upperspec((u_int)m_saddr->sadb_address_proto, (u_int)sport, + (u_int)dport); + } +#ifdef SADB_X_EXT_TAG + else if (m_tag) + printf("tagged \"%s\" ", m_tag->sadb_x_tag_name); +#endif + else + printf("(no selector, probably per-socket policy) "); + + /* policy */ + { + char *d_xpl; + + if (m_xpl == NULL) { + printf("no X_POLICY extension.\n"); + return; + } + if (withports) + d_xpl = ipsec_dump_policy_withports(m_xpl, "\n\t"); + else + d_xpl = ipsec_dump_policy((ipsec_policy_t)m_xpl, "\n\t"); + + if (!d_xpl) + printf("\n\tPolicy:[%s]\n", ipsec_strerror()); + else { + /* dump SPD */ + printf("\n\t%s\n", d_xpl); + free(d_xpl); + } + } + + /* lifetime */ + if (m_lftc) { + printf("\tcreated: %s ", + str_time((long)m_lftc->sadb_lifetime_addtime)); + printf("lastused: %s\n", + str_time((long)m_lftc->sadb_lifetime_usetime)); + } + if (m_lfth) { + printf("\tlifetime: %lu(s) ", + (u_long)m_lfth->sadb_lifetime_addtime); + printf("validtime: %lu(s)\n", + (u_long)m_lfth->sadb_lifetime_usetime); + } + +#ifdef SADB_X_EXT_SEC_CTX + if (m_sec_ctx != NULL) { + printf("\tsecurity context doi: %u\n", + m_sec_ctx->sadb_x_ctx_doi); + printf("\tsecurity context algorithm: %u\n", + m_sec_ctx->sadb_x_ctx_alg); + printf("\tsecurity context length: %u\n", + m_sec_ctx->sadb_x_ctx_len); + printf("\tsecurity context: %s\n", + (char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)); + } +#endif + + printf("\tspid=%ld seq=%ld pid=%ld\n", + (u_long)m_xpl->sadb_x_policy_id, + (u_long)m->sadb_msg_seq, + (u_long)m->sadb_msg_pid); + + /* XXX TEST */ + printf("\trefcnt=%u\n", m->sadb_msg_reserved); + + return; +} + +/* + * set "ipaddress" to buffer. + */ +static char * +str_ipaddr(sa) + struct sockaddr *sa; +{ + static char buf[NI_MAXHOST]; + const int niflag = NI_NUMERICHOST; + + if (sa == NULL) + return ""; + + if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), buf, sizeof(buf), + NULL, 0, niflag) == 0) + return buf; + return NULL; +} + +/* + * set "port" to buffer. + */ +static char * +str_ipport(sa) + struct sockaddr *sa; +{ + static char buf[NI_MAXHOST]; + const int niflag = NI_NUMERICSERV; + + if (sa == NULL) + return ""; + + if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), NULL, 0, + buf, sizeof(buf), niflag) == 0) + return buf; + return NULL; +} + + +/* + * set "/prefix[port number]" to buffer. + */ +static char * +str_prefport(family, pref, port, ulp) + u_int family, pref, port, ulp; +{ + static char buf[128]; + char prefbuf[128]; + char portbuf[128]; + int plen; + + switch (family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + return "?"; + } + + if (pref == plen) + prefbuf[0] = '\0'; + else + snprintf(prefbuf, sizeof(prefbuf), "/%u", pref); + + switch (ulp) { + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + case IPPROTO_MH: + case IPPROTO_GRE: + memset(portbuf, 0, sizeof(portbuf)); + break; + default: + if (port == IPSEC_PORT_ANY) + strcpy(portbuf, "[any]"); + else + snprintf(portbuf, sizeof(portbuf), "[%u]", port); + break; + } + + snprintf(buf, sizeof(buf), "%s%s", prefbuf, portbuf); + + return buf; +} + +static void +str_upperspec(ulp, p1, p2) + u_int ulp, p1, p2; +{ + struct protoent *ent; + + ent = getprotobynumber((int)ulp); + if (ent) + printf("%s", ent->p_name); + else + printf("%u", ulp); + + if (p1 == IPSEC_PORT_ANY && p2 == IPSEC_PORT_ANY) + return; + + switch (ulp) { + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + case IPPROTO_MH: + printf(" %u,%u", p1, p2); + break; + case IPPROTO_GRE: + printf(" %u", (p1 << 16) + p2); + break; + } +} + +/* + * set "Mon Day Time Year" to buffer + */ +static char * +str_time(t) + time_t t; +{ + static char buf[128]; + + if (t == 0) { + int i = 0; + for (;i < 20;) buf[i++] = ' '; + } else { + char *t0; + if ((t0 = ctime(&t)) == NULL) + memset(buf, '?', 20); + else + memcpy(buf, t0 + 4, 20); + } + + buf[20] = '\0'; + + return(buf); +} + +static void +str_lifetime_byte(x, str) + struct sadb_lifetime *x; + char *str; +{ + double y; + char *unit; + int w; + + if (x == NULL) { + printf("\t%s: 0(bytes)", str); + return; + } + +#if 0 + if ((x->sadb_lifetime_bytes) / 1024 / 1024) { + y = (x->sadb_lifetime_bytes) * 1.0 / 1024 / 1024; + unit = "M"; + w = 1; + } else if ((x->sadb_lifetime_bytes) / 1024) { + y = (x->sadb_lifetime_bytes) * 1.0 / 1024; + unit = "K"; + w = 1; + } else { + y = (x->sadb_lifetime_bytes) * 1.0; + unit = ""; + w = 0; + } +#else + y = (x->sadb_lifetime_bytes) * 1.0; + unit = ""; + w = 0; +#endif + printf("\t%s: %.*f(%sbytes)", str, w, y, unit); +} diff --git a/ipsec-tools/src/libipsec/policy_parse.c b/ipsec-tools/src/libipsec/policy_parse.c new file mode 100644 index 00000000..dcfa3d09 --- /dev/null +++ b/ipsec-tools/src/libipsec/policy_parse.c @@ -0,0 +1,2279 @@ +/* A Bison parser, made by GNU Bison 2.6.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + 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 3 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.6.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + +/* Substitute the variable and function names. */ +#define yyparse __libipsecparse +#define yylex __libipseclex +#define yyerror __libipsecerror +#define yylval __libipseclval +#define yychar __libipsecchar +#define yydebug __libipsecdebug +#define yynerrs __libipsecnerrs + +/* Copy the first part of user declarations. */ +/* Line 336 of yacc.c */ +#line 65 "policy_parse.y" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include + +#include + +#include "config.h" + +#include "ipsec_strerror.h" +#include "libpfkey.h" + +#ifndef INT32_MAX +#define INT32_MAX (0xffffffff) +#endif + +#ifndef INT32_MIN +#define INT32_MIN (-INT32_MAX-1) +#endif + +#define ATOX(c) \ + (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) )) + +static u_int8_t *pbuf = NULL; /* sadb_x_policy buffer */ +static int tlen = 0; /* total length of pbuf */ +static int offset = 0; /* offset of pbuf */ +static int p_dir, p_type, p_protocol, p_mode, p_level, p_reqid; +static u_int32_t p_priority = 0; +static long p_priority_offset = 0; +static struct sockaddr *p_src = NULL; +static struct sockaddr *p_dst = NULL; + +struct _val; +extern void yyerror __P((char *msg)); +static struct sockaddr *parse_sockaddr __P((struct _val *addrbuf, + struct _val *portbuf)); +static int rule_check __P((void)); +static int init_x_policy __P((void)); +static int set_x_request __P((struct sockaddr *, struct sockaddr *)); +static int set_sockaddr __P((struct sockaddr *)); +static void policy_parse_request_init __P((void)); +static void *policy_parse __P((const char *, int)); + +extern void __policy__strbuffer__init__ __P((const char *)); +extern void __policy__strbuffer__free__ __P((void)); +extern int yyparse __P((void)); +extern int yylex __P((void)); + +extern char *__libipsectext; /*XXX*/ + + +/* Line 336 of yacc.c */ +#line 139 "policy_parse.c" + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "y.tab.h". */ +#ifndef _LIBIPSEC_Y_TAB_H +# define _LIBIPSEC_Y_TAB_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int __libipsecdebug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + DIR = 258, + PRIORITY = 259, + PLUS = 260, + PRIO_BASE = 261, + PRIO_OFFSET = 262, + ACTION = 263, + PROTOCOL = 264, + MODE = 265, + LEVEL = 266, + LEVEL_SPECIFY = 267, + IPADDRESS = 268, + PORT = 269, + ME = 270, + ANY = 271, + SLASH = 272, + HYPHEN = 273 + }; +#endif +/* Tokens. */ +#define DIR 258 +#define PRIORITY 259 +#define PLUS 260 +#define PRIO_BASE 261 +#define PRIO_OFFSET 262 +#define ACTION 263 +#define PROTOCOL 264 +#define MODE 265 +#define LEVEL 266 +#define LEVEL_SPECIFY 267 +#define IPADDRESS 268 +#define PORT 269 +#define ME 270 +#define ANY 271 +#define SLASH 272 +#define HYPHEN 273 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 350 of yacc.c */ +#line 129 "policy_parse.y" + + u_int num; + u_int32_t num32; + struct _val { + int len; + char *buf; + } val; + + +/* Line 350 of yacc.c */ +#line 228 "policy_parse.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE __libipseclval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int __libipsecparse (void *YYPARSE_PARAM); +#else +int __libipsecparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int __libipsecparse (void); +#else +int __libipsecparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !_LIBIPSEC_Y_TAB_H */ + +/* Copy the second part of user declarations. */ + +/* Line 353 of yacc.c */ +#line 256 "policy_parse.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 5 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 48 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 19 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 16 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 34 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 60 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 273 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 4, 9, 10, 17, 18, 26, 27, + 34, 35, 44, 45, 54, 56, 57, 60, 68, 75, + 81, 86, 93, 97, 100, 102, 104, 106, 108, 110, + 111, 116, 117, 124, 128 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 20, 0, -1, -1, 3, 8, 21, 27, -1, -1, + 3, 4, 7, 8, 22, 27, -1, -1, 3, 4, + 18, 7, 8, 23, 27, -1, -1, 3, 4, 6, + 8, 24, 27, -1, -1, 3, 4, 6, 5, 7, + 8, 25, 27, -1, -1, 3, 4, 6, 18, 7, + 8, 26, 27, -1, 3, -1, -1, 27, 28, -1, + 29, 17, 30, 17, 32, 17, 31, -1, 29, 17, + 30, 17, 32, 17, -1, 29, 17, 30, 17, 32, + -1, 29, 17, 30, 17, -1, 29, 17, 30, 17, + 17, 31, -1, 29, 17, 30, -1, 29, 17, -1, + 29, -1, 9, -1, 10, -1, 11, -1, 12, -1, + -1, 13, 33, 18, 13, -1, -1, 13, 14, 34, + 18, 13, 14, -1, 15, 18, 16, -1, 16, 18, + 15, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 151, 151, 150, 166, 165, 185, 184, 207, 206, + 218, 217, 240, 239, 261, 273, 275, 287, 288, 289, + 290, 291, 292, 293, 297, 304, 308, 312, 316, 323, + 323, 334, 334, 345, 351 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "DIR", "PRIORITY", "PLUS", "PRIO_BASE", + "PRIO_OFFSET", "ACTION", "PROTOCOL", "MODE", "LEVEL", "LEVEL_SPECIFY", + "IPADDRESS", "PORT", "ME", "ANY", "SLASH", "HYPHEN", "$accept", + "policy_spec", "$@1", "$@2", "$@3", "$@4", "$@5", "$@6", "rules", "rule", + "protocol", "mode", "level", "addresses", "$@7", "$@8", YY_NULL +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 19, 21, 20, 22, 20, 23, 20, 24, 20, + 25, 20, 26, 20, 20, 27, 27, 28, 28, 28, + 28, 28, 28, 28, 28, 29, 30, 31, 31, 33, + 32, 34, 32, 32, 32 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 0, 4, 0, 6, 0, 7, 0, 6, + 0, 8, 0, 8, 1, 0, 2, 7, 6, 5, + 4, 6, 3, 2, 1, 1, 1, 1, 1, 0, + 4, 0, 6, 3, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 14, 0, 0, 2, 1, 0, 0, 0, 15, + 0, 8, 0, 4, 0, 3, 0, 15, 0, 15, + 6, 25, 16, 24, 10, 9, 12, 5, 15, 23, + 15, 15, 7, 26, 22, 11, 13, 20, 29, 0, + 0, 0, 19, 31, 0, 0, 0, 27, 28, 21, + 18, 0, 0, 33, 34, 17, 0, 30, 0, 32 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 2, 9, 19, 28, 17, 30, 31, 15, 22, + 23, 34, 49, 42, 44, 51 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -18 +static const yytype_int8 yypact[] = +{ + 6, -3, 4, 1, -18, -18, -2, 2, 8, -18, + 10, -18, 18, -18, 19, 3, 20, -18, 21, -18, + -18, -18, -18, 9, -18, 3, -18, 3, -18, 22, + -18, -18, 3, -18, 13, 3, 3, 5, 17, 15, + 16, 12, 23, -18, 24, 25, 28, -18, -18, -18, + 12, 26, 32, -18, -18, -18, 33, -18, 34, -18 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -18, -18, -18, -18, -18, -18, -18, -18, -17, -18, + -18, -18, -15, -18, -18, -18 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 25, 3, 27, 10, 5, 4, 11, 6, 7, 1, + 13, 32, 21, 35, 36, 14, 12, 16, 38, 8, + 39, 40, 41, 47, 48, 18, 29, 20, 24, 26, + 37, 43, 33, 45, 46, 55, 0, 0, 0, 0, + 50, 53, 52, 54, 56, 57, 58, 0, 59 +}; + +#define yypact_value_is_default(yystate) \ + ((yystate) == (-18)) + +#define yytable_value_is_error(yytable_value) \ + YYID (0) + +static const yytype_int8 yycheck[] = +{ + 17, 4, 19, 5, 0, 8, 8, 6, 7, 3, + 8, 28, 9, 30, 31, 7, 18, 7, 13, 18, + 15, 16, 17, 11, 12, 7, 17, 8, 8, 8, + 17, 14, 10, 18, 18, 50, -1, -1, -1, -1, + 17, 16, 18, 15, 18, 13, 13, -1, 14 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 20, 4, 8, 0, 6, 7, 18, 21, + 5, 8, 18, 8, 7, 27, 7, 24, 7, 22, + 8, 9, 28, 29, 8, 27, 8, 27, 23, 17, + 25, 26, 27, 10, 30, 27, 27, 17, 13, 15, + 16, 17, 32, 14, 33, 18, 18, 11, 12, 31, + 17, 34, 18, 16, 15, 31, 18, 13, 13, 14 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + + + +/* This macro is provided for backward compatibility. */ + +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULL; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +/* Line 1787 of yacc.c */ +#line 151 "policy_parse.y" + { + p_dir = (yyvsp[(1) - (2)].num); + p_type = (yyvsp[(2) - (2)].num); + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + p_priority = PRIORITY_DEFAULT; +#else + p_priority = 0; +#endif + + if (init_x_policy()) + return -1; + } + break; + + case 4: +/* Line 1787 of yacc.c */ +#line 166 "policy_parse.y" + { + p_dir = (yyvsp[(1) - (4)].num); + p_type = (yyvsp[(4) - (4)].num); + p_priority_offset = -atol((yyvsp[(3) - (4)].val).buf); + + errno = 0; + if (errno != 0 || p_priority_offset < INT32_MIN) + { + __ipsec_errcode = EIPSEC_INVAL_PRIORITY_OFFSET; + return -1; + } + + p_priority = PRIORITY_DEFAULT + (u_int32_t) p_priority_offset; + + if (init_x_policy()) + return -1; + } + break; + + case 6: +/* Line 1787 of yacc.c */ +#line 185 "policy_parse.y" + { + p_dir = (yyvsp[(1) - (5)].num); + p_type = (yyvsp[(5) - (5)].num); + + errno = 0; + p_priority_offset = atol((yyvsp[(4) - (5)].val).buf); + + if (errno != 0 || p_priority_offset > INT32_MAX) + { + __ipsec_errcode = EIPSEC_INVAL_PRIORITY_OFFSET; + return -1; + } + + /* negative input value means lower priority, therefore higher + actual value so that is closer to the end of the list */ + p_priority = PRIORITY_DEFAULT + (u_int32_t) p_priority_offset; + + if (init_x_policy()) + return -1; + } + break; + + case 8: +/* Line 1787 of yacc.c */ +#line 207 "policy_parse.y" + { + p_dir = (yyvsp[(1) - (4)].num); + p_type = (yyvsp[(4) - (4)].num); + + p_priority = (yyvsp[(3) - (4)].num32); + + if (init_x_policy()) + return -1; + } + break; + + case 10: +/* Line 1787 of yacc.c */ +#line 218 "policy_parse.y" + { + p_dir = (yyvsp[(1) - (6)].num); + p_type = (yyvsp[(6) - (6)].num); + + errno = 0; + p_priority_offset = atol((yyvsp[(5) - (6)].val).buf); + + if (errno != 0 || p_priority_offset > PRIORITY_OFFSET_NEGATIVE_MAX) + { + __ipsec_errcode = EIPSEC_INVAL_PRIORITY_BASE_OFFSET; + return -1; + } + + /* adding value means higher priority, therefore lower + actual value so that is closer to the beginning of the list */ + p_priority = (yyvsp[(3) - (6)].num32) - (u_int32_t) p_priority_offset; + + if (init_x_policy()) + return -1; + } + break; + + case 12: +/* Line 1787 of yacc.c */ +#line 240 "policy_parse.y" + { + p_dir = (yyvsp[(1) - (6)].num); + p_type = (yyvsp[(6) - (6)].num); + + errno = 0; + p_priority_offset = atol((yyvsp[(5) - (6)].val).buf); + + if (errno != 0 || p_priority_offset > PRIORITY_OFFSET_POSITIVE_MAX) + { + __ipsec_errcode = EIPSEC_INVAL_PRIORITY_BASE_OFFSET; + return -1; + } + + /* subtracting value means lower priority, therefore higher + actual value so that is closer to the end of the list */ + p_priority = (yyvsp[(3) - (6)].num32) + (u_int32_t) p_priority_offset; + + if (init_x_policy()) + return -1; + } + break; + + case 14: +/* Line 1787 of yacc.c */ +#line 262 "policy_parse.y" + { + p_dir = (yyvsp[(1) - (1)].num); + p_type = 0; /* ignored it by kernel */ + + p_priority = 0; + + if (init_x_policy()) + return -1; + } + break; + + case 16: +/* Line 1787 of yacc.c */ +#line 275 "policy_parse.y" + { + if (rule_check() < 0) + return -1; + + if (set_x_request(p_src, p_dst) < 0) + return -1; + + policy_parse_request_init(); + } + break; + + case 23: +/* Line 1787 of yacc.c */ +#line 293 "policy_parse.y" + { + __ipsec_errcode = EIPSEC_FEW_ARGUMENTS; + return -1; + } + break; + + case 24: +/* Line 1787 of yacc.c */ +#line 297 "policy_parse.y" + { + __ipsec_errcode = EIPSEC_FEW_ARGUMENTS; + return -1; + } + break; + + case 25: +/* Line 1787 of yacc.c */ +#line 304 "policy_parse.y" + { p_protocol = (yyvsp[(1) - (1)].num); } + break; + + case 26: +/* Line 1787 of yacc.c */ +#line 308 "policy_parse.y" + { p_mode = (yyvsp[(1) - (1)].num); } + break; + + case 27: +/* Line 1787 of yacc.c */ +#line 312 "policy_parse.y" + { + p_level = (yyvsp[(1) - (1)].num); + p_reqid = 0; + } + break; + + case 28: +/* Line 1787 of yacc.c */ +#line 316 "policy_parse.y" + { + p_level = IPSEC_LEVEL_UNIQUE; + p_reqid = atol((yyvsp[(1) - (1)].val).buf); /* atol() is good. */ + } + break; + + case 29: +/* Line 1787 of yacc.c */ +#line 323 "policy_parse.y" + { + p_src = parse_sockaddr(&(yyvsp[(1) - (1)].val), NULL); + if (p_src == NULL) + return -1; + } + break; + + case 30: +/* Line 1787 of yacc.c */ +#line 329 "policy_parse.y" + { + p_dst = parse_sockaddr(&(yyvsp[(4) - (4)].val), NULL); + if (p_dst == NULL) + return -1; + } + break; + + case 31: +/* Line 1787 of yacc.c */ +#line 334 "policy_parse.y" + { + p_src = parse_sockaddr(&(yyvsp[(1) - (2)].val), &(yyvsp[(2) - (2)].val)); + if (p_src == NULL) + return -1; + } + break; + + case 32: +/* Line 1787 of yacc.c */ +#line 340 "policy_parse.y" + { + p_dst = parse_sockaddr(&(yyvsp[(5) - (6)].val), &(yyvsp[(6) - (6)].val)); + if (p_dst == NULL) + return -1; + } + break; + + case 33: +/* Line 1787 of yacc.c */ +#line 345 "policy_parse.y" + { + if (p_dir != IPSEC_DIR_OUTBOUND) { + __ipsec_errcode = EIPSEC_INVAL_DIR; + return -1; + } + } + break; + + case 34: +/* Line 1787 of yacc.c */ +#line 351 "policy_parse.y" + { + if (p_dir != IPSEC_DIR_INBOUND) { + __ipsec_errcode = EIPSEC_INVAL_DIR; + return -1; + } + } + break; + + +/* Line 1787 of yacc.c */ +#line 1777 "policy_parse.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +/* Line 2048 of yacc.c */ +#line 362 "policy_parse.y" + + +void +yyerror(msg) + char *msg; +{ + fprintf(stderr, "libipsec: %s while parsing \"%s\"\n", + msg, __libipsectext); + + return; +} + +static struct sockaddr * +parse_sockaddr(addrbuf, portbuf) + struct _val *addrbuf; + struct _val *portbuf; +{ + struct addrinfo hints, *res; + char *addr; + char *serv = NULL; + int error; + struct sockaddr *newaddr = NULL; + + if ((addr = malloc(addrbuf->len + 1)) == NULL) { + yyerror("malloc failed"); + __ipsec_set_strerror(strerror(errno)); + return NULL; + } + + if (portbuf && ((serv = malloc(portbuf->len + 1)) == NULL)) { + free(addr); + yyerror("malloc failed"); + __ipsec_set_strerror(strerror(errno)); + return NULL; + } + + strncpy(addr, addrbuf->buf, addrbuf->len); + addr[addrbuf->len] = '\0'; + + if (portbuf) { + strncpy(serv, portbuf->buf, portbuf->len); + serv[portbuf->len] = '\0'; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_flags = AI_NUMERICHOST; + hints.ai_socktype = SOCK_DGRAM; + error = getaddrinfo(addr, serv, &hints, &res); + free(addr); + if (serv != NULL) + free(serv); + if (error != 0) { + yyerror("invalid IP address"); + __ipsec_set_strerror(gai_strerror(error)); + return NULL; + } + + if (res->ai_addr == NULL) { + yyerror("invalid IP address"); + __ipsec_set_strerror(gai_strerror(error)); + return NULL; + } + + newaddr = malloc(res->ai_addrlen); + if (newaddr == NULL) { + __ipsec_errcode = EIPSEC_NO_BUFS; + freeaddrinfo(res); + return NULL; + } + memcpy(newaddr, res->ai_addr, res->ai_addrlen); + + freeaddrinfo(res); + + __ipsec_errcode = EIPSEC_NO_ERROR; + return newaddr; +} + +static int +rule_check() +{ + if (p_type == IPSEC_POLICY_IPSEC) { + if (p_protocol == IPPROTO_IP) { + __ipsec_errcode = EIPSEC_NO_PROTO; + return -1; + } + + if (p_mode != IPSEC_MODE_TRANSPORT + && p_mode != IPSEC_MODE_TUNNEL) { + __ipsec_errcode = EIPSEC_INVAL_MODE; + return -1; + } + + if (p_src == NULL && p_dst == NULL) { + if (p_mode != IPSEC_MODE_TRANSPORT) { + __ipsec_errcode = EIPSEC_INVAL_ADDRESS; + return -1; + } + } + else if (p_src->sa_family != p_dst->sa_family) { + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + return -1; + } + } + + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; +} + +static int +init_x_policy() +{ + struct sadb_x_policy *p; + + if (pbuf) { + free(pbuf); + tlen = 0; + } + pbuf = malloc(sizeof(struct sadb_x_policy)); + if (pbuf == NULL) { + __ipsec_errcode = EIPSEC_NO_BUFS; + return -1; + } + tlen = sizeof(struct sadb_x_policy); + + memset(pbuf, 0, tlen); + p = (struct sadb_x_policy *)pbuf; + p->sadb_x_policy_len = 0; /* must update later */ + p->sadb_x_policy_exttype = SADB_X_EXT_POLICY; + p->sadb_x_policy_type = p_type; + p->sadb_x_policy_dir = p_dir; + p->sadb_x_policy_id = 0; +#ifdef HAVE_PFKEY_POLICY_PRIORITY + p->sadb_x_policy_priority = p_priority; +#else + /* fail if given a priority and libipsec was not compiled with + priority support */ + if (p_priority != 0) + { + __ipsec_errcode = EIPSEC_PRIORITY_NOT_COMPILED; + return -1; + } +#endif + + offset = tlen; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; +} + +static int +set_x_request(src, dst) + struct sockaddr *src, *dst; +{ + struct sadb_x_ipsecrequest *p; + int reqlen; + u_int8_t *n; + + reqlen = sizeof(*p) + + (src ? sysdep_sa_len(src) : 0) + + (dst ? sysdep_sa_len(dst) : 0); + tlen += reqlen; /* increment to total length */ + + n = realloc(pbuf, tlen); + if (n == NULL) { + __ipsec_errcode = EIPSEC_NO_BUFS; + return -1; + } + pbuf = n; + + p = (struct sadb_x_ipsecrequest *)&pbuf[offset]; + p->sadb_x_ipsecrequest_len = reqlen; + p->sadb_x_ipsecrequest_proto = p_protocol; + p->sadb_x_ipsecrequest_mode = p_mode; + p->sadb_x_ipsecrequest_level = p_level; + p->sadb_x_ipsecrequest_reqid = p_reqid; + offset += sizeof(*p); + + if (set_sockaddr(src) || set_sockaddr(dst)) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; +} + +static int +set_sockaddr(addr) + struct sockaddr *addr; +{ + if (addr == NULL) { + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; + } + + /* tlen has already incremented */ + + memcpy(&pbuf[offset], addr, sysdep_sa_len(addr)); + + offset += sysdep_sa_len(addr); + + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; +} + +static void +policy_parse_request_init() +{ + p_protocol = IPPROTO_IP; + p_mode = IPSEC_MODE_ANY; + p_level = IPSEC_LEVEL_DEFAULT; + p_reqid = 0; + if (p_src != NULL) { + free(p_src); + p_src = NULL; + } + if (p_dst != NULL) { + free(p_dst); + p_dst = NULL; + } + + return; +} + +static void * +policy_parse(msg, msglen) + const char *msg; + int msglen; +{ + int error; + + pbuf = NULL; + tlen = 0; + + /* initialize */ + p_dir = IPSEC_DIR_INVALID; + p_type = IPSEC_POLICY_DISCARD; + policy_parse_request_init(); + __policy__strbuffer__init__(msg); + + error = yyparse(); /* it must be set errcode. */ + __policy__strbuffer__free__(); + + if (error) { + if (pbuf != NULL) + free(pbuf); + return NULL; + } + + /* update total length */ + ((struct sadb_x_policy *)pbuf)->sadb_x_policy_len = PFKEY_UNIT64(tlen); + + __ipsec_errcode = EIPSEC_NO_ERROR; + + return pbuf; +} + +ipsec_policy_t +ipsec_set_policy(msg, msglen) + __ipsec_const char *msg; + int msglen; +{ + caddr_t policy; + + policy = policy_parse(msg, msglen); + if (policy == NULL) { + if (__ipsec_errcode == EIPSEC_NO_ERROR) + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return NULL; + } + + __ipsec_errcode = EIPSEC_NO_ERROR; + return policy; +} diff --git a/ipsec-tools/src/libipsec/policy_parse.h b/ipsec-tools/src/libipsec/policy_parse.h new file mode 100644 index 00000000..113444d3 --- /dev/null +++ b/ipsec-tools/src/libipsec/policy_parse.h @@ -0,0 +1,125 @@ +/* A Bison parser, made by GNU Bison 2.6.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + 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 3 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef _LIBIPSEC_POLICY_PARSE_H +# define _LIBIPSEC_POLICY_PARSE_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int __libipsecdebug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + DIR = 258, + PRIORITY = 259, + PLUS = 260, + PRIO_BASE = 261, + PRIO_OFFSET = 262, + ACTION = 263, + PROTOCOL = 264, + MODE = 265, + LEVEL = 266, + LEVEL_SPECIFY = 267, + IPADDRESS = 268, + PORT = 269, + ME = 270, + ANY = 271, + SLASH = 272, + HYPHEN = 273 + }; +#endif +/* Tokens. */ +#define DIR 258 +#define PRIORITY 259 +#define PLUS 260 +#define PRIO_BASE 261 +#define PRIO_OFFSET 262 +#define ACTION 263 +#define PROTOCOL 264 +#define MODE 265 +#define LEVEL 266 +#define LEVEL_SPECIFY 267 +#define IPADDRESS 268 +#define PORT 269 +#define ME 270 +#define ANY 271 +#define SLASH 272 +#define HYPHEN 273 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 2049 of yacc.c */ +#line 129 "policy_parse.y" + + u_int num; + u_int32_t num32; + struct _val { + int len; + char *buf; + } val; + + +/* Line 2049 of yacc.c */ +#line 103 "policy_parse.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE __libipseclval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int __libipsecparse (void *YYPARSE_PARAM); +#else +int __libipsecparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int __libipsecparse (void); +#else +int __libipsecparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !_LIBIPSEC_POLICY_PARSE_H */ diff --git a/ipsec-tools/src/libipsec/policy_parse.y b/ipsec-tools/src/libipsec/policy_parse.y new file mode 100644 index 00000000..321f4f06 --- /dev/null +++ b/ipsec-tools/src/libipsec/policy_parse.y @@ -0,0 +1,634 @@ +/* $NetBSD: policy_parse.y,v 1.11 2009/02/16 18:36:21 tteras Exp $ */ + +/* $KAME: policy_parse.y,v 1.21 2003/12/12 08:01:26 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * IN/OUT bound policy configuration take place such below: + * in + * out + * + * is one of the following: + * priority where the integer is an offset from the default + * priority, where negative numbers indicate lower + * priority (towards end of list) and positive numbers + * indicate higher priority (towards beginning of list) + * + * priority {low,def,high} {+,-} where low and high are + * constants which are closer + * to the end of the list and + * beginning of the list, + * respectively + * + * is one of following: + * "discard", "none", "ipsec ", "entrust", "bypass", + * + * The following requests are accepted as : + * + * protocol/mode/src-dst/level + * protocol/mode/src-dst parsed as protocol/mode/src-dst/default + * protocol/mode/src-dst/ parsed as protocol/mode/src-dst/default + * protocol/transport parsed as protocol/mode/any-any/default + * protocol/transport//level parsed as protocol/mode/any-any/level + * + * You can concatenate these requests with either ' '(single space) or '\n'. + */ + +%{ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include + +#include + +#include "config.h" + +#include "ipsec_strerror.h" +#include "libpfkey.h" + +#ifndef INT32_MAX +#define INT32_MAX (0xffffffff) +#endif + +#ifndef INT32_MIN +#define INT32_MIN (-INT32_MAX-1) +#endif + +#define ATOX(c) \ + (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) )) + +static u_int8_t *pbuf = NULL; /* sadb_x_policy buffer */ +static int tlen = 0; /* total length of pbuf */ +static int offset = 0; /* offset of pbuf */ +static int p_dir, p_type, p_protocol, p_mode, p_level, p_reqid; +static u_int32_t p_priority = 0; +static long p_priority_offset = 0; +static struct sockaddr *p_src = NULL; +static struct sockaddr *p_dst = NULL; + +struct _val; +extern void yyerror __P((char *msg)); +static struct sockaddr *parse_sockaddr __P((struct _val *addrbuf, + struct _val *portbuf)); +static int rule_check __P((void)); +static int init_x_policy __P((void)); +static int set_x_request __P((struct sockaddr *, struct sockaddr *)); +static int set_sockaddr __P((struct sockaddr *)); +static void policy_parse_request_init __P((void)); +static void *policy_parse __P((const char *, int)); + +extern void __policy__strbuffer__init__ __P((const char *)); +extern void __policy__strbuffer__free__ __P((void)); +extern int yyparse __P((void)); +extern int yylex __P((void)); + +extern char *__libipsectext; /*XXX*/ + +%} + +%union { + u_int num; + u_int32_t num32; + struct _val { + int len; + char *buf; + } val; +} + +%token DIR +%token PRIORITY PLUS +%token PRIO_BASE +%token PRIO_OFFSET +%token ACTION PROTOCOL MODE LEVEL LEVEL_SPECIFY IPADDRESS PORT +%token ME ANY +%token SLASH HYPHEN +%type DIR PRIORITY ACTION PROTOCOL MODE LEVEL +%type IPADDRESS LEVEL_SPECIFY PORT + +%% +policy_spec + : DIR ACTION + { + p_dir = $1; + p_type = $2; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + p_priority = PRIORITY_DEFAULT; +#else + p_priority = 0; +#endif + + if (init_x_policy()) + return -1; + } + rules + | DIR PRIORITY PRIO_OFFSET ACTION + { + p_dir = $1; + p_type = $4; + p_priority_offset = -atol($3.buf); + + errno = 0; + if (errno != 0 || p_priority_offset < INT32_MIN) + { + __ipsec_errcode = EIPSEC_INVAL_PRIORITY_OFFSET; + return -1; + } + + p_priority = PRIORITY_DEFAULT + (u_int32_t) p_priority_offset; + + if (init_x_policy()) + return -1; + } + rules + | DIR PRIORITY HYPHEN PRIO_OFFSET ACTION + { + p_dir = $1; + p_type = $5; + + errno = 0; + p_priority_offset = atol($4.buf); + + if (errno != 0 || p_priority_offset > INT32_MAX) + { + __ipsec_errcode = EIPSEC_INVAL_PRIORITY_OFFSET; + return -1; + } + + /* negative input value means lower priority, therefore higher + actual value so that is closer to the end of the list */ + p_priority = PRIORITY_DEFAULT + (u_int32_t) p_priority_offset; + + if (init_x_policy()) + return -1; + } + rules + | DIR PRIORITY PRIO_BASE ACTION + { + p_dir = $1; + p_type = $4; + + p_priority = $3; + + if (init_x_policy()) + return -1; + } + rules + | DIR PRIORITY PRIO_BASE PLUS PRIO_OFFSET ACTION + { + p_dir = $1; + p_type = $6; + + errno = 0; + p_priority_offset = atol($5.buf); + + if (errno != 0 || p_priority_offset > PRIORITY_OFFSET_NEGATIVE_MAX) + { + __ipsec_errcode = EIPSEC_INVAL_PRIORITY_BASE_OFFSET; + return -1; + } + + /* adding value means higher priority, therefore lower + actual value so that is closer to the beginning of the list */ + p_priority = $3 - (u_int32_t) p_priority_offset; + + if (init_x_policy()) + return -1; + } + rules + | DIR PRIORITY PRIO_BASE HYPHEN PRIO_OFFSET ACTION + { + p_dir = $1; + p_type = $6; + + errno = 0; + p_priority_offset = atol($5.buf); + + if (errno != 0 || p_priority_offset > PRIORITY_OFFSET_POSITIVE_MAX) + { + __ipsec_errcode = EIPSEC_INVAL_PRIORITY_BASE_OFFSET; + return -1; + } + + /* subtracting value means lower priority, therefore higher + actual value so that is closer to the end of the list */ + p_priority = $3 + (u_int32_t) p_priority_offset; + + if (init_x_policy()) + return -1; + } + rules + | DIR + { + p_dir = $1; + p_type = 0; /* ignored it by kernel */ + + p_priority = 0; + + if (init_x_policy()) + return -1; + } + ; + +rules + : /*NOTHING*/ + | rules rule { + if (rule_check() < 0) + return -1; + + if (set_x_request(p_src, p_dst) < 0) + return -1; + + policy_parse_request_init(); + } + ; + +rule + : protocol SLASH mode SLASH addresses SLASH level + | protocol SLASH mode SLASH addresses SLASH + | protocol SLASH mode SLASH addresses + | protocol SLASH mode SLASH + | protocol SLASH mode SLASH SLASH level + | protocol SLASH mode + | protocol SLASH { + __ipsec_errcode = EIPSEC_FEW_ARGUMENTS; + return -1; + } + | protocol { + __ipsec_errcode = EIPSEC_FEW_ARGUMENTS; + return -1; + } + ; + +protocol + : PROTOCOL { p_protocol = $1; } + ; + +mode + : MODE { p_mode = $1; } + ; + +level + : LEVEL { + p_level = $1; + p_reqid = 0; + } + | LEVEL_SPECIFY { + p_level = IPSEC_LEVEL_UNIQUE; + p_reqid = atol($1.buf); /* atol() is good. */ + } + ; + +addresses + : IPADDRESS { + p_src = parse_sockaddr(&$1, NULL); + if (p_src == NULL) + return -1; + } + HYPHEN + IPADDRESS { + p_dst = parse_sockaddr(&$4, NULL); + if (p_dst == NULL) + return -1; + } + | IPADDRESS PORT { + p_src = parse_sockaddr(&$1, &$2); + if (p_src == NULL) + return -1; + } + HYPHEN + IPADDRESS PORT { + p_dst = parse_sockaddr(&$5, &$6); + if (p_dst == NULL) + return -1; + } + | ME HYPHEN ANY { + if (p_dir != IPSEC_DIR_OUTBOUND) { + __ipsec_errcode = EIPSEC_INVAL_DIR; + return -1; + } + } + | ANY HYPHEN ME { + if (p_dir != IPSEC_DIR_INBOUND) { + __ipsec_errcode = EIPSEC_INVAL_DIR; + return -1; + } + } + /* + | ME HYPHEN ME + */ + ; + +%% + +void +yyerror(msg) + char *msg; +{ + fprintf(stderr, "libipsec: %s while parsing \"%s\"\n", + msg, __libipsectext); + + return; +} + +static struct sockaddr * +parse_sockaddr(addrbuf, portbuf) + struct _val *addrbuf; + struct _val *portbuf; +{ + struct addrinfo hints, *res; + char *addr; + char *serv = NULL; + int error; + struct sockaddr *newaddr = NULL; + + if ((addr = malloc(addrbuf->len + 1)) == NULL) { + yyerror("malloc failed"); + __ipsec_set_strerror(strerror(errno)); + return NULL; + } + + if (portbuf && ((serv = malloc(portbuf->len + 1)) == NULL)) { + free(addr); + yyerror("malloc failed"); + __ipsec_set_strerror(strerror(errno)); + return NULL; + } + + strncpy(addr, addrbuf->buf, addrbuf->len); + addr[addrbuf->len] = '\0'; + + if (portbuf) { + strncpy(serv, portbuf->buf, portbuf->len); + serv[portbuf->len] = '\0'; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_flags = AI_NUMERICHOST; + hints.ai_socktype = SOCK_DGRAM; + error = getaddrinfo(addr, serv, &hints, &res); + free(addr); + if (serv != NULL) + free(serv); + if (error != 0) { + yyerror("invalid IP address"); + __ipsec_set_strerror(gai_strerror(error)); + return NULL; + } + + if (res->ai_addr == NULL) { + yyerror("invalid IP address"); + __ipsec_set_strerror(gai_strerror(error)); + return NULL; + } + + newaddr = malloc(res->ai_addrlen); + if (newaddr == NULL) { + __ipsec_errcode = EIPSEC_NO_BUFS; + freeaddrinfo(res); + return NULL; + } + memcpy(newaddr, res->ai_addr, res->ai_addrlen); + + freeaddrinfo(res); + + __ipsec_errcode = EIPSEC_NO_ERROR; + return newaddr; +} + +static int +rule_check() +{ + if (p_type == IPSEC_POLICY_IPSEC) { + if (p_protocol == IPPROTO_IP) { + __ipsec_errcode = EIPSEC_NO_PROTO; + return -1; + } + + if (p_mode != IPSEC_MODE_TRANSPORT + && p_mode != IPSEC_MODE_TUNNEL) { + __ipsec_errcode = EIPSEC_INVAL_MODE; + return -1; + } + + if (p_src == NULL && p_dst == NULL) { + if (p_mode != IPSEC_MODE_TRANSPORT) { + __ipsec_errcode = EIPSEC_INVAL_ADDRESS; + return -1; + } + } + else if (p_src->sa_family != p_dst->sa_family) { + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + return -1; + } + } + + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; +} + +static int +init_x_policy() +{ + struct sadb_x_policy *p; + + if (pbuf) { + free(pbuf); + tlen = 0; + } + pbuf = malloc(sizeof(struct sadb_x_policy)); + if (pbuf == NULL) { + __ipsec_errcode = EIPSEC_NO_BUFS; + return -1; + } + tlen = sizeof(struct sadb_x_policy); + + memset(pbuf, 0, tlen); + p = (struct sadb_x_policy *)pbuf; + p->sadb_x_policy_len = 0; /* must update later */ + p->sadb_x_policy_exttype = SADB_X_EXT_POLICY; + p->sadb_x_policy_type = p_type; + p->sadb_x_policy_dir = p_dir; + p->sadb_x_policy_id = 0; +#ifdef HAVE_PFKEY_POLICY_PRIORITY + p->sadb_x_policy_priority = p_priority; +#else + /* fail if given a priority and libipsec was not compiled with + priority support */ + if (p_priority != 0) + { + __ipsec_errcode = EIPSEC_PRIORITY_NOT_COMPILED; + return -1; + } +#endif + + offset = tlen; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; +} + +static int +set_x_request(src, dst) + struct sockaddr *src, *dst; +{ + struct sadb_x_ipsecrequest *p; + int reqlen; + u_int8_t *n; + + reqlen = sizeof(*p) + + (src ? sysdep_sa_len(src) : 0) + + (dst ? sysdep_sa_len(dst) : 0); + tlen += reqlen; /* increment to total length */ + + n = realloc(pbuf, tlen); + if (n == NULL) { + __ipsec_errcode = EIPSEC_NO_BUFS; + return -1; + } + pbuf = n; + + p = (struct sadb_x_ipsecrequest *)&pbuf[offset]; + p->sadb_x_ipsecrequest_len = reqlen; + p->sadb_x_ipsecrequest_proto = p_protocol; + p->sadb_x_ipsecrequest_mode = p_mode; + p->sadb_x_ipsecrequest_level = p_level; + p->sadb_x_ipsecrequest_reqid = p_reqid; + offset += sizeof(*p); + + if (set_sockaddr(src) || set_sockaddr(dst)) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; +} + +static int +set_sockaddr(addr) + struct sockaddr *addr; +{ + if (addr == NULL) { + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; + } + + /* tlen has already incremented */ + + memcpy(&pbuf[offset], addr, sysdep_sa_len(addr)); + + offset += sysdep_sa_len(addr); + + __ipsec_errcode = EIPSEC_NO_ERROR; + return 0; +} + +static void +policy_parse_request_init() +{ + p_protocol = IPPROTO_IP; + p_mode = IPSEC_MODE_ANY; + p_level = IPSEC_LEVEL_DEFAULT; + p_reqid = 0; + if (p_src != NULL) { + free(p_src); + p_src = NULL; + } + if (p_dst != NULL) { + free(p_dst); + p_dst = NULL; + } + + return; +} + +static void * +policy_parse(msg, msglen) + const char *msg; + int msglen; +{ + int error; + + pbuf = NULL; + tlen = 0; + + /* initialize */ + p_dir = IPSEC_DIR_INVALID; + p_type = IPSEC_POLICY_DISCARD; + policy_parse_request_init(); + __policy__strbuffer__init__(msg); + + error = yyparse(); /* it must be set errcode. */ + __policy__strbuffer__free__(); + + if (error) { + if (pbuf != NULL) + free(pbuf); + return NULL; + } + + /* update total length */ + ((struct sadb_x_policy *)pbuf)->sadb_x_policy_len = PFKEY_UNIT64(tlen); + + __ipsec_errcode = EIPSEC_NO_ERROR; + + return pbuf; +} + +ipsec_policy_t +ipsec_set_policy(msg, msglen) + __ipsec_const char *msg; + int msglen; +{ + caddr_t policy; + + policy = policy_parse(msg, msglen); + if (policy == NULL) { + if (__ipsec_errcode == EIPSEC_NO_ERROR) + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return NULL; + } + + __ipsec_errcode = EIPSEC_NO_ERROR; + return policy; +} diff --git a/ipsec-tools/src/libipsec/policy_token.c b/ipsec-tools/src/libipsec/policy_token.c new file mode 100644 index 00000000..1728394c --- /dev/null +++ b/ipsec-tools/src/libipsec/policy_token.c @@ -0,0 +1,2075 @@ +#line 2 "policy_token.c" + +#line 4 "policy_token.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer __libipsec_create_buffer +#define yy_delete_buffer __libipsec_delete_buffer +#define yy_flex_debug __libipsec_flex_debug +#define yy_init_buffer __libipsec_init_buffer +#define yy_flush_buffer __libipsec_flush_buffer +#define yy_load_buffer_state __libipsec_load_buffer_state +#define yy_switch_to_buffer __libipsec_switch_to_buffer +#define yyin __libipsecin +#define yyleng __libipsecleng +#define yylex __libipseclex +#define yylineno __libipseclineno +#define yyout __libipsecout +#define yyrestart __libipsecrestart +#define yytext __libipsectext +#define yywrap __libipsecwrap +#define yyalloc __libipsecalloc +#define yyrealloc __libipsecrealloc +#define yyfree __libipsecfree + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 37 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE __libipsecrestart(__libipsecin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t __libipsecleng; + +extern FILE *__libipsecin, *__libipsecout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up __libipsectext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up __libipsectext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via __libipsecrestart()), so that the user can continue scanning by + * just pointing __libipsecin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when __libipsectext is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t __libipsecleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow __libipsecwrap()'s to do buffer switches + * instead of setting up a fresh __libipsecin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void __libipsecrestart (FILE *input_file ); +void __libipsec_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE __libipsec_create_buffer (FILE *file,int size ); +void __libipsec_delete_buffer (YY_BUFFER_STATE b ); +void __libipsec_flush_buffer (YY_BUFFER_STATE b ); +void __libipsecpush_buffer_state (YY_BUFFER_STATE new_buffer ); +void __libipsecpop_buffer_state (void ); + +static void __libipsecensure_buffer_stack (void ); +static void __libipsec_load_buffer_state (void ); +static void __libipsec_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER __libipsec_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE __libipsec_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE __libipsec_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE __libipsec_scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *__libipsecalloc (yy_size_t ); +void *__libipsecrealloc (void *,yy_size_t ); +void __libipsecfree (void * ); + +#define yy_new_buffer __libipsec_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + __libipsecensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + __libipsec_create_buffer(__libipsecin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + __libipsecensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + __libipsec_create_buffer(__libipsecin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define __libipsecwrap() 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +FILE *__libipsecin = (FILE *) 0, *__libipsecout = (FILE *) 0; + +typedef int yy_state_type; + +extern int __libipseclineno; + +int __libipseclineno = 1; + +extern char *__libipsectext; +#define yytext_ptr __libipsectext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up __libipsectext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + __libipsecleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 34 +#define YY_END_OF_BUFFER 35 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[121] = + { 0, + 0, 0, 35, 34, 32, 33, 9, 30, 29, 28, + 10, 34, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 32, 0, 29, + 10, 0, 17, 29, 29, 29, 29, 29, 29, 29, + 29, 1, 29, 29, 21, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 31, 22, 29, 7, 29, 29, + 16, 3, 29, 29, 29, 6, 29, 2, 29, 29, + 29, 29, 29, 24, 29, 29, 29, 29, 8, 29, + 29, 12, 5, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 13, 29, 29, 29, 29, 29, 14, 29, + + 29, 29, 18, 29, 29, 29, 20, 27, 23, 11, + 15, 29, 25, 29, 29, 4, 29, 26, 19, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 4, 1, 1, 1, + 1, 1, 5, 1, 6, 7, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 10, 1, 1, + 1, 1, 1, 1, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 12, 1, 13, 1, 7, 1, 14, 15, 16, 17, + + 18, 19, 20, 21, 22, 11, 11, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 11, 33, 11, + 34, 11, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[35] = + { 0, + 1, 1, 1, 2, 1, 1, 2, 1, 3, 2, + 3, 1, 1, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3 + } ; + +static yyconst flex_int16_t yy_base[123] = + { 0, + 0, 0, 235, 236, 232, 236, 236, 236, 229, 236, + 31, 223, 32, 33, 34, 35, 37, 39, 41, 38, + 40, 43, 42, 44, 45, 46, 47, 229, 0, 226, + 50, 67, 225, 51, 67, 77, 58, 75, 78, 80, + 79, 224, 82, 83, 223, 85, 86, 87, 91, 88, + 89, 96, 97, 0, 236, 222, 99, 107, 104, 100, + 221, 220, 103, 118, 119, 219, 121, 218, 122, 123, + 124, 126, 128, 217, 127, 129, 131, 130, 216, 134, + 136, 215, 137, 132, 138, 142, 139, 143, 146, 149, + 155, 159, 214, 160, 161, 166, 168, 163, 213, 170, + + 171, 172, 212, 173, 176, 179, 211, 185, 206, 204, + 202, 175, 196, 183, 188, 195, 180, 198, 194, 236, + 211, 193 + } ; + +static yyconst flex_int16_t yy_def[123] = + { 0, + 120, 1, 120, 120, 120, 120, 120, 120, 121, 120, + 121, 120, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 120, 122, 121, + 121, 120, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 122, 120, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 0, + 120, 120 + } ; + +static yyconst flex_int16_t yy_nxt[271] = + { 0, + 4, 5, 6, 4, 7, 8, 9, 10, 11, 9, + 9, 12, 4, 13, 14, 9, 15, 16, 17, 9, + 18, 19, 20, 21, 22, 23, 24, 9, 25, 9, + 26, 27, 9, 9, 29, 29, 29, 29, 29, 31, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 36, 33, 29, 29, 37, 34, 45, 31, 38, + 41, 29, 49, 44, 39, 42, 35, 43, 46, 40, + 29, 52, 48, 47, 50, 32, 53, 51, 29, 55, + 29, 29, 29, 29, 56, 29, 29, 59, 29, 29, + 29, 29, 29, 57, 29, 58, 62, 64, 63, 29, + + 29, 71, 29, 29, 61, 60, 29, 29, 69, 67, + 29, 65, 75, 72, 74, 66, 68, 73, 70, 77, + 76, 29, 29, 79, 29, 29, 29, 29, 78, 29, + 29, 29, 29, 29, 29, 29, 81, 29, 82, 29, + 29, 29, 29, 80, 90, 29, 29, 83, 85, 29, + 86, 93, 29, 95, 84, 87, 88, 92, 29, 97, + 89, 91, 29, 29, 29, 94, 29, 96, 100, 29, + 98, 29, 99, 29, 29, 29, 29, 101, 29, 29, + 108, 104, 29, 29, 102, 103, 29, 110, 29, 105, + 107, 29, 106, 113, 115, 54, 118, 29, 29, 29, + + 109, 29, 111, 112, 114, 29, 118, 29, 116, 29, + 119, 117, 30, 30, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 28, 32, 29, 28, 120, 3, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120 + } ; + +static yyconst flex_int16_t yy_chk[271] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 11, 13, 14, 15, 16, 11, + 17, 20, 18, 21, 19, 23, 22, 24, 25, 26, + 27, 15, 13, 31, 34, 15, 13, 21, 31, 16, + 18, 37, 25, 20, 16, 19, 14, 19, 22, 17, + 35, 27, 24, 23, 26, 32, 27, 26, 38, 32, + 36, 39, 41, 40, 34, 43, 44, 37, 46, 47, + 48, 50, 51, 35, 49, 36, 40, 43, 41, 52, + + 53, 50, 57, 60, 39, 38, 63, 59, 48, 46, + 58, 43, 57, 51, 53, 44, 47, 52, 49, 59, + 58, 64, 65, 63, 67, 69, 70, 71, 60, 72, + 75, 73, 76, 78, 77, 84, 65, 80, 67, 81, + 83, 85, 87, 64, 77, 86, 88, 69, 71, 89, + 72, 81, 90, 84, 70, 73, 75, 80, 91, 86, + 76, 78, 92, 94, 95, 83, 98, 85, 89, 96, + 87, 97, 88, 100, 101, 102, 104, 90, 112, 105, + 98, 94, 106, 117, 91, 92, 114, 101, 108, 95, + 97, 115, 96, 105, 108, 122, 115, 119, 116, 113, + + 100, 118, 102, 104, 106, 111, 118, 110, 112, 109, + 117, 114, 121, 121, 107, 103, 99, 93, 82, 79, + 74, 68, 66, 62, 61, 56, 45, 42, 33, 30, + 28, 12, 9, 5, 3, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int __libipsec_flex_debug; +int __libipsec_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *__libipsectext; +#line 1 "policy_token.l" +/* $NetBSD: policy_token.l,v 1.7 2007/07/18 12:07:50 vanhu Exp $ */ +/* Id: policy_token.l,v 1.12 2005/05/05 12:32:18 manubsd Exp */ +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#line 35 "policy_token.l" +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include +#include + +#include "libpfkey.h" + +#if !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(__linux__) && \ +!defined(__APPLE__) && !defined(__MACH__) +#include "y.tab.h" +#else +#include "policy_parse.h" +#endif +#define yylval __libipseclval /* XXX */ + +int __libipseclex __P((void)); +/* common section */ +#line 630 "policy_token.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int __libipseclex_destroy (void ); + +int __libipsecget_debug (void ); + +void __libipsecset_debug (int debug_flag ); + +YY_EXTRA_TYPE __libipsecget_extra (void ); + +void __libipsecset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *__libipsecget_in (void ); + +void __libipsecset_in (FILE * in_str ); + +FILE *__libipsecget_out (void ); + +void __libipsecset_out (FILE * out_str ); + +yy_size_t __libipsecget_leng (void ); + +char *__libipsecget_text (void ); + +int __libipsecget_lineno (void ); + +void __libipsecset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int __libipsecwrap (void ); +#else +extern int __libipsecwrap (void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( __libipsectext, __libipsecleng, 1, __libipsecout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( __libipsecin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( __libipsecin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, __libipsecin))==0 && ferror(__libipsecin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(__libipsecin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int __libipseclex (void); + +#define YY_DECL int __libipseclex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after __libipsectext and __libipsecleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 97 "policy_token.l" + + +#line 813 "policy_token.c" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! __libipsecin ) + __libipsecin = stdin; + + if ( ! __libipsecout ) + __libipsecout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + __libipsecensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + __libipsec_create_buffer(__libipsecin,YY_BUF_SIZE ); + } + + __libipsec_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of __libipsectext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 121 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 236 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 99 "policy_token.l" +{ yylval.num = IPSEC_DIR_INBOUND; return(DIR); } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 100 "policy_token.l" +{ yylval.num = IPSEC_DIR_OUTBOUND; return(DIR); } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 101 "policy_token.l" +{ +#ifdef HAVE_POLICY_FWD + yylval.num = IPSEC_DIR_FWD; return(DIR); +#else + yylval.num = IPSEC_DIR_INBOUND; return(DIR); +#endif + } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 109 "policy_token.l" +{ return(PRIORITY); } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 110 "policy_token.l" +{ return(PRIORITY); } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 111 "policy_token.l" +{ yylval.num32 = PRIORITY_LOW; return(PRIO_BASE); } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 112 "policy_token.l" +{ yylval.num32 = PRIORITY_DEFAULT; return(PRIO_BASE); } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 113 "policy_token.l" +{ yylval.num32 = PRIORITY_HIGH; return(PRIO_BASE); } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 114 "policy_token.l" +{ return(PLUS); } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 115 "policy_token.l" +{ + yylval.val.len = strlen(__libipsectext); + yylval.val.buf = __libipsectext; + return(PRIO_OFFSET); +} + YY_BREAK +case 11: +YY_RULE_SETUP +#line 121 "policy_token.l" +{ yylval.num = IPSEC_POLICY_DISCARD; return(ACTION); } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 122 "policy_token.l" +{ yylval.num = IPSEC_POLICY_NONE; return(ACTION); } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 123 "policy_token.l" +{ yylval.num = IPSEC_POLICY_IPSEC; return(ACTION); } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 124 "policy_token.l" +{ yylval.num = IPSEC_POLICY_BYPASS; return(ACTION); } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 125 "policy_token.l" +{ yylval.num = IPSEC_POLICY_ENTRUST; return(ACTION); } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 127 "policy_token.l" +{ yylval.num = IPPROTO_ESP; return(PROTOCOL); } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 128 "policy_token.l" +{ yylval.num = IPPROTO_AH; return(PROTOCOL); } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 129 "policy_token.l" +{ yylval.num = IPPROTO_IPCOMP; return(PROTOCOL); } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 131 "policy_token.l" +{ yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 132 "policy_token.l" +{ yylval.num = IPSEC_MODE_TUNNEL; return(MODE); } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 134 "policy_token.l" +{ return(ME); } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 135 "policy_token.l" +{ return(ANY); } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 137 "policy_token.l" +{ yylval.num = IPSEC_LEVEL_DEFAULT; return(LEVEL); } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 138 "policy_token.l" +{ yylval.num = IPSEC_LEVEL_USE; return(LEVEL); } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 139 "policy_token.l" +{ yylval.num = IPSEC_LEVEL_REQUIRE; return(LEVEL); } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 140 "policy_token.l" +{ + yylval.val.len = strlen(__libipsectext + 7); + yylval.val.buf = __libipsectext + 7; + return(LEVEL_SPECIFY); + } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 145 "policy_token.l" +{ yylval.num = IPSEC_LEVEL_UNIQUE; return(LEVEL); } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 146 "policy_token.l" +{ return(SLASH); } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 148 "policy_token.l" +{ + yylval.val.len = strlen(__libipsectext); + yylval.val.buf = __libipsectext; + return(IPADDRESS); + } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 154 "policy_token.l" +{ return(HYPHEN); } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 156 "policy_token.l" +{ + /* Remove leading '[' and trailing ']' */ + yylval.val.buf = __libipsectext + 1; + yylval.val.len = strlen(__libipsectext) - 2; + + return(PORT); + } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 164 "policy_token.l" +{ ; } + YY_BREAK +case 33: +/* rule 33 can match eol */ +YY_RULE_SETUP +#line 165 "policy_token.l" +{ ; } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 167 "policy_token.l" +ECHO; + YY_BREAK +#line 1091 "policy_token.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed __libipsecin at a new source and called + * __libipseclex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = __libipsecin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( __libipsecwrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * __libipsectext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of __libipseclex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + __libipsecrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + __libipsecrestart(__libipsecin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) __libipsecrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 121 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 121 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 120); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + __libipsecrestart(__libipsecin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( __libipsecwrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve __libipsectext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void __libipsecrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + __libipsecensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + __libipsec_create_buffer(__libipsecin,YY_BUF_SIZE ); + } + + __libipsec_init_buffer(YY_CURRENT_BUFFER,input_file ); + __libipsec_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void __libipsec_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * __libipsecpop_buffer_state(); + * __libipsecpush_buffer_state(new_buffer); + */ + __libipsecensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + __libipsec_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (__libipsecwrap()) processing, but the only time this flag + * is looked at is after __libipsecwrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void __libipsec_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + __libipsecin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE __libipsec_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) __libipsecalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in __libipsec_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) __libipsecalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in __libipsec_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + __libipsec_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with __libipsec_create_buffer() + * + */ + void __libipsec_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + __libipsecfree((void *) b->yy_ch_buf ); + + __libipsecfree((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a __libipsecrestart() or at EOF. + */ + static void __libipsec_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + __libipsec_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then __libipsec_init_buffer was _probably_ + * called from __libipsecrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void __libipsec_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + __libipsec_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void __libipsecpush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + __libipsecensure_buffer_stack(); + + /* This block is copied from __libipsec_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from __libipsec_switch_to_buffer. */ + __libipsec_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void __libipsecpop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + __libipsec_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + __libipsec_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void __libipsecensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)__libipsecalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in __libipsecensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)__libipsecrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in __libipsecensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE __libipsec_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) __libipsecalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in __libipsec_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + __libipsec_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to __libipseclex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * __libipsec_scan_bytes() instead. + */ +YY_BUFFER_STATE __libipsec_scan_string (yyconst char * yystr ) +{ + + return __libipsec_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to __libipseclex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE __libipsec_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) __libipsecalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in __libipsec_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = __libipsec_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in __libipsec_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up __libipsectext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + __libipsectext[__libipsecleng] = (yy_hold_char); \ + (yy_c_buf_p) = __libipsectext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + __libipsecleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int __libipsecget_lineno (void) +{ + + return __libipseclineno; +} + +/** Get the input stream. + * + */ +FILE *__libipsecget_in (void) +{ + return __libipsecin; +} + +/** Get the output stream. + * + */ +FILE *__libipsecget_out (void) +{ + return __libipsecout; +} + +/** Get the length of the current token. + * + */ +yy_size_t __libipsecget_leng (void) +{ + return __libipsecleng; +} + +/** Get the current token. + * + */ + +char *__libipsecget_text (void) +{ + return __libipsectext; +} + +/** Set the current line number. + * @param line_number + * + */ +void __libipsecset_lineno (int line_number ) +{ + + __libipseclineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see __libipsec_switch_to_buffer + */ +void __libipsecset_in (FILE * in_str ) +{ + __libipsecin = in_str ; +} + +void __libipsecset_out (FILE * out_str ) +{ + __libipsecout = out_str ; +} + +int __libipsecget_debug (void) +{ + return __libipsec_flex_debug; +} + +void __libipsecset_debug (int bdebug ) +{ + __libipsec_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from __libipseclex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + __libipsecin = stdin; + __libipsecout = stdout; +#else + __libipsecin = (FILE *) 0; + __libipsecout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * __libipseclex_init() + */ + return 0; +} + +/* __libipseclex_destroy is for both reentrant and non-reentrant scanners. */ +int __libipseclex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + __libipsec_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + __libipsecpop_buffer_state(); + } + + /* Destroy the stack itself. */ + __libipsecfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * __libipseclex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *__libipsecalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *__libipsecrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void __libipsecfree (void * ptr ) +{ + free( (char *) ptr ); /* see __libipsecrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 167 "policy_token.l" + + + +void __policy__strbuffer__init__ __P((char *)); +void __policy__strbuffer__free__ __P((void)); + +static YY_BUFFER_STATE strbuffer; + +void +__policy__strbuffer__init__(msg) + char *msg; +{ + if (YY_CURRENT_BUFFER) + __libipsec_delete_buffer(YY_CURRENT_BUFFER); + strbuffer = (YY_BUFFER_STATE)__libipsec_scan_string(msg); + __libipsec_switch_to_buffer(strbuffer); + + return; +} + +void +__policy__strbuffer__free__() +{ + __libipsec_delete_buffer(strbuffer); + + return; +} + diff --git a/ipsec-tools/src/libipsec/policy_token.l b/ipsec-tools/src/libipsec/policy_token.l new file mode 100644 index 00000000..243b6785 --- /dev/null +++ b/ipsec-tools/src/libipsec/policy_token.l @@ -0,0 +1,192 @@ +/* $NetBSD: policy_token.l,v 1.7 2007/07/18 12:07:50 vanhu Exp $ */ + +/* Id: policy_token.l,v 1.12 2005/05/05 12:32:18 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +%{ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include +#include + +#include "libpfkey.h" + +#if !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(__linux__) && \ +!defined(__APPLE__) && !defined(__MACH__) +#include "y.tab.h" +#else +#include "policy_parse.h" +#endif +#define yylval __libipseclval /* XXX */ + +int yylex __P((void)); +%} + +%option noyywrap +%option nounput + +/* common section */ +nl \n +ws [ \t]+ +digit [0-9] +hexdigit [0-9A-Fa-f] +special [()+\|\?\*,] +dot \. +comma \, +hyphen \- +colon \: +slash \/ +bcl \{ +ecl \} +blcl \[ +elcl \] +percent \% +semi \; +plus \+ +usec {dot}{digit}{1,6} +comment \#.* +ccomment "/*" +bracketstring \<[^>]*\> +quotedstring \"[^"]*\" +decstring {digit}+ +hexpair {hexdigit}{hexdigit} +hexstring 0[xX]{hexdigit}+ +octetstring {octet}({dot}{octet})+ +ipaddress [a-zA-Z0-9:\._][a-zA-Z0-9:\._]*(%[a-zA-Z0-9]+)? + +%% + +in { yylval.num = IPSEC_DIR_INBOUND; return(DIR); } +out { yylval.num = IPSEC_DIR_OUTBOUND; return(DIR); } +fwd { +#ifdef HAVE_POLICY_FWD + yylval.num = IPSEC_DIR_FWD; return(DIR); +#else + yylval.num = IPSEC_DIR_INBOUND; return(DIR); +#endif + } + +priority { return(PRIORITY); } +prio { return(PRIORITY); } +low { yylval.num32 = PRIORITY_LOW; return(PRIO_BASE); } +def { yylval.num32 = PRIORITY_DEFAULT; return(PRIO_BASE); } +high { yylval.num32 = PRIORITY_HIGH; return(PRIO_BASE); } +{plus} { return(PLUS); } +{decstring} { + yylval.val.len = strlen(yytext); + yylval.val.buf = yytext; + return(PRIO_OFFSET); +} + +discard { yylval.num = IPSEC_POLICY_DISCARD; return(ACTION); } +none { yylval.num = IPSEC_POLICY_NONE; return(ACTION); } +ipsec { yylval.num = IPSEC_POLICY_IPSEC; return(ACTION); } +bypass { yylval.num = IPSEC_POLICY_BYPASS; return(ACTION); } +entrust { yylval.num = IPSEC_POLICY_ENTRUST; return(ACTION); } + +esp { yylval.num = IPPROTO_ESP; return(PROTOCOL); } +ah { yylval.num = IPPROTO_AH; return(PROTOCOL); } +ipcomp { yylval.num = IPPROTO_IPCOMP; return(PROTOCOL); } + +transport { yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); } +tunnel { yylval.num = IPSEC_MODE_TUNNEL; return(MODE); } + +me { return(ME); } +any { return(ANY); } + +default { yylval.num = IPSEC_LEVEL_DEFAULT; return(LEVEL); } +use { yylval.num = IPSEC_LEVEL_USE; return(LEVEL); } +require { yylval.num = IPSEC_LEVEL_REQUIRE; return(LEVEL); } +unique{colon}{decstring} { + yylval.val.len = strlen(yytext + 7); + yylval.val.buf = yytext + 7; + return(LEVEL_SPECIFY); + } +unique { yylval.num = IPSEC_LEVEL_UNIQUE; return(LEVEL); } +{slash} { return(SLASH); } + +{ipaddress} { + yylval.val.len = strlen(yytext); + yylval.val.buf = yytext; + return(IPADDRESS); + } + +{hyphen} { return(HYPHEN); } + +{blcl}{decstring}{elcl} { + /* Remove leading '[' and trailing ']' */ + yylval.val.buf = yytext + 1; + yylval.val.len = strlen(yytext) - 2; + + return(PORT); + } + +{ws} { ; } +{nl} { ; } + +%% + +void __policy__strbuffer__init__ __P((char *)); +void __policy__strbuffer__free__ __P((void)); + +static YY_BUFFER_STATE strbuffer; + +void +__policy__strbuffer__init__(msg) + char *msg; +{ + if (YY_CURRENT_BUFFER) + yy_delete_buffer(YY_CURRENT_BUFFER); + strbuffer = (YY_BUFFER_STATE)yy_scan_string(msg); + yy_switch_to_buffer(strbuffer); + + return; +} + +void +__policy__strbuffer__free__() +{ + yy_delete_buffer(strbuffer); + + return; +} diff --git a/ipsec-tools/src/libipsec/test-policy.c b/ipsec-tools/src/libipsec/test-policy.c new file mode 100644 index 00000000..a6e6efc4 --- /dev/null +++ b/ipsec-tools/src/libipsec/test-policy.c @@ -0,0 +1,332 @@ +/* $NetBSD: test-policy.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* $KAME: test-policy.c,v 1.16 2003/08/26 03:24:08 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "libpfkey.h" + +struct req_t { + int result; /* expected result; 0:ok 1:ng */ + char *str; +} reqs[] = { +{ 0, "out ipsec" }, +{ 1, "must_error" }, +{ 1, "in ipsec must_error" }, +{ 1, "out ipsec esp/must_error" }, +{ 1, "out discard" }, +{ 1, "out none" }, +{ 0, "in entrust" }, +{ 0, "out entrust" }, +{ 1, "out ipsec esp" }, +{ 0, "in ipsec ah/transport" }, +{ 1, "in ipsec ah/tunnel" }, +{ 0, "out ipsec ah/transport/" }, +{ 1, "out ipsec ah/tunnel/" }, +{ 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" }, +{ 0, "in ipsec esp/tunnel/::1-::2" }, +{ 1, "in ipsec esp/tunnel/10.0.0.1-::2" }, +{ 0, "in ipsec esp/tunnel/::1-::2/require" }, +{ 0, "out ipsec ah/transport//use" }, +{ 1, "out ipsec ah/transport esp/use" }, +{ 1, "in ipsec ah/transport esp/tunnel" }, +{ 0, "in ipsec ah/transport esp/tunnel/::1-::1" }, +{ 0, "in ipsec + ah / transport + esp / tunnel / ::1-::2" }, +{ 0, "out ipsec + ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require + ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require + ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require + " }, +{ 0, "out ipsec esp/transport/fec0::10-fec0::11/use" }, +}; + +int test1 __P((void)); +int test1sub1 __P((struct req_t *)); +int test1sub2 __P((char *, int)); +int test2 __P((void)); +int test2sub __P((int)); + +int +main(ac, av) + int ac; + char **av; +{ + test1(); + test2(); + + exit(0); +} + +int +test1() +{ + int i; + int result; + + printf("TEST1\n"); + for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) { + printf("#%d [%s]\n", i + 1, reqs[i].str); + + result = test1sub1(&reqs[i]); + if (result == 0 && reqs[i].result == 1) { + warnx("ERROR: expecting failure."); + } else if (result == 1 && reqs[i].result == 0) { + warnx("ERROR: expecting success."); + } + } + + return 0; +} + +int +test1sub1(req) + struct req_t *req; +{ + char *buf; + + buf = ipsec_set_policy(req->str, strlen(req->str)); + if (buf == NULL) { + printf("ipsec_set_policy: %s\n", ipsec_strerror()); + return 1; + } + + if (test1sub2(buf, PF_INET) != 0 + || test1sub2(buf, PF_INET6) != 0) { + free(buf); + return 1; + } +#if 0 + kdebug_sadb_x_policy((struct sadb_ext *)buf); +#endif + + free(buf); + return 0; +} + +int +test1sub2(policy, family) + char *policy; + int family; +{ + int so; + int proto = 0, optname = 0; + int len; + char getbuf[1024]; + + switch (family) { + case PF_INET: + proto = IPPROTO_IP; + optname = IP_IPSEC_POLICY; + break; + case PF_INET6: + proto = IPPROTO_IPV6; + optname = IPV6_IPSEC_POLICY; + break; + } + + if ((so = socket(family, SOCK_DGRAM, 0)) < 0) + err(1, "socket"); + + len = ipsec_get_policylen(policy); +#if 0 + printf("\tsetlen:%d\n", len); +#endif + + if (setsockopt(so, proto, optname, policy, len) < 0) { + printf("fail to set sockopt; %s\n", strerror(errno)); + close(so); + return 1; + } + + memset(getbuf, 0, sizeof(getbuf)); + memcpy(getbuf, policy, sizeof(struct sadb_x_policy)); + if (getsockopt(so, proto, optname, getbuf, &len) < 0) { + printf("fail to get sockopt; %s\n", strerror(errno)); + close(so); + return 1; + } + + { + char *buf = NULL; + +#if 0 + printf("\tgetlen:%d\n", len); +#endif + + if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) { + printf("%s\n", ipsec_strerror()); + close(so); + return 1; + } +#if 0 + printf("\t[%s]\n", buf); +#endif + free(buf); + } + + close (so); + return 0; +} + +char addr[] = { + 28, 28, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, +}; + +int +test2() +{ + int so; + char *pol1 = "out ipsec"; + char *pol2 = "out ipsec ah/transport//use"; + char *sp1, *sp2; + int splen1, splen2; + int spid; + struct sadb_msg *m; + + printf("TEST2\n"); + if (getuid() != 0) + errx(1, "root privilege required."); + + sp1 = ipsec_set_policy(pol1, strlen(pol1)); + splen1 = ipsec_get_policylen(sp1); + sp2 = ipsec_set_policy(pol2, strlen(pol2)); + splen2 = ipsec_get_policylen(sp2); + + if ((so = pfkey_open()) < 0) + errx(1, "ERROR: %s", ipsec_strerror()); + + printf("spdflush()\n"); + if (pfkey_send_spdflush(so) < 0) + errx(1, "ERROR: %s", ipsec_strerror()); + m = pfkey_recv(so); + free(m); + + printf("spdsetidx()\n"); + if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128, + (struct sockaddr *)addr, 128, + 255, sp1, splen1, 0) < 0) + errx(1, "ERROR: %s", ipsec_strerror()); + m = pfkey_recv(so); + free(m); + + printf("spdupdate()\n"); + if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128, + (struct sockaddr *)addr, 128, + 255, sp2, splen2, 0) < 0) + errx(1, "ERROR: %s", ipsec_strerror()); + m = pfkey_recv(so); + free(m); + + printf("sleep(4)\n"); + sleep(4); + + printf("spddelete()\n"); + if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128, + (struct sockaddr *)addr, 128, + 255, sp1, splen1, 0) < 0) + errx(1, "ERROR: %s", ipsec_strerror()); + m = pfkey_recv(so); + free(m); + + printf("spdadd()\n"); + if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128, + (struct sockaddr *)addr, 128, + 255, sp2, splen2, 0) < 0) + errx(1, "ERROR: %s", ipsec_strerror()); + spid = test2sub(so); + + printf("spdget(%u)\n", spid); + if (pfkey_send_spdget(so, spid) < 0) + errx(1, "ERROR: %s", ipsec_strerror()); + m = pfkey_recv(so); + free(m); + + printf("sleep(4)\n"); + sleep(4); + + printf("spddelete2()\n"); + if (pfkey_send_spddelete2(so, spid) < 0) + errx(1, "ERROR: %s", ipsec_strerror()); + m = pfkey_recv(so); + free(m); + + printf("spdadd() with lifetime's 10(s)\n"); + if (pfkey_send_spdadd2(so, (struct sockaddr *)addr, 128, + (struct sockaddr *)addr, 128, + 255, 0, 10, sp2, splen2, 0) < 0) + errx(1, "ERROR: %s", ipsec_strerror()); + spid = test2sub(so); + + /* expecting failure */ + printf("spdupdate()\n"); + if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128, + (struct sockaddr *)addr, 128, + 255, sp2, splen2, 0) == 0) { + warnx("ERROR: expecting failure."); + } + + return 0; +} + +int +test2sub(so) + int so; +{ + struct sadb_msg *msg; + caddr_t mhp[SADB_EXT_MAX + 1]; + + if ((msg = pfkey_recv(so)) == NULL) + errx(1, "ERROR: pfkey_recv failure."); + if (pfkey_align(msg, mhp) < 0) + errx(1, "ERROR: pfkey_align failure."); + + return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id; +} + diff --git a/ipsec-tools/src/racoon/Makefile.am b/ipsec-tools/src/racoon/Makefile.am new file mode 100644 index 00000000..dbaded96 --- /dev/null +++ b/ipsec-tools/src/racoon/Makefile.am @@ -0,0 +1,129 @@ +# Id: Makefile.am,v 1.23 2005/07/01 08:57:50 manubsd Exp + +sbin_PROGRAMS = racoon racoonctl plainrsa-gen +noinst_PROGRAMS = eaytest +include_racoon_HEADERS = racoonctl.h var.h vmbuf.h misc.h gcmalloc.h admin.h \ + schedule.h sockmisc.h isakmp_var.h isakmp.h isakmp_xauth.h \ + isakmp_cfg.h isakmp_unity.h ipsec_doi.h evt.h +lib_LTLIBRARIES = libracoon.la + +adminsockdir=${localstatedir}/racoon + +BUILT_SOURCES = cfparse.h prsa_par.h +INCLUDES = -I${srcdir}/../libipsec +AM_CFLAGS = -D_GNU_SOURCE @GLIBC_BUGS@ -DSYSCONFDIR=\"${sysconfdir}\" \ + -DADMINPORTDIR=\"${adminsockdir}\" +AM_LDFLAGS = @EXTRA_CRYPTO@ -lcrypto +AM_YFLAGS = -d ${$*_YFLAGS} +AM_LFLAGS = ${$*_LFLAGS} + +prsa_par_YFLAGS = -p prsa +prsa_tok_LFLAGS = -Pprsa -olex.yy.c + +MISSING_ALGOS = \ + missing/crypto/sha2/sha2.c \ + missing/crypto/rijndael/rijndael-api-fst.c \ + missing/crypto/rijndael/rijndael-alg-fst.c + +racoon_SOURCES = \ + main.c session.c isakmp.c handler.c \ + isakmp_ident.c isakmp_agg.c isakmp_base.c \ + isakmp_quick.c isakmp_inf.c isakmp_newg.c \ + gssapi.c dnssec.c getcertsbyname.c privsep.c \ + pfkey.c admin.c evt.c ipsec_doi.c oakley.c grabmyaddr.c vendorid.c \ + policy.c localconf.c remoteconf.c crypto_openssl.c algorithm.c \ + proposal.c sainfo.c strnames.c \ + plog.c logger.c schedule.c str2val.c \ + safefile.c backupsa.c genlist.c rsalist.c \ + cftoken.l cfparse.y prsa_tok.l prsa_par.y +EXTRA_racoon_SOURCES = isakmp_xauth.c isakmp_cfg.c isakmp_unity.c throttle.c \ + isakmp_frag.c nattraversal.c security.c $(MISSING_ALGOS) +racoon_LDADD = $(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) $(LEXLIB) \ + $(SECCTX_OBJS) vmbuf.o sockmisc.o misc.o ../libipsec/libipsec.la +racoon_DEPENDENCIES = \ + $(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) $(SECCTX_OBJS) \ + vmbuf.o sockmisc.o misc.o + +racoonctl_SOURCES = racoonctl.c str2val.c +racoonctl_LDADD = libracoon.la ../libipsec/libipsec.la + +libracoon_la_SOURCES = kmpstat.c vmbuf.c sockmisc.c misc.c +libracoon_la_CFLAGS = -DNOUSE_PRIVSEP $(AM_CFLAGS) + +plainrsa_gen_SOURCES = plainrsa-gen.c plog.c \ + crypto_openssl.c logger.c +EXTRA_plainrsa_gen_SOURCES = $(MISSING_ALGOS) +plainrsa_gen_LDADD = $(CRYPTOBJS) vmbuf.o misc.o +plainrsa_gen_DEPENDENCIES = $(CRYPTOBJS) vmbuf.o misc.o + +eaytest_SOURCES = eaytest.c plog.c logger.c +EXTRA_eaytest_SOURCES = missing/crypto/sha2/sha2.c +eaytest_LDADD = crypto_openssl_test.o vmbuf.o str2val.o misc_noplog.o \ + $(CRYPTOBJS) +eaytest_DEPENDENCIES = crypto_openssl_test.o vmbuf.o str2val.o \ + misc_noplog.o $(CRYPTOBJS) + +noinst_HEADERS = \ + admin.h dnssec.h isakmp_base.h oakley.h session.h \ + admin_var.h dump.h isakmp_ident.h pfkey.h sockmisc.h \ + algorithm.h gcmalloc.h isakmp_inf.h plog.h str2val.h \ + backupsa.h gnuc.h isakmp_newg.h policy.h strnames.h \ + grabmyaddr.h isakmp_quick.h proposal.h var.h evt.h \ + gssapi.h isakmp_var.h vendorid.h nattraversal.h\ + crypto_openssl.h handler.h localconf.h remoteconf.h vmbuf.h \ + debug.h ipsec_doi.h logger.h safefile.h \ + debugrm.h isakmp.h misc.h sainfo.h \ + dhgroup.h isakmp_agg.h netdb_dnssec.h schedule.h \ + isakmp_cfg.h isakmp_xauth.h isakmp_unity.h isakmp_frag.h \ + throttle.h privsep.h \ + cfparse_proto.h cftoken_proto.h genlist.h rsalist.h \ + missing/crypto/sha2/sha2.h missing/crypto/rijndael/rijndael_local.h \ + missing/crypto/rijndael/rijndael-api-fst.h \ + missing/crypto/rijndael/rijndael-alg-fst.h \ + missing/crypto/rijndael/rijndael.h + +man5_MANS = racoon.conf.5 +man8_MANS = racoon.8 racoonctl.8 plainrsa-gen.8 + +EXTRA_DIST = \ + ${man5_MANS} ${man8_MANS} \ + missing/crypto/rijndael/boxes-fst.dat \ + doc/FAQ doc/README.certificate doc/README.gssapi doc/README.plainrsa \ + doc/README.privsep \ + contrib/sp.pl stats.pl \ + samples/psk.txt.sample samples/racoon.conf.sample \ + samples/psk.txt.in samples/racoon.conf.in \ + samples/racoon.conf.sample-gssapi samples/racoon.conf.sample-natt \ + samples/racoon.conf.sample-inherit samples/racoon.conf.sample-plainrsa \ + samples/roadwarrior/README \ + samples/roadwarrior/client/phase1-down.sh \ + samples/roadwarrior/client/phase1-up.sh \ + samples/roadwarrior/client/racoon.conf \ + samples/roadwarrior/server/racoon.conf \ + samples/roadwarrior/server/racoon.conf-radius + +TESTS = eaytest + +install-exec-local: + ${mkinstalldirs} $(DESTDIR)${adminsockdir} + +# special object rules +crypto_openssl_test.o: crypto_openssl.c + $(COMPILE) -DEAYDEBUG -o crypto_openssl_test.o -c $(srcdir)/crypto_openssl.c + +misc_noplog.o: misc.c + $(COMPILE) -DNOUSE_PLOG -o misc_noplog.o -c $(srcdir)/misc.c + +# missing/*.c +strdup.o: $(srcdir)/missing/strdup.c + $(COMPILE) -c $(srcdir)/missing/$*.c +getaddrinfo.o: $(srcdir)/missing/getaddrinfo.c + $(COMPILE) -c $(srcdir)/missing/$*.c +getnameinfo.o: $(srcdir)/missing/getnameinfo.c + $(COMPILE) -c $(srcdir)/missing/$*.c +rijndael-api-fst.o: $(srcdir)/missing/crypto/rijndael/rijndael-api-fst.c + $(COMPILE) -c $(srcdir)/missing/crypto/rijndael/$*.c +rijndael-alg-fst.o: $(srcdir)/missing/crypto/rijndael/rijndael-alg-fst.c + $(COMPILE) -c $(srcdir)/missing/crypto/rijndael/$*.c +sha2.o: $(srcdir)/missing/crypto/sha2/sha2.c + $(COMPILE) -c $(srcdir)/missing/crypto/sha2/$*.c diff --git a/ipsec-tools/src/racoon/Makefile.in b/ipsec-tools/src/racoon/Makefile.in new file mode 100644 index 00000000..2e001f87 --- /dev/null +++ b/ipsec-tools/src/racoon/Makefile.in @@ -0,0 +1,1494 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Id: Makefile.am,v 1.23 2005/07/01 08:57:50 manubsd Exp + + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +sbin_PROGRAMS = racoon$(EXEEXT) racoonctl$(EXEEXT) \ + plainrsa-gen$(EXEEXT) +noinst_PROGRAMS = eaytest$(EXEEXT) +TESTS = eaytest$(EXEEXT) +subdir = src/racoon +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am cftoken.c \ + cfparse.h cfparse.c prsa_tok.c prsa_par.h prsa_par.c \ + $(top_srcdir)/depcomp $(top_srcdir)/ylwrap \ + $(include_racoon_HEADERS) $(noinst_HEADERS) \ + $(top_srcdir)/test-driver TODO +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acracoon.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(sbindir)" \ + "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" \ + "$(DESTDIR)$(include_racoondir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libracoon_la_LIBADD = +am_libracoon_la_OBJECTS = libracoon_la-kmpstat.lo \ + libracoon_la-vmbuf.lo libracoon_la-sockmisc.lo \ + libracoon_la-misc.lo +libracoon_la_OBJECTS = $(am_libracoon_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libracoon_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libracoon_la_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +PROGRAMS = $(noinst_PROGRAMS) $(sbin_PROGRAMS) +am_eaytest_OBJECTS = eaytest.$(OBJEXT) plog.$(OBJEXT) logger.$(OBJEXT) +eaytest_OBJECTS = $(am_eaytest_OBJECTS) +am__DEPENDENCIES_1 = +am_plainrsa_gen_OBJECTS = plainrsa-gen.$(OBJEXT) plog.$(OBJEXT) \ + crypto_openssl.$(OBJEXT) logger.$(OBJEXT) +plainrsa_gen_OBJECTS = $(am_plainrsa_gen_OBJECTS) +am_racoon_OBJECTS = main.$(OBJEXT) session.$(OBJEXT) isakmp.$(OBJEXT) \ + handler.$(OBJEXT) isakmp_ident.$(OBJEXT) isakmp_agg.$(OBJEXT) \ + isakmp_base.$(OBJEXT) isakmp_quick.$(OBJEXT) \ + isakmp_inf.$(OBJEXT) isakmp_newg.$(OBJEXT) gssapi.$(OBJEXT) \ + dnssec.$(OBJEXT) getcertsbyname.$(OBJEXT) privsep.$(OBJEXT) \ + pfkey.$(OBJEXT) admin.$(OBJEXT) evt.$(OBJEXT) \ + ipsec_doi.$(OBJEXT) oakley.$(OBJEXT) grabmyaddr.$(OBJEXT) \ + vendorid.$(OBJEXT) policy.$(OBJEXT) localconf.$(OBJEXT) \ + remoteconf.$(OBJEXT) crypto_openssl.$(OBJEXT) \ + algorithm.$(OBJEXT) proposal.$(OBJEXT) sainfo.$(OBJEXT) \ + strnames.$(OBJEXT) plog.$(OBJEXT) logger.$(OBJEXT) \ + schedule.$(OBJEXT) str2val.$(OBJEXT) safefile.$(OBJEXT) \ + backupsa.$(OBJEXT) genlist.$(OBJEXT) rsalist.$(OBJEXT) \ + cftoken.$(OBJEXT) cfparse.$(OBJEXT) prsa_tok.$(OBJEXT) \ + prsa_par.$(OBJEXT) +racoon_OBJECTS = $(am_racoon_OBJECTS) +am_racoonctl_OBJECTS = racoonctl.$(OBJEXT) str2val.$(OBJEXT) +racoonctl_OBJECTS = $(am_racoonctl_OBJECTS) +racoonctl_DEPENDENCIES = libracoon.la ../libipsec/libipsec.la +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) +LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) +AM_V_LEX = $(am__v_LEX_@AM_V@) +am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) +am__v_LEX_0 = @echo " LEX " $@; +am__v_LEX_1 = +YLWRAP = $(top_srcdir)/ylwrap +am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ + -e s/c++$$/h++/ -e s/c$$/h/ +YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) +LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) +AM_V_YACC = $(am__v_YACC_@AM_V@) +am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) +am__v_YACC_0 = @echo " YACC " $@; +am__v_YACC_1 = +SOURCES = $(libracoon_la_SOURCES) $(eaytest_SOURCES) \ + $(EXTRA_eaytest_SOURCES) $(plainrsa_gen_SOURCES) \ + $(EXTRA_plainrsa_gen_SOURCES) $(racoon_SOURCES) \ + $(EXTRA_racoon_SOURCES) $(racoonctl_SOURCES) +DIST_SOURCES = $(libracoon_la_SOURCES) $(eaytest_SOURCES) \ + $(EXTRA_eaytest_SOURCES) $(plainrsa_gen_SOURCES) \ + $(EXTRA_plainrsa_gen_SOURCES) $(racoon_SOURCES) \ + $(EXTRA_racoon_SOURCES) $(racoonctl_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +man5dir = $(mandir)/man5 +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(man5_MANS) $(man8_MANS) +HEADERS = $(include_racoon_HEADERS) $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGURE_AMFLAGS = @CONFIGURE_AMFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTOBJS = @CRYPTOBJS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_CRYPTO = @EXTRA_CRYPTO@ +FGREP = @FGREP@ +FRAG_OBJS = @FRAG_OBJS@ +GLIBC_BUGS = @GLIBC_BUGS@ +GREP = @GREP@ +HYBRID_OBJS = @HYBRID_OBJS@ +INCLUDE_GLIBC = @INCLUDE_GLIBC@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_OPTS = @INSTALL_OPTS@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KERNEL_INCLUDE = @KERNEL_INCLUDE@ +KRB5_CONFIG = @KRB5_CONFIG@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NATT_OBJS = @NATT_OBJS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RPM = @RPM@ +SECCTX_OBJS = @SECCTX_OBJS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +include_racoondir = @include_racoondir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +include_racoon_HEADERS = racoonctl.h var.h vmbuf.h misc.h gcmalloc.h admin.h \ + schedule.h sockmisc.h isakmp_var.h isakmp.h isakmp_xauth.h \ + isakmp_cfg.h isakmp_unity.h ipsec_doi.h evt.h + +lib_LTLIBRARIES = libracoon.la +adminsockdir = ${localstatedir}/racoon +BUILT_SOURCES = cfparse.h prsa_par.h +INCLUDES = -I${srcdir}/../libipsec +AM_CFLAGS = -D_GNU_SOURCE @GLIBC_BUGS@ -DSYSCONFDIR=\"${sysconfdir}\" \ + -DADMINPORTDIR=\"${adminsockdir}\" + +AM_LDFLAGS = @EXTRA_CRYPTO@ -lcrypto +AM_YFLAGS = -d ${$*_YFLAGS} +AM_LFLAGS = ${$*_LFLAGS} +prsa_par_YFLAGS = -p prsa +prsa_tok_LFLAGS = -Pprsa -olex.yy.c +MISSING_ALGOS = \ + missing/crypto/sha2/sha2.c \ + missing/crypto/rijndael/rijndael-api-fst.c \ + missing/crypto/rijndael/rijndael-alg-fst.c + +racoon_SOURCES = \ + main.c session.c isakmp.c handler.c \ + isakmp_ident.c isakmp_agg.c isakmp_base.c \ + isakmp_quick.c isakmp_inf.c isakmp_newg.c \ + gssapi.c dnssec.c getcertsbyname.c privsep.c \ + pfkey.c admin.c evt.c ipsec_doi.c oakley.c grabmyaddr.c vendorid.c \ + policy.c localconf.c remoteconf.c crypto_openssl.c algorithm.c \ + proposal.c sainfo.c strnames.c \ + plog.c logger.c schedule.c str2val.c \ + safefile.c backupsa.c genlist.c rsalist.c \ + cftoken.l cfparse.y prsa_tok.l prsa_par.y + +EXTRA_racoon_SOURCES = isakmp_xauth.c isakmp_cfg.c isakmp_unity.c throttle.c \ + isakmp_frag.c nattraversal.c security.c $(MISSING_ALGOS) + +racoon_LDADD = $(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) $(LEXLIB) \ + $(SECCTX_OBJS) vmbuf.o sockmisc.o misc.o ../libipsec/libipsec.la + +racoon_DEPENDENCIES = \ + $(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) $(SECCTX_OBJS) \ + vmbuf.o sockmisc.o misc.o + +racoonctl_SOURCES = racoonctl.c str2val.c +racoonctl_LDADD = libracoon.la ../libipsec/libipsec.la +libracoon_la_SOURCES = kmpstat.c vmbuf.c sockmisc.c misc.c +libracoon_la_CFLAGS = -DNOUSE_PRIVSEP $(AM_CFLAGS) +plainrsa_gen_SOURCES = plainrsa-gen.c plog.c \ + crypto_openssl.c logger.c + +EXTRA_plainrsa_gen_SOURCES = $(MISSING_ALGOS) +plainrsa_gen_LDADD = $(CRYPTOBJS) vmbuf.o misc.o +plainrsa_gen_DEPENDENCIES = $(CRYPTOBJS) vmbuf.o misc.o +eaytest_SOURCES = eaytest.c plog.c logger.c +EXTRA_eaytest_SOURCES = missing/crypto/sha2/sha2.c +eaytest_LDADD = crypto_openssl_test.o vmbuf.o str2val.o misc_noplog.o \ + $(CRYPTOBJS) + +eaytest_DEPENDENCIES = crypto_openssl_test.o vmbuf.o str2val.o \ + misc_noplog.o $(CRYPTOBJS) + +noinst_HEADERS = \ + admin.h dnssec.h isakmp_base.h oakley.h session.h \ + admin_var.h dump.h isakmp_ident.h pfkey.h sockmisc.h \ + algorithm.h gcmalloc.h isakmp_inf.h plog.h str2val.h \ + backupsa.h gnuc.h isakmp_newg.h policy.h strnames.h \ + grabmyaddr.h isakmp_quick.h proposal.h var.h evt.h \ + gssapi.h isakmp_var.h vendorid.h nattraversal.h\ + crypto_openssl.h handler.h localconf.h remoteconf.h vmbuf.h \ + debug.h ipsec_doi.h logger.h safefile.h \ + debugrm.h isakmp.h misc.h sainfo.h \ + dhgroup.h isakmp_agg.h netdb_dnssec.h schedule.h \ + isakmp_cfg.h isakmp_xauth.h isakmp_unity.h isakmp_frag.h \ + throttle.h privsep.h \ + cfparse_proto.h cftoken_proto.h genlist.h rsalist.h \ + missing/crypto/sha2/sha2.h missing/crypto/rijndael/rijndael_local.h \ + missing/crypto/rijndael/rijndael-api-fst.h \ + missing/crypto/rijndael/rijndael-alg-fst.h \ + missing/crypto/rijndael/rijndael.h + +man5_MANS = racoon.conf.5 +man8_MANS = racoon.8 racoonctl.8 plainrsa-gen.8 +EXTRA_DIST = \ + ${man5_MANS} ${man8_MANS} \ + missing/crypto/rijndael/boxes-fst.dat \ + doc/FAQ doc/README.certificate doc/README.gssapi doc/README.plainrsa \ + doc/README.privsep \ + contrib/sp.pl stats.pl \ + samples/psk.txt.sample samples/racoon.conf.sample \ + samples/psk.txt.in samples/racoon.conf.in \ + samples/racoon.conf.sample-gssapi samples/racoon.conf.sample-natt \ + samples/racoon.conf.sample-inherit samples/racoon.conf.sample-plainrsa \ + samples/roadwarrior/README \ + samples/roadwarrior/client/phase1-down.sh \ + samples/roadwarrior/client/phase1-up.sh \ + samples/roadwarrior/client/racoon.conf \ + samples/roadwarrior/server/racoon.conf \ + samples/roadwarrior/server/racoon.conf-radius + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .l .lo .log .o .obj .test .test$(EXEEXT) .trs .y +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/racoon/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/racoon/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libracoon.la: $(libracoon_la_OBJECTS) $(libracoon_la_DEPENDENCIES) $(EXTRA_libracoon_la_DEPENDENCIES) + $(AM_V_CCLD)$(libracoon_la_LINK) -rpath $(libdir) $(libracoon_la_OBJECTS) $(libracoon_la_LIBADD) $(LIBS) + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +eaytest$(EXEEXT): $(eaytest_OBJECTS) $(eaytest_DEPENDENCIES) $(EXTRA_eaytest_DEPENDENCIES) + @rm -f eaytest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(eaytest_OBJECTS) $(eaytest_LDADD) $(LIBS) + +plainrsa-gen$(EXEEXT): $(plainrsa_gen_OBJECTS) $(plainrsa_gen_DEPENDENCIES) $(EXTRA_plainrsa_gen_DEPENDENCIES) + @rm -f plainrsa-gen$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(plainrsa_gen_OBJECTS) $(plainrsa_gen_LDADD) $(LIBS) +cfparse.h: cfparse.c + @if test ! -f $@; then rm -f cfparse.c; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) cfparse.c; else :; fi +prsa_par.h: prsa_par.c + @if test ! -f $@; then rm -f prsa_par.c; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) prsa_par.c; else :; fi + +racoon$(EXEEXT): $(racoon_OBJECTS) $(racoon_DEPENDENCIES) $(EXTRA_racoon_DEPENDENCIES) + @rm -f racoon$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(racoon_OBJECTS) $(racoon_LDADD) $(LIBS) + +racoonctl$(EXEEXT): $(racoonctl_OBJECTS) $(racoonctl_DEPENDENCIES) $(EXTRA_racoonctl_DEPENDENCIES) + @rm -f racoonctl$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(racoonctl_OBJECTS) $(racoonctl_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/admin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algorithm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backupsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfparse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cftoken.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_openssl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dnssec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaytest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genlist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcertsbyname.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grabmyaddr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gssapi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/handler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipsec_doi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_agg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_base.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_cfg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_frag.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_ident.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_inf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_newg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_quick.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_unity.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_xauth.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libracoon_la-kmpstat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libracoon_la-misc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libracoon_la-sockmisc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libracoon_la-vmbuf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/localconf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nattraversal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oakley.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pfkey.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plainrsa-gen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plog.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/policy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/privsep.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proposal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prsa_par.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prsa_tok.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/racoonctl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remoteconf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-alg-fst.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-api-fst.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsalist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safefile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sainfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schedule.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/security.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str2val.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strnames.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/throttle.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vendorid.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libracoon_la-kmpstat.lo: kmpstat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -MT libracoon_la-kmpstat.lo -MD -MP -MF $(DEPDIR)/libracoon_la-kmpstat.Tpo -c -o libracoon_la-kmpstat.lo `test -f 'kmpstat.c' || echo '$(srcdir)/'`kmpstat.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libracoon_la-kmpstat.Tpo $(DEPDIR)/libracoon_la-kmpstat.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kmpstat.c' object='libracoon_la-kmpstat.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -c -o libracoon_la-kmpstat.lo `test -f 'kmpstat.c' || echo '$(srcdir)/'`kmpstat.c + +libracoon_la-vmbuf.lo: vmbuf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -MT libracoon_la-vmbuf.lo -MD -MP -MF $(DEPDIR)/libracoon_la-vmbuf.Tpo -c -o libracoon_la-vmbuf.lo `test -f 'vmbuf.c' || echo '$(srcdir)/'`vmbuf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libracoon_la-vmbuf.Tpo $(DEPDIR)/libracoon_la-vmbuf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vmbuf.c' object='libracoon_la-vmbuf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -c -o libracoon_la-vmbuf.lo `test -f 'vmbuf.c' || echo '$(srcdir)/'`vmbuf.c + +libracoon_la-sockmisc.lo: sockmisc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -MT libracoon_la-sockmisc.lo -MD -MP -MF $(DEPDIR)/libracoon_la-sockmisc.Tpo -c -o libracoon_la-sockmisc.lo `test -f 'sockmisc.c' || echo '$(srcdir)/'`sockmisc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libracoon_la-sockmisc.Tpo $(DEPDIR)/libracoon_la-sockmisc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sockmisc.c' object='libracoon_la-sockmisc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -c -o libracoon_la-sockmisc.lo `test -f 'sockmisc.c' || echo '$(srcdir)/'`sockmisc.c + +libracoon_la-misc.lo: misc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -MT libracoon_la-misc.lo -MD -MP -MF $(DEPDIR)/libracoon_la-misc.Tpo -c -o libracoon_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libracoon_la-misc.Tpo $(DEPDIR)/libracoon_la-misc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='misc.c' object='libracoon_la-misc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -c -o libracoon_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c + +sha2.obj: missing/crypto/sha2/sha2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sha2.obj -MD -MP -MF $(DEPDIR)/sha2.Tpo -c -o sha2.obj `if test -f 'missing/crypto/sha2/sha2.c'; then $(CYGPATH_W) 'missing/crypto/sha2/sha2.c'; else $(CYGPATH_W) '$(srcdir)/missing/crypto/sha2/sha2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sha2.Tpo $(DEPDIR)/sha2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='missing/crypto/sha2/sha2.c' object='sha2.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sha2.obj `if test -f 'missing/crypto/sha2/sha2.c'; then $(CYGPATH_W) 'missing/crypto/sha2/sha2.c'; else $(CYGPATH_W) '$(srcdir)/missing/crypto/sha2/sha2.c'; fi` + +rijndael-api-fst.obj: missing/crypto/rijndael/rijndael-api-fst.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rijndael-api-fst.obj -MD -MP -MF $(DEPDIR)/rijndael-api-fst.Tpo -c -o rijndael-api-fst.obj `if test -f 'missing/crypto/rijndael/rijndael-api-fst.c'; then $(CYGPATH_W) 'missing/crypto/rijndael/rijndael-api-fst.c'; else $(CYGPATH_W) '$(srcdir)/missing/crypto/rijndael/rijndael-api-fst.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rijndael-api-fst.Tpo $(DEPDIR)/rijndael-api-fst.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='missing/crypto/rijndael/rijndael-api-fst.c' object='rijndael-api-fst.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rijndael-api-fst.obj `if test -f 'missing/crypto/rijndael/rijndael-api-fst.c'; then $(CYGPATH_W) 'missing/crypto/rijndael/rijndael-api-fst.c'; else $(CYGPATH_W) '$(srcdir)/missing/crypto/rijndael/rijndael-api-fst.c'; fi` + +rijndael-alg-fst.obj: missing/crypto/rijndael/rijndael-alg-fst.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rijndael-alg-fst.obj -MD -MP -MF $(DEPDIR)/rijndael-alg-fst.Tpo -c -o rijndael-alg-fst.obj `if test -f 'missing/crypto/rijndael/rijndael-alg-fst.c'; then $(CYGPATH_W) 'missing/crypto/rijndael/rijndael-alg-fst.c'; else $(CYGPATH_W) '$(srcdir)/missing/crypto/rijndael/rijndael-alg-fst.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rijndael-alg-fst.Tpo $(DEPDIR)/rijndael-alg-fst.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='missing/crypto/rijndael/rijndael-alg-fst.c' object='rijndael-alg-fst.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rijndael-alg-fst.obj `if test -f 'missing/crypto/rijndael/rijndael-alg-fst.c'; then $(CYGPATH_W) 'missing/crypto/rijndael/rijndael-alg-fst.c'; else $(CYGPATH_W) '$(srcdir)/missing/crypto/rijndael/rijndael-alg-fst.c'; fi` + +.l.c: + $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) + +.y.c: + $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man5: $(man5_MANS) + @$(NORMAL_INSTALL) + @list1='$(man5_MANS)'; \ + list2=''; \ + test -n "$(man5dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.5[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ + done; } + +uninstall-man5: + @$(NORMAL_UNINSTALL) + @list='$(man5_MANS)'; test -n "$(man5dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) +install-man8: $(man8_MANS) + @$(NORMAL_INSTALL) + @list1='$(man8_MANS)'; \ + list2=''; \ + test -n "$(man8dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.8[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list='$(man8_MANS)'; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) +install-include_racoonHEADERS: $(include_racoon_HEADERS) + @$(NORMAL_INSTALL) + @list='$(include_racoon_HEADERS)'; test -n "$(include_racoondir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(include_racoondir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(include_racoondir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_racoondir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_racoondir)" || exit $$?; \ + done + +uninstall-include_racoonHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_racoon_HEADERS)'; test -n "$(include_racoondir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(include_racoondir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + else \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +eaytest.log: eaytest$(EXEEXT) + @p='eaytest$(EXEEXT)'; \ + b='eaytest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(include_racoondir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -rm -f cfparse.c + -rm -f cfparse.h + -rm -f cftoken.c + -rm -f prsa_par.c + -rm -f prsa_par.h + -rm -f prsa_tok.c + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstPROGRAMS clean-sbinPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-include_racoonHEADERS install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-exec-local install-libLTLIBRARIES \ + install-sbinPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man5 install-man8 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-include_racoonHEADERS uninstall-libLTLIBRARIES \ + uninstall-man uninstall-sbinPROGRAMS + +uninstall-man: uninstall-man5 uninstall-man8 + +.MAKE: all check check-am install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstPROGRAMS clean-sbinPROGRAMS cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-exec-local install-html \ + install-html-am install-include_racoonHEADERS install-info \ + install-info-am install-libLTLIBRARIES install-man \ + install-man5 install-man8 install-pdf install-pdf-am \ + install-ps install-ps-am install-sbinPROGRAMS install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am \ + uninstall-include_racoonHEADERS uninstall-libLTLIBRARIES \ + uninstall-man uninstall-man5 uninstall-man8 \ + uninstall-sbinPROGRAMS + + +install-exec-local: + ${mkinstalldirs} $(DESTDIR)${adminsockdir} + +# special object rules +crypto_openssl_test.o: crypto_openssl.c + $(COMPILE) -DEAYDEBUG -o crypto_openssl_test.o -c $(srcdir)/crypto_openssl.c + +misc_noplog.o: misc.c + $(COMPILE) -DNOUSE_PLOG -o misc_noplog.o -c $(srcdir)/misc.c + +# missing/*.c +strdup.o: $(srcdir)/missing/strdup.c + $(COMPILE) -c $(srcdir)/missing/$*.c +getaddrinfo.o: $(srcdir)/missing/getaddrinfo.c + $(COMPILE) -c $(srcdir)/missing/$*.c +getnameinfo.o: $(srcdir)/missing/getnameinfo.c + $(COMPILE) -c $(srcdir)/missing/$*.c +rijndael-api-fst.o: $(srcdir)/missing/crypto/rijndael/rijndael-api-fst.c + $(COMPILE) -c $(srcdir)/missing/crypto/rijndael/$*.c +rijndael-alg-fst.o: $(srcdir)/missing/crypto/rijndael/rijndael-alg-fst.c + $(COMPILE) -c $(srcdir)/missing/crypto/rijndael/$*.c +sha2.o: $(srcdir)/missing/crypto/sha2/sha2.c + $(COMPILE) -c $(srcdir)/missing/crypto/sha2/$*.c + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ipsec-tools/src/racoon/TODO b/ipsec-tools/src/racoon/TODO new file mode 100644 index 00000000..1507167e --- /dev/null +++ b/ipsec-tools/src/racoon/TODO @@ -0,0 +1,131 @@ +$KAME: TODO,v 1.36 2001/09/19 09:41:39 sakane Exp $ + +Please send any questions or bug reports to snap-users@kame.net. + +TODO list + +URGENT +o The documents for users convenience. +o split log file based on client. printf-like config directive, i.e. + "logfile racoon.%s.log", should be useful here. + -> beware of possible security issue, don't use sprintf() directly! + make validation before giving a string to sprintf(). +o save decrypted IKE packet in tcpdump format +o IPComp SA with wellknown CPI in CPI field. how to handle it? +o better rekey + +MUST +o multiple certificate payload handling. +o To consider the use with certificate infrastructure. PXIX ??? +o kmstat should be improved. +o Informational Exchange processing properly. +o require less configuration. phase 2 is easier (as kernel presents racoon + some hints), phase 1 is harder. for example, + - grab phase 2 lifetime and algorith configuration from sadb_comb payloads in + ACQUIRE message. + - give reasonable default behavior when no configuration file is present. + - difficult items: + how to guess a reasonable phase 1 SA lifetime + (hardcoded default? guess from phase 2 lifetime?) + guess what kind of ID payload to use + guess what kind of authentication to be used + guess phase 1 DH group (for aggressive mode, we cannot negotiate it) + guess if we need phase 2 PFS or not (we cannot negotiate it. so + we may need to pick from "no PFS" or "same as phase 1 DH group") + guess how we should negotiate lifetime + (is "strict" a reasonable default?) + guess which mode to use for phase 1 negotiation (is main mode useful? + is base mode popular enough?) +o more acceptable check. + +SHOULD +o psk.txt should be a database? (psk.db?) psk_mkdb? +o Dynamically retry to exchange and resend the packet per nodes. +o To make the list of supported algorithm by sadb_supported payload + in the SADB_REGISTER message which happens asynchronously. +o fix the structure of ph2handle. + We can handle the below case. + + node A node B + +--------------SA1----------------+ + +--------------SA2----------------+ + + at node A: + kernel + acquire(A-B) ------> ph2handle(A=B) -----> ph1handle + | + policy + A=B + A=B + + But we can not handle the below case because there is no x?handle. + + node A node B node C + +--------------SA1----------------+ + +------------------------------------------------SA2---------------+ + + at node A: + kernel + acquire(A-C) ---+---> x?handle ---+---> ph2handle(A=B) -------> ph1handle + | | | + acquire(A-B) ---+ policy +---> ph2handle(A=C) -------> ph1handle + A=B + A=C + +o consistency of function name. +o deep copy configuration entry to hander. It's easy to reload configuration. +o don't keep to hold keymat values, do it ? +o local address's field in isakmpsa handler must be kicked out to rmconf. +o responder policy and initiator policy should be separated. +o for lifetime and key length, something like this should be useful. + - propose N + - accept between X and Y +o wildcard "accept any proposal" policy should be allowed. +o replay prevention + - limited total number of session + - limited session per peer + - number of proposal +o full support for variable length SPI. quickhack support for IPComp is done. + +MAY +o Effective code. +o interaction between IKE/IPsec and socket layer. + at this moment, IKE/IPsec failure is modeled as total packet loss to other + part of network subsystem, including socket layer. this presents the + following behaviors: + - annoyingly long timeouts on tcp connection attempt, and IKE failure; + need to wait till tcp socket timeouts. + - blackhole if there's mismatching SAs. + we may be able to give socket layer some feedback from IKE/IPsec layer. + still not sure if those make sense or not. + for example: + - send PRU_HOSTDEAD to sockets if IKE negotiation failed + (sys/netkey/key.c:key_acquire2) + to do this, we need to remember which ACQUIRE was caused by which socket, + possibly into larval SAs. + - PRU_QUENCH on "no SA found on output" + - kick tcp retransmission timer on first SA establishment +o IKE daemon should handle situations where peer does not run IKE daemon + (UDP port unreach for port 500) better. + should use connected UDP sockets for sending IKE datagrams. +o rate-limit log messages from kernel IPsec errors, like "no SA found". + +TO BE TESTED. +o IKE retransmit behavior + see, draft-*-ipsec-rekeying*.txt +o Reboot recovery (peer reboot losing it's security associations) + see, draft-*-ipsec-rekeying*.txt +o Scenarios + - End-to-End transport long lived security associations + (over night, data transfer >1Gb) with frequent dynamic rekey + - End-to-GW tunnel long lived security associations + (over night, data transfer >1Gb) with frequent dynamic rekey + - Policy change events while under SA load + - End-to-End SA through IPsec tunnels, initiation both ways + - Client End-to-End through client-to-GW tunnel SA, initiate from + client for tunnel, then initiation both ways for end-to-end + - Client-to-GW transport SA for secure management +o behavior to receive multiple auth method proposals and AND proposal + +and to be written many many. + diff --git a/ipsec-tools/src/racoon/admin.c b/ipsec-tools/src/racoon/admin.c new file mode 100644 index 00000000..4b1875bc --- /dev/null +++ b/ipsec-tools/src/racoon/admin.c @@ -0,0 +1,775 @@ +/* $NetBSD: admin.c,v 1.38.4.1 2013/06/03 05:49:59 tteras Exp $ */ + +/* Id: admin.c,v 1.25 2006/04/06 14:31:04 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include PATH_IPSEC_H + + +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef ENABLE_HYBRID +#include +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "debug.h" + +#include "schedule.h" +#include "localconf.h" +#include "remoteconf.h" +#include "grabmyaddr.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "oakley.h" +#include "handler.h" +#include "evt.h" +#include "pfkey.h" +#include "ipsec_doi.h" +#include "policy.h" +#include "admin.h" +#include "admin_var.h" +#include "isakmp_inf.h" +#ifdef ENABLE_HYBRID +#include "isakmp_cfg.h" +#endif +#include "session.h" +#include "gcmalloc.h" + +#ifdef ENABLE_ADMINPORT +char *adminsock_path = ADMINSOCK_PATH; +uid_t adminsock_owner = 0; +gid_t adminsock_group = 0; +mode_t adminsock_mode = 0600; + +static struct sockaddr_un sunaddr; +static int admin_process __P((int, char *)); +static int admin_reply __P((int, struct admin_com *, int, vchar_t *)); + +static int +admin_handler(ctx, fd) + void *ctx; + int fd; +{ + int so2; + struct sockaddr_storage from; + socklen_t fromlen = sizeof(from); + struct admin_com com; + char *combuf = NULL; + int len, error = -1; + + so2 = accept(lcconf->sock_admin, (struct sockaddr *)&from, &fromlen); + if (so2 < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to accept admin command: %s\n", + strerror(errno)); + return -1; + } + close_on_exec(so2); + + /* get buffer length */ + while ((len = recv(so2, (char *)&com, sizeof(com), MSG_PEEK)) < 0) { + if (errno == EINTR) + continue; + plog(LLV_ERROR, LOCATION, NULL, + "failed to recv admin command: %s\n", + strerror(errno)); + goto end; + } + + /* sanity check */ + if (len < sizeof(com)) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid header length of admin command\n"); + goto end; + } + + /* get buffer to receive */ + if ((combuf = racoon_malloc(com.ac_len)) == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to alloc buffer for admin command\n"); + goto end; + } + + /* get real data */ + while ((len = recv(so2, combuf, com.ac_len, 0)) < 0) { + if (errno == EINTR) + continue; + plog(LLV_ERROR, LOCATION, NULL, + "failed to recv admin command: %s\n", + strerror(errno)); + goto end; + } + + error = admin_process(so2, combuf); + +end: + if (error == -2) { + plog(LLV_DEBUG, LOCATION, NULL, + "[%d] admin connection established\n", so2); + } else { + (void)close(so2); + } + + if (combuf) + racoon_free(combuf); + + return error; +} + +static int admin_ph1_delete_sa(struct ph1handle *iph1, void *arg) +{ + if (iph1->status >= PHASE1ST_ESTABLISHED) + isakmp_info_send_d1(iph1); + purge_remote(iph1); + return 0; +} + +/* + * main child's process. + */ +static int +admin_process(so2, combuf) + int so2; + char *combuf; +{ + struct admin_com *com = (struct admin_com *)combuf; + vchar_t *buf = NULL; + vchar_t *id = NULL; + vchar_t *key = NULL; + int idtype = 0; + int error = 0, l_ac_errno = 0; + struct evt_listener_list *event_list = NULL; + + if (com->ac_cmd & ADMIN_FLAG_VERSION) + com->ac_cmd &= ~ADMIN_FLAG_VERSION; + else + com->ac_version = 0; + + switch (com->ac_cmd) { + case ADMIN_RELOAD_CONF: + signal_handler(SIGHUP); + break; + + case ADMIN_SHOW_SCHED: { + caddr_t p = NULL; + int len; + + if (sched_dump(&p, &len) != -1) { + buf = vmalloc(len); + if (buf != NULL) + memcpy(buf->v, p, len); + else + l_ac_errno = ENOMEM; + racoon_free(p); + } else + l_ac_errno = ENOMEM; + break; + } + + case ADMIN_SHOW_EVT: + if (com->ac_version == 0) { + buf = evt_dump(); + l_ac_errno = 0; + } + break; + + case ADMIN_SHOW_SA: + switch (com->ac_proto) { + case ADMIN_PROTO_ISAKMP: + buf = dumpph1(); + if (buf == NULL) + l_ac_errno = ENOMEM; + break; + case ADMIN_PROTO_IPSEC: + case ADMIN_PROTO_AH: + case ADMIN_PROTO_ESP: { + u_int p; + p = admin2pfkey_proto(com->ac_proto); + if (p != -1) { + buf = pfkey_dump_sadb(p); + if (buf == NULL) + l_ac_errno = ENOMEM; + } else + l_ac_errno = EINVAL; + break; + } + case ADMIN_PROTO_INTERNAL: + default: + l_ac_errno = ENOTSUP; + break; + } + break; + + case ADMIN_GET_SA_CERT: { + struct admin_com_indexes *ndx; + struct sockaddr *src, *dst; + struct ph1handle *iph1; + + ndx = (struct admin_com_indexes *) ((caddr_t)com + sizeof(*com)); + src = (struct sockaddr *) &ndx->src; + dst = (struct sockaddr *) &ndx->dst; + + if (com->ac_proto != ADMIN_PROTO_ISAKMP) { + l_ac_errno = ENOTSUP; + break; + } + + iph1 = getph1byaddr(src, dst, 0); + if (iph1 == NULL) { + l_ac_errno = ENOENT; + break; + } + + if (iph1->cert_p != NULL) { + vchar_t tmp; + tmp.v = iph1->cert_p->v + 1; + tmp.l = iph1->cert_p->l - 1; + buf = vdup(&tmp); + } + break; + } + + case ADMIN_FLUSH_SA: + switch (com->ac_proto) { + case ADMIN_PROTO_ISAKMP: + flushph1(); + break; + case ADMIN_PROTO_IPSEC: + case ADMIN_PROTO_AH: + case ADMIN_PROTO_ESP: + pfkey_flush_sadb(com->ac_proto); + break; + case ADMIN_PROTO_INTERNAL: + /*XXX flushph2();*/ + default: + l_ac_errno = ENOTSUP; + break; + } + break; + + case ADMIN_DELETE_SA: { + char *loc, *rem; + struct ph1selector sel; + + memset(&sel, 0, sizeof(sel)); + sel.local = (struct sockaddr *) + &((struct admin_com_indexes *) + ((caddr_t)com + sizeof(*com)))->src; + sel.remote = (struct sockaddr *) + &((struct admin_com_indexes *) + ((caddr_t)com + sizeof(*com)))->dst; + + loc = racoon_strdup(saddr2str(sel.local)); + rem = racoon_strdup(saddr2str(sel.remote)); + STRDUP_FATAL(loc); + STRDUP_FATAL(rem); + + plog(LLV_INFO, LOCATION, NULL, + "admin delete-sa %s %s\n", loc, rem); + enumph1(&sel, admin_ph1_delete_sa, NULL); + remcontacted(sel.remote); + + racoon_free(loc); + racoon_free(rem); + break; + } + +#ifdef ENABLE_HYBRID + case ADMIN_LOGOUT_USER: { + struct ph1handle *iph1; + char user[LOGINLEN+1]; + int found = 0, len = com->ac_len - sizeof(*com); + + if (len > LOGINLEN) { + plog(LLV_ERROR, LOCATION, NULL, + "malformed message (login too long)\n"); + break; + } + + memcpy(user, (char *)(com + 1), len); + user[len] = 0; + + found = purgeph1bylogin(user); + plog(LLV_INFO, LOCATION, NULL, + "deleted %d SA for user \"%s\"\n", found, user); + + break; + } +#endif + + case ADMIN_DELETE_ALL_SA_DST: { + struct ph1handle *iph1; + struct sockaddr *dst; + char *loc, *rem; + + dst = (struct sockaddr *) + &((struct admin_com_indexes *) + ((caddr_t)com + sizeof(*com)))->dst; + + rem = racoon_strdup(saddrwop2str(dst)); + STRDUP_FATAL(rem); + + plog(LLV_INFO, LOCATION, NULL, + "Flushing all SAs for peer %s\n", rem); + + while ((iph1 = getph1bydstaddr(dst)) != NULL) { + loc = racoon_strdup(saddrwop2str(iph1->local)); + STRDUP_FATAL(loc); + + if (iph1->status >= PHASE1ST_ESTABLISHED) + isakmp_info_send_d1(iph1); + purge_remote(iph1); + + racoon_free(loc); + } + + racoon_free(rem); + break; + } + + case ADMIN_ESTABLISH_SA_PSK: { + struct admin_com_psk *acp; + char *data; + + acp = (struct admin_com_psk *) + ((char *)com + sizeof(*com) + + sizeof(struct admin_com_indexes)); + + idtype = acp->id_type; + + if ((id = vmalloc(acp->id_len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot allocate memory: %s\n", + strerror(errno)); + break; + } + data = (char *)(acp + 1); + memcpy(id->v, data, id->l); + + if ((key = vmalloc(acp->key_len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot allocate memory: %s\n", + strerror(errno)); + vfree(id); + id = NULL; + break; + } + data = (char *)(data + acp->id_len); + memcpy(key->v, data, key->l); + } + /* FALLTHROUGH */ + case ADMIN_ESTABLISH_SA: { + struct admin_com_indexes *ndx; + struct sockaddr *dst; + struct sockaddr *src; + char *name = NULL; + + ndx = (struct admin_com_indexes *) ((caddr_t)com + sizeof(*com)); + src = (struct sockaddr *) &ndx->src; + dst = (struct sockaddr *) &ndx->dst; + + if (com->ac_cmd == ADMIN_ESTABLISH_SA && + com->ac_len > sizeof(*com) + sizeof(*ndx)) + name = (char *) ((caddr_t) ndx + sizeof(*ndx)); + + switch (com->ac_proto) { + case ADMIN_PROTO_ISAKMP: { + struct ph1handle *ph1; + struct remoteconf *rmconf; + u_int16_t port; + + l_ac_errno = -1; + + /* connected already? */ + ph1 = getph1byaddr(src, dst, 0); + if (ph1 != NULL) { + event_list = &ph1->evt_listeners; + if (ph1->status == PHASE1ST_ESTABLISHED) + l_ac_errno = EEXIST; + else + l_ac_errno = 0; + break; + } + + /* search appropreate configuration */ + if (name == NULL) + rmconf = getrmconf(dst, 0); + else + rmconf = getrmconf_by_name(name); + if (rmconf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no configuration found " + "for %s\n", saddrwop2str(dst)); + break; + } + +#ifdef ENABLE_HYBRID + /* XXX This overwrites rmconf information globally. */ + /* Set the id and key */ + if (id && key) { + if (xauth_rmconf_used(&rmconf->xauth) == -1) + break; + + if (rmconf->xauth->login != NULL) { + vfree(rmconf->xauth->login); + rmconf->xauth->login = NULL; + } + if (rmconf->xauth->pass != NULL) { + vfree(rmconf->xauth->pass); + rmconf->xauth->pass = NULL; + } + + rmconf->xauth->login = id; + rmconf->xauth->pass = key; + } +#endif + + plog(LLV_INFO, LOCATION, NULL, + "accept a request to establish IKE-SA: " + "%s\n", saddrwop2str(dst)); + + /* begin ident mode */ + ph1 = isakmp_ph1begin_i(rmconf, dst, src); + if (ph1 == NULL) + break; + + event_list = &ph1->evt_listeners; + l_ac_errno = 0; + break; + } + case ADMIN_PROTO_AH: + case ADMIN_PROTO_ESP: { + struct ph2handle *iph2; + struct secpolicy *sp_out = NULL, *sp_in = NULL; + struct policyindex spidx; + + l_ac_errno = -1; + + /* got outbound policy */ + memset(&spidx, 0, sizeof(spidx)); + spidx.dir = IPSEC_DIR_OUTBOUND; + memcpy(&spidx.src, src, sizeof(spidx.src)); + memcpy(&spidx.dst, dst, sizeof(spidx.dst)); + spidx.prefs = ndx->prefs; + spidx.prefd = ndx->prefd; + spidx.ul_proto = ndx->ul_proto; + + sp_out = getsp_r(&spidx); + if (sp_out) { + plog(LLV_DEBUG, LOCATION, NULL, + "suitable outbound SP found: %s.\n", + spidx2str(&sp_out->spidx)); + } else { + l_ac_errno = ENOENT; + plog(LLV_NOTIFY, LOCATION, NULL, + "no outbound policy found: %s\n", + spidx2str(&spidx)); + break; + } + + iph2 = getph2byid(src, dst, sp_out->id); + if (iph2 != NULL) { + event_list = &iph2->evt_listeners; + if (iph2->status == PHASE2ST_ESTABLISHED) + l_ac_errno = EEXIST; + else + l_ac_errno = 0; + break; + } + + /* get inbound policy */ + memset(&spidx, 0, sizeof(spidx)); + spidx.dir = IPSEC_DIR_INBOUND; + memcpy(&spidx.src, dst, sizeof(spidx.src)); + memcpy(&spidx.dst, src, sizeof(spidx.dst)); + spidx.prefs = ndx->prefd; + spidx.prefd = ndx->prefs; + spidx.ul_proto = ndx->ul_proto; + + sp_in = getsp_r(&spidx); + if (sp_in) { + plog(LLV_DEBUG, LOCATION, NULL, + "suitable inbound SP found: %s.\n", + spidx2str(&sp_in->spidx)); + } else { + l_ac_errno = ENOENT; + plog(LLV_NOTIFY, LOCATION, NULL, + "no inbound policy found: %s\n", + spidx2str(&spidx)); + break; + } + + /* allocate a phase 2 */ + iph2 = newph2(); + if (iph2 == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate phase2 entry.\n"); + break; + } + iph2->side = INITIATOR; + iph2->satype = admin2pfkey_proto(com->ac_proto); + iph2->spid = sp_out->id; + iph2->seq = pk_getseq(); + iph2->status = PHASE2ST_STATUS2; + + if (sp_out->local && sp_out->remote) { + /* hints available, let's use them */ + iph2->sa_dst = dupsaddr(dst); + iph2->sa_src = dupsaddr(src); + iph2->src = dupsaddr((struct sockaddr *)sp_out->local); + iph2->dst = dupsaddr((struct sockaddr *)sp_out->remote); + } else if (sp_out->req && sp_out->req->saidx.mode == IPSEC_MODE_TUNNEL) { + /* Tunnel mode and no hint, use endpoints */ + iph2->src = dupsaddr((struct sockaddr *)&sp_out->req->saidx.src); + iph2->dst = dupsaddr((struct sockaddr *)&sp_out->req->saidx.dst); + } else { + /* default, use selectors as fallback */ + iph2->sa_dst = dupsaddr(dst); + iph2->sa_src = dupsaddr(src); + iph2->dst = dupsaddr(dst); + iph2->src = dupsaddr(src); + } + + if (iph2->dst == NULL || iph2->src == NULL) { + delph2(iph2); + break; + } + set_port(iph2->dst, 0); + set_port(iph2->src, 0); + + if (isakmp_get_sainfo(iph2, sp_out, sp_in) < 0) { + delph2(iph2); + break; + } + + insph2(iph2); + if (isakmp_post_acquire(iph2, NULL, FALSE) < 0) { + remph2(iph2); + delph2(iph2); + break; + } + + event_list = &iph2->evt_listeners; + l_ac_errno = 0; + break; + } + default: + /* ignore */ + l_ac_errno = ENOTSUP; + } + break; + } + + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid command: %d\n", com->ac_cmd); + l_ac_errno = ENOTSUP; + } + + if ((error = admin_reply(so2, com, l_ac_errno, buf)) != 0) + goto out; + + /* start pushing events if so requested */ + if ((l_ac_errno == 0) && + (com->ac_version >= 1) && + (com->ac_cmd == ADMIN_SHOW_EVT || event_list != NULL)) + error = evt_subscribe(event_list, so2); +out: + if (buf != NULL) + vfree(buf); + + return error; +} + +static int +admin_reply(so, req, l_ac_errno, buf) + int so, l_ac_errno; + struct admin_com *req; + vchar_t *buf; +{ + int tlen; + struct admin_com *combuf; + char *retbuf = NULL; + + if (buf != NULL) + tlen = sizeof(*combuf) + buf->l; + else + tlen = sizeof(*combuf); + + retbuf = racoon_calloc(1, tlen); + if (retbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate admin buffer\n"); + return -1; + } + + combuf = (struct admin_com *) retbuf; + combuf->ac_len = (u_int16_t) tlen; + combuf->ac_cmd = req->ac_cmd & ~ADMIN_FLAG_VERSION; + if (tlen != (u_int32_t) combuf->ac_len && + l_ac_errno == 0) { + combuf->ac_len_high = tlen >> 16; + combuf->ac_cmd |= ADMIN_FLAG_LONG_REPLY; + } else { + combuf->ac_errno = l_ac_errno; + } + combuf->ac_proto = req->ac_proto; + + if (buf != NULL) + memcpy(retbuf + sizeof(*combuf), buf->v, buf->l); + + tlen = send(so, retbuf, tlen, 0); + racoon_free(retbuf); + if (tlen < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send admin command: %s\n", + strerror(errno)); + return -1; + } + + return 0; +} + +/* ADMIN_PROTO -> SADB_SATYPE */ +int +admin2pfkey_proto(proto) + u_int proto; +{ + switch (proto) { + case ADMIN_PROTO_IPSEC: + return SADB_SATYPE_UNSPEC; + case ADMIN_PROTO_AH: + return SADB_SATYPE_AH; + case ADMIN_PROTO_ESP: + return SADB_SATYPE_ESP; + default: + plog(LLV_ERROR, LOCATION, NULL, + "unsupported proto for admin: %d\n", proto); + return -1; + } + /*NOTREACHED*/ +} + +int +admin_init() +{ + if (adminsock_path == NULL) { + lcconf->sock_admin = -1; + return 0; + } + + memset(&sunaddr, 0, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), + "%s", adminsock_path); + + lcconf->sock_admin = socket(AF_UNIX, SOCK_STREAM, 0); + if (lcconf->sock_admin == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "socket: %s\n", strerror(errno)); + return -1; + } + close_on_exec(lcconf->sock_admin); + + unlink(sunaddr.sun_path); + if (bind(lcconf->sock_admin, (struct sockaddr *)&sunaddr, + sizeof(sunaddr)) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "bind(sockname:%s): %s\n", + sunaddr.sun_path, strerror(errno)); + (void)close(lcconf->sock_admin); + return -1; + } + + if (chown(sunaddr.sun_path, adminsock_owner, adminsock_group) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "chown(%s, %d, %d): %s\n", + sunaddr.sun_path, adminsock_owner, + adminsock_group, strerror(errno)); + (void)close(lcconf->sock_admin); + return -1; + } + + if (chmod(sunaddr.sun_path, adminsock_mode) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "chmod(%s, 0%03o): %s\n", + sunaddr.sun_path, adminsock_mode, strerror(errno)); + (void)close(lcconf->sock_admin); + return -1; + } + + if (listen(lcconf->sock_admin, 5) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "listen(sockname:%s): %s\n", + sunaddr.sun_path, strerror(errno)); + (void)close(lcconf->sock_admin); + return -1; + } + + monitor_fd(lcconf->sock_admin, admin_handler, NULL, 0); + plog(LLV_DEBUG, LOCATION, NULL, + "open %s as racoon management.\n", sunaddr.sun_path); + + return 0; +} + +int +admin_close() +{ + unmonitor_fd(lcconf->sock_admin); + close(lcconf->sock_admin); + return 0; +} + +#endif diff --git a/ipsec-tools/src/racoon/admin.h b/ipsec-tools/src/racoon/admin.h new file mode 100644 index 00000000..8cb93824 --- /dev/null +++ b/ipsec-tools/src/racoon/admin.h @@ -0,0 +1,129 @@ +/* $NetBSD: admin.h,v 1.8 2010/11/12 09:08:26 tteras Exp $ */ + +/* Id: admin.h,v 1.11 2005/06/19 22:37:47 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ADMIN_H +#define _ADMIN_H + +#define ADMINSOCK_PATH ADMINPORTDIR "/racoon.sock" + +extern char *adminsock_path; +extern uid_t adminsock_owner; +extern gid_t adminsock_group; +extern mode_t adminsock_mode; + +/* command for administration. */ +/* NOTE: host byte order. */ +struct admin_com { + u_int16_t ac_len; /* total packet length including data */ + u_int16_t ac_cmd; + union { + int16_t ac_un_errno; + uint16_t ac_un_version; + uint16_t ac_un_len_high; + } u; + u_int16_t ac_proto; +}; +#define ac_errno u.ac_un_errno +#define ac_version u.ac_un_version +#define ac_len_high u.ac_un_len_high + +/* + * Version field in request is valid. + */ +#define ADMIN_FLAG_VERSION 0x8000 +#define ADMIN_FLAG_LONG_REPLY 0x8000 + +/* + * No data follows as the data. + * These don't use proto field. + */ +#define ADMIN_RELOAD_CONF 0x0001 +#define ADMIN_SHOW_SCHED 0x0002 +#define ADMIN_SHOW_EVT 0x0003 + +/* + * No data follows as the data. + * These use proto field. + */ +#define ADMIN_SHOW_SA 0x0101 +#define ADMIN_FLUSH_SA 0x0102 + +/* + * The admin_com_indexes follows, see below. + */ +#define ADMIN_DELETE_SA 0x0201 +#define ADMIN_ESTABLISH_SA 0x0202 +#define ADMIN_DELETE_ALL_SA_DST 0x0204 /* All SA for a given peer */ + +#define ADMIN_GET_SA_CERT 0x0206 + +/* + * The admin_com_indexes and admin_com_psk follow, see below. + */ +#define ADMIN_ESTABLISH_SA_PSK 0x0203 + +/* + * user login follows + */ +#define ADMIN_LOGOUT_USER 0x0205 /* Delete SA for a given Xauth user */ + +/* + * Range 0x08xx is reserved for privilege separation, see privsep.h + */ + +/* the value of proto */ +#define ADMIN_PROTO_ISAKMP 0x01ff +#define ADMIN_PROTO_IPSEC 0x02ff +#define ADMIN_PROTO_AH 0x0201 +#define ADMIN_PROTO_ESP 0x0202 +#define ADMIN_PROTO_INTERNAL 0x0301 + +struct admin_com_indexes { + u_int8_t prefs; + u_int8_t prefd; + u_int8_t ul_proto; + u_int8_t reserved; + struct sockaddr_storage src; + struct sockaddr_storage dst; +}; + +struct admin_com_psk { + int id_type; + size_t id_len; + size_t key_len; + /* Followed by id and key */ +}; + +extern int admin2pfkey_proto __P((u_int)); + +#endif /* _ADMIN_H */ diff --git a/ipsec-tools/src/racoon/admin_var.h b/ipsec-tools/src/racoon/admin_var.h new file mode 100644 index 00000000..f4471a34 --- /dev/null +++ b/ipsec-tools/src/racoon/admin_var.h @@ -0,0 +1,40 @@ +/* $NetBSD: admin_var.h,v 1.5 2008/12/23 14:03:12 tteras Exp $ */ + +/* Id: admin_var.h,v 1.7 2004/12/30 00:08:30 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ADMIN_VAR_H +#define _ADMIN_VAR_H + +extern int admin_init __P((void)); +extern int admin_close __P((void)); + +#endif /* _ADMIN_VAR_H */ diff --git a/ipsec-tools/src/racoon/algorithm.c b/ipsec-tools/src/racoon/algorithm.c new file mode 100644 index 00000000..3fd50f6e --- /dev/null +++ b/ipsec-tools/src/racoon/algorithm.c @@ -0,0 +1,957 @@ +/* $NetBSD: algorithm.c,v 1.8 2006/10/06 12:02:27 manu Exp $ */ + +/* Id: algorithm.c,v 1.15 2006/05/23 20:23:09 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "debug.h" + +#include "crypto_openssl.h" +#include "dhgroup.h" +#include "algorithm.h" +#include "oakley.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "ipsec_doi.h" +#include "gcmalloc.h" + +static struct hash_algorithm oakley_hashdef[] = { +{ "md5", algtype_md5, OAKLEY_ATTR_HASH_ALG_MD5, + eay_md5_init, eay_md5_update, + eay_md5_final, eay_md5_hashlen, + eay_md5_one, }, +{ "sha1", algtype_sha1, OAKLEY_ATTR_HASH_ALG_SHA, + eay_sha1_init, eay_sha1_update, + eay_sha1_final, eay_sha1_hashlen, + eay_sha1_one, }, +#ifdef WITH_SHA2 +{ "sha2_256", algtype_sha2_256, OAKLEY_ATTR_HASH_ALG_SHA2_256, + eay_sha2_256_init, eay_sha2_256_update, + eay_sha2_256_final, eay_sha2_256_hashlen, + eay_sha2_256_one, }, +{ "sha2_384", algtype_sha2_384, OAKLEY_ATTR_HASH_ALG_SHA2_384, + eay_sha2_384_init, eay_sha2_384_update, + eay_sha2_384_final, eay_sha2_384_hashlen, + eay_sha2_384_one, }, +{ "sha2_512", algtype_sha2_512, OAKLEY_ATTR_HASH_ALG_SHA2_512, + eay_sha2_512_init, eay_sha2_512_update, + eay_sha2_512_final, eay_sha2_512_hashlen, + eay_sha2_512_one, }, +#endif +}; + +static struct hmac_algorithm oakley_hmacdef[] = { +{ "hmac_md5", algtype_md5, OAKLEY_ATTR_HASH_ALG_MD5, + eay_hmacmd5_init, eay_hmacmd5_update, + eay_hmacmd5_final, NULL, + eay_hmacmd5_one, }, +{ "hmac_sha1", algtype_sha1, OAKLEY_ATTR_HASH_ALG_SHA, + eay_hmacsha1_init, eay_hmacsha1_update, + eay_hmacsha1_final, NULL, + eay_hmacsha1_one, }, +#ifdef WITH_SHA2 +{ "hmac_sha2_256", algtype_sha2_256, OAKLEY_ATTR_HASH_ALG_SHA2_256, + eay_hmacsha2_256_init, eay_hmacsha2_256_update, + eay_hmacsha2_256_final, NULL, + eay_hmacsha2_256_one, }, +{ "hmac_sha2_384", algtype_sha2_384, OAKLEY_ATTR_HASH_ALG_SHA2_384, + eay_hmacsha2_384_init, eay_hmacsha2_384_update, + eay_hmacsha2_384_final, NULL, + eay_hmacsha2_384_one, }, +{ "hmac_sha2_512", algtype_sha2_512, OAKLEY_ATTR_HASH_ALG_SHA2_512, + eay_hmacsha2_512_init, eay_hmacsha2_512_update, + eay_hmacsha2_512_final, NULL, + eay_hmacsha2_512_one, }, +#endif +}; + +static struct enc_algorithm oakley_encdef[] = { +{ "des", algtype_des, OAKLEY_ATTR_ENC_ALG_DES, 8, + eay_des_encrypt, eay_des_decrypt, + eay_des_weakkey, eay_des_keylen, }, +#ifdef HAVE_OPENSSL_IDEA_H +{ "idea", algtype_idea, OAKLEY_ATTR_ENC_ALG_IDEA, 8, + eay_idea_encrypt, eay_idea_decrypt, + eay_idea_weakkey, eay_idea_keylen, }, +#endif +{ "blowfish", algtype_blowfish, OAKLEY_ATTR_ENC_ALG_BLOWFISH, 8, + eay_bf_encrypt, eay_bf_decrypt, + eay_bf_weakkey, eay_bf_keylen, }, +#ifdef HAVE_OPENSSL_RC5_H +{ "rc5", algtype_rc5, OAKLEY_ATTR_ENC_ALG_RC5, 8, + eay_rc5_encrypt, eay_rc5_decrypt, + eay_rc5_weakkey, eay_rc5_keylen, }, +#endif +{ "3des", algtype_3des, OAKLEY_ATTR_ENC_ALG_3DES, 8, + eay_3des_encrypt, eay_3des_decrypt, + eay_3des_weakkey, eay_3des_keylen, }, +{ "cast", algtype_cast128, OAKLEY_ATTR_ENC_ALG_CAST, 8, + eay_cast_encrypt, eay_cast_decrypt, + eay_cast_weakkey, eay_cast_keylen, }, +{ "aes", algtype_aes, OAKLEY_ATTR_ENC_ALG_AES, 16, + eay_aes_encrypt, eay_aes_decrypt, + eay_aes_weakkey, eay_aes_keylen, }, +#ifdef HAVE_OPENSSL_CAMELLIA_H +{ "camellia", algtype_camellia, OAKLEY_ATTR_ENC_ALG_CAMELLIA, 16, + eay_camellia_encrypt, eay_camellia_decrypt, + eay_camellia_weakkey, eay_camellia_keylen, }, +#endif +}; + +static struct enc_algorithm ipsec_encdef[] = { +{ "des-iv64", algtype_des_iv64, IPSECDOI_ESP_DES_IV64, 8, + NULL, NULL, + NULL, eay_des_keylen, }, +{ "des", algtype_des, IPSECDOI_ESP_DES, 8, + NULL, NULL, + NULL, eay_des_keylen, }, +{ "3des", algtype_3des, IPSECDOI_ESP_3DES, 8, + NULL, NULL, + NULL, eay_3des_keylen, }, +#ifdef HAVE_OPENSSL_RC5_H +{ "rc5", algtype_rc5, IPSECDOI_ESP_RC5, 8, + NULL, NULL, + NULL, eay_rc5_keylen, }, +#endif +{ "cast", algtype_cast128, IPSECDOI_ESP_CAST, 8, + NULL, NULL, + NULL, eay_cast_keylen, }, +{ "blowfish", algtype_blowfish, IPSECDOI_ESP_BLOWFISH, 8, + NULL, NULL, + NULL, eay_bf_keylen, }, +{ "des-iv32", algtype_des_iv32, IPSECDOI_ESP_DES_IV32, 8, + NULL, NULL, + NULL, eay_des_keylen, }, +{ "null", algtype_null_enc, IPSECDOI_ESP_NULL, 8, + NULL, NULL, + NULL, eay_null_keylen, }, +{ "aes", algtype_aes, IPSECDOI_ESP_AES, 16, + NULL, NULL, + NULL, eay_aes_keylen, }, +{ "twofish", algtype_twofish, IPSECDOI_ESP_TWOFISH, 16, + NULL, NULL, + NULL, eay_twofish_keylen, }, +#ifdef HAVE_OPENSSL_IDEA_H +{ "3idea", algtype_3idea, IPSECDOI_ESP_3IDEA, 8, + NULL, NULL, + NULL, NULL, }, +{ "idea", algtype_idea, IPSECDOI_ESP_IDEA, 8, + NULL, NULL, + NULL, NULL, }, +#endif +{ "rc4", algtype_rc4, IPSECDOI_ESP_RC4, 8, + NULL, NULL, + NULL, NULL, }, +#ifdef HAVE_OPENSSL_CAMELLIA_H +{ "camellia", algtype_camellia, IPSECDOI_ESP_CAMELLIA, 16, + NULL, NULL, + NULL, eay_camellia_keylen, }, +#endif +}; + +static struct hmac_algorithm ipsec_hmacdef[] = { +{ "md5", algtype_hmac_md5, IPSECDOI_ATTR_AUTH_HMAC_MD5, + NULL, NULL, + NULL, eay_md5_hashlen, + NULL, }, +{ "sha1", algtype_hmac_sha1, IPSECDOI_ATTR_AUTH_HMAC_SHA1, + NULL, NULL, + NULL, eay_sha1_hashlen, + NULL, }, +{ "kpdk", algtype_kpdk, IPSECDOI_ATTR_AUTH_KPDK, + NULL, NULL, + NULL, eay_kpdk_hashlen, + NULL, }, +{ "null", algtype_non_auth, IPSECDOI_ATTR_AUTH_NONE, + NULL, NULL, + NULL, eay_null_hashlen, + NULL, }, +#ifdef WITH_SHA2 +{ "hmac_sha2_256", algtype_hmac_sha2_256,IPSECDOI_ATTR_AUTH_HMAC_SHA2_256, + NULL, NULL, + NULL, eay_sha2_256_hashlen, + NULL, }, +{ "hmac_sha2_384", algtype_hmac_sha2_384,IPSECDOI_ATTR_AUTH_HMAC_SHA2_384, + NULL, NULL, + NULL, eay_sha2_384_hashlen, + NULL, }, +{ "hmac_sha2_512", algtype_hmac_sha2_512,IPSECDOI_ATTR_AUTH_HMAC_SHA2_512, + NULL, NULL, + NULL, eay_sha2_512_hashlen, + NULL, }, +#endif +}; + +static struct misc_algorithm ipsec_compdef[] = { +{ "oui", algtype_oui, IPSECDOI_IPCOMP_OUI, }, +{ "deflate", algtype_deflate, IPSECDOI_IPCOMP_DEFLATE, }, +{ "lzs", algtype_lzs, IPSECDOI_IPCOMP_LZS, }, +}; + +/* + * In case of asymetric modes (hybrid xauth), what's racoon mode of + * operations ; it seems that the proposal should always use the + * initiator half (unless a server initiates a connection, which is + * not handled, and probably not useful). + */ +static struct misc_algorithm oakley_authdef[] = { +{ "pre_shared_key", algtype_psk, OAKLEY_ATTR_AUTH_METHOD_PSKEY, }, +{ "dsssig", algtype_dsssig, OAKLEY_ATTR_AUTH_METHOD_DSSSIG, }, +{ "rsasig", algtype_rsasig, OAKLEY_ATTR_AUTH_METHOD_RSASIG, }, +{ "rsaenc", algtype_rsaenc, OAKLEY_ATTR_AUTH_METHOD_RSAENC, }, +{ "rsarev", algtype_rsarev, OAKLEY_ATTR_AUTH_METHOD_RSAREV, }, + +{ "gssapi_krb", algtype_gssapikrb, + OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, }, + +#ifdef ENABLE_HYBRID +{ "hybrid_rsa_server", algtype_hybrid_rsa_s, + OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, }, + +{ "hybrid_dss_server", algtype_hybrid_dss_s, + OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, }, + +{ "xauth_psk_server", algtype_xauth_psk_s, + OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R, }, + +{ "xauth_rsa_server", algtype_xauth_rsa_s, + OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R, }, + +{ "hybrid_rsa_client", algtype_hybrid_rsa_c, + OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I, }, + +{ "hybrid_dss_client", algtype_hybrid_dss_c, + OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I, }, + +{ "xauth_psk_client", algtype_xauth_psk_c, + OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I, }, + +{ "xauth_rsa_client", algtype_xauth_rsa_c, + OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I, }, +#endif +}; + +static struct dh_algorithm oakley_dhdef[] = { +{ "modp768", algtype_modp768, OAKLEY_ATTR_GRP_DESC_MODP768, + &dh_modp768, }, +{ "modp1024", algtype_modp1024, OAKLEY_ATTR_GRP_DESC_MODP1024, + &dh_modp1024, }, +{ "modp1536", algtype_modp1536, OAKLEY_ATTR_GRP_DESC_MODP1536, + &dh_modp1536, }, +{ "modp2048", algtype_modp2048, OAKLEY_ATTR_GRP_DESC_MODP2048, + &dh_modp2048, }, +{ "modp3072", algtype_modp3072, OAKLEY_ATTR_GRP_DESC_MODP3072, + &dh_modp3072, }, +{ "modp4096", algtype_modp4096, OAKLEY_ATTR_GRP_DESC_MODP4096, + &dh_modp4096, }, +{ "modp6144", algtype_modp6144, OAKLEY_ATTR_GRP_DESC_MODP6144, + &dh_modp6144, }, +{ "modp8192", algtype_modp8192, OAKLEY_ATTR_GRP_DESC_MODP8192, + &dh_modp8192, }, +}; + +static struct hash_algorithm *alg_oakley_hashdef __P((int)); +static struct hmac_algorithm *alg_oakley_hmacdef __P((int)); +static struct enc_algorithm *alg_oakley_encdef __P((int)); +static struct enc_algorithm *alg_ipsec_encdef __P((int)); +static struct hmac_algorithm *alg_ipsec_hmacdef __P((int)); +static struct dh_algorithm *alg_oakley_dhdef __P((int)); + +/* oakley hash algorithm */ +static struct hash_algorithm * +alg_oakley_hashdef(doi) + int doi; +{ + int i; + + for (i = 0; i < ARRAYLEN(oakley_hashdef); i++) + if (doi == oakley_hashdef[i].doi) { + plog(LLV_DEBUG, LOCATION, NULL, "hash(%s)\n", + oakley_hashdef[i].name); + return &oakley_hashdef[i]; + } + return NULL; +} + +int +alg_oakley_hashdef_ok(doi) + int doi; +{ + struct hash_algorithm *f; + + f = alg_oakley_hashdef(doi); + if (f == NULL) + return 0; + + return 1; +} + +int +alg_oakley_hashdef_doi(type) + int type; +{ + int i, res = -1; + + for (i = 0; i < ARRAYLEN(oakley_hashdef); i++) + if (type == oakley_hashdef[i].type) { + res = oakley_hashdef[i].doi; + break; + } + return res; +} + +int +alg_oakley_hashdef_hashlen(doi) + int doi; +{ + struct hash_algorithm *f; + + f = alg_oakley_hashdef(doi); + if (f == NULL || f->hashlen == NULL) + return 0; + + return (f->hashlen)(); +} + +const char * +alg_oakley_hashdef_name (doi) + int doi; +{ + struct hash_algorithm *f; + + f = alg_oakley_hashdef(doi); + if (f == NULL) + return "*UNKNOWN*"; + + return f->name; +} + +vchar_t * +alg_oakley_hashdef_one(doi, buf) + int doi; + vchar_t *buf; +{ + struct hash_algorithm *f; + + f = alg_oakley_hashdef(doi); + if (f == NULL || f->hashlen == NULL) + return NULL; + + return (f->one)(buf); +} + +/* oakley hmac algorithm */ +static struct hmac_algorithm * +alg_oakley_hmacdef(doi) + int doi; +{ + int i; + + for (i = 0; i < ARRAYLEN(oakley_hmacdef); i++) + if (doi == oakley_hmacdef[i].doi) { + plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n", + oakley_hmacdef[i].name); + return &oakley_hmacdef[i]; + } + return NULL; +} + +int +alg_oakley_hmacdef_doi(type) + int type; +{ + int i, res = -1; + + for (i = 0; i < ARRAYLEN(oakley_hmacdef); i++) + if (type == oakley_hmacdef[i].type) { + res = oakley_hmacdef[i].doi; + break; + } + return res; +} + +vchar_t * +alg_oakley_hmacdef_one(doi, key, buf) + int doi; + vchar_t *key, *buf; +{ + struct hmac_algorithm *f; + vchar_t *res; +#ifdef ENABLE_STATS + struct timeval start, end; +#endif + + f = alg_oakley_hmacdef(doi); + if (f == NULL || f->one == NULL) + return NULL; + +#ifdef ENABLE_STATS + gettimeofday(&start, NULL); +#endif + + res = (f->one)(key, buf); + +#ifdef ENABLE_STATS + gettimeofday(&end, NULL); + syslog(LOG_NOTICE, "%s(%s size=%zu): %8.6f", __func__, + f->name, buf->l, timedelta(&start, &end)); +#endif + + return res; +} + +/* oakley encryption algorithm */ +static struct enc_algorithm * +alg_oakley_encdef(doi) + int doi; +{ + int i; + + for (i = 0; i < ARRAYLEN(oakley_encdef); i++) + if (doi == oakley_encdef[i].doi) { + plog(LLV_DEBUG, LOCATION, NULL, "encryption(%s)\n", + oakley_encdef[i].name); + return &oakley_encdef[i]; + } + return NULL; +} + +int +alg_oakley_encdef_ok(doi) + int doi; +{ + struct enc_algorithm *f; + + f = alg_oakley_encdef(doi); + if (f == NULL) + return 0; + + return 1; +} + +int +alg_oakley_encdef_doi(type) + int type; +{ + int i, res = -1; + + for (i = 0; i < ARRAYLEN(oakley_encdef); i++) + if (type == oakley_encdef[i].type) { + res = oakley_encdef[i].doi; + break; + } + return res; +} + +int +alg_oakley_encdef_keylen(doi, len) + int doi, len; +{ + struct enc_algorithm *f; + + f = alg_oakley_encdef(doi); + if (f == NULL || f->keylen == NULL) + return -1; + + return (f->keylen)(len); +} + +int +alg_oakley_encdef_blocklen(doi) + int doi; +{ + struct enc_algorithm *f; + + f = alg_oakley_encdef(doi); + if (f == NULL) + return -1; + + return f->blocklen; +} + +const char * +alg_oakley_encdef_name (doi) + int doi; +{ + struct enc_algorithm *f; + + f = alg_oakley_encdef(doi); + if (f == NULL) + return "*UNKNOWN*"; + + return f->name; +} + +vchar_t * +alg_oakley_encdef_decrypt(doi, buf, key, iv) + int doi; + vchar_t *buf, *key, *iv; +{ + vchar_t *res; + struct enc_algorithm *f; +#ifdef ENABLE_STATS + struct timeval start, end; +#endif + + f = alg_oakley_encdef(doi); + if (f == NULL || f->decrypt == NULL) + return NULL; + +#ifdef ENABLE_STATS + gettimeofday(&start, NULL); +#endif + + res = (f->decrypt)(buf, key, iv); + +#ifdef ENABLE_STATS + gettimeofday(&end, NULL); + syslog(LOG_NOTICE, "%s(%s klen=%zu size=%zu): %8.6f", __func__, + f->name, key->l << 3, buf->l, timedelta(&start, &end)); +#endif + return res; +} + +vchar_t * +alg_oakley_encdef_encrypt(doi, buf, key, iv) + int doi; + vchar_t *buf, *key, *iv; +{ + vchar_t *res; + struct enc_algorithm *f; +#ifdef ENABLE_STATS + struct timeval start, end; +#endif + + f = alg_oakley_encdef(doi); + if (f == NULL || f->encrypt == NULL) + return NULL; + +#ifdef ENABLE_STATS + gettimeofday(&start, NULL); +#endif + + res = (f->encrypt)(buf, key, iv); + +#ifdef ENABLE_STATS + gettimeofday(&end, NULL); + syslog(LOG_NOTICE, "%s(%s klen=%zu size=%zu): %8.6f", __func__, + f->name, key->l << 3, buf->l, timedelta(&start, &end)); +#endif + return res; +} + +/* ipsec encryption algorithm */ +static struct enc_algorithm * +alg_ipsec_encdef(doi) + int doi; +{ + int i; + + for (i = 0; i < ARRAYLEN(ipsec_encdef); i++) + if (doi == ipsec_encdef[i].doi) { + plog(LLV_DEBUG, LOCATION, NULL, "encryption(%s)\n", + ipsec_encdef[i].name); + return &ipsec_encdef[i]; + } + return NULL; +} + +int +alg_ipsec_encdef_doi(type) + int type; +{ + int i, res = -1; + + for (i = 0; i < ARRAYLEN(ipsec_encdef); i++) + if (type == ipsec_encdef[i].type) { + res = ipsec_encdef[i].doi; + break; + } + return res; +} + +int +alg_ipsec_encdef_keylen(doi, len) + int doi, len; +{ + struct enc_algorithm *f; + + f = alg_ipsec_encdef(doi); + if (f == NULL || f->keylen == NULL) + return -1; + + return (f->keylen)(len); +} + +/* ipsec hmac algorithm */ +static struct hmac_algorithm * +alg_ipsec_hmacdef(doi) + int doi; +{ + int i; + + for (i = 0; i < ARRAYLEN(ipsec_hmacdef); i++) + if (doi == ipsec_hmacdef[i].doi) { + plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n", + ipsec_hmacdef[i].name); + return &ipsec_hmacdef[i]; + } + return NULL; +} + +int +alg_ipsec_hmacdef_doi(type) + int type; +{ + int i, res = -1; + + for (i = 0; i < ARRAYLEN(ipsec_hmacdef); i++) + if (type == ipsec_hmacdef[i].type) { + res = ipsec_hmacdef[i].doi; + break; + } + return res; +} + +int +alg_ipsec_hmacdef_hashlen(doi) + int doi; +{ + struct hmac_algorithm *f; + + f = alg_ipsec_hmacdef(doi); + if (f == NULL || f->hashlen == NULL) + return -1; + + return (f->hashlen)(); +} + +/* ip compression */ +int +alg_ipsec_compdef_doi(type) + int type; +{ + int i, res = -1; + + for (i = 0; i < ARRAYLEN(ipsec_compdef); i++) + if (type == ipsec_compdef[i].type) { + res = ipsec_compdef[i].doi; + break; + } + return res; +} + +/* dh algorithm */ +static struct dh_algorithm * +alg_oakley_dhdef(doi) + int doi; +{ + int i; + + for (i = 0; i < ARRAYLEN(oakley_dhdef); i++) + if (doi == oakley_dhdef[i].doi) { + plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n", + oakley_dhdef[i].name); + return &oakley_dhdef[i]; + } + return NULL; +} + +int +alg_oakley_dhdef_ok(doi) + int doi; +{ + struct dh_algorithm *f; + + f = alg_oakley_dhdef(doi); + if (f == NULL) + return 0; + + return 1; +} + +int +alg_oakley_dhdef_doi(type) + int type; +{ + int i, res = -1; + + for (i = 0; i < ARRAYLEN(oakley_dhdef); i++) + if (type == oakley_dhdef[i].type) { + res = oakley_dhdef[i].doi; + break; + } + return res; +} + +struct dhgroup * +alg_oakley_dhdef_group(doi) + int doi; +{ + struct dh_algorithm *f; + + f = alg_oakley_dhdef(doi); + if (f == NULL || f->dhgroup == NULL) + return NULL; + + return f->dhgroup; +} + +const char * +alg_oakley_dhdef_name (doi) + int doi; +{ + struct dh_algorithm *f; + + f = alg_oakley_dhdef(doi); + if (f == NULL) + return "*UNKNOWN*"; + return f->name; +} + +/* authentication method */ +int +alg_oakley_authdef_doi(type) + int type; +{ + int i, res = -1; + + for (i = 0; i < ARRAYLEN(oakley_authdef); i++) + if (type == oakley_authdef[i].type) { + res = oakley_authdef[i].doi; + break; + } + return res; +} + +const char * +alg_oakley_authdef_name (doi) + int doi; +{ + int i; + + for (i = 0; i < ARRAYLEN(oakley_authdef); i++) + if (doi == oakley_authdef[i].doi) { + return oakley_authdef[i].name; + } + return "*UNKNOWN*"; +} + +/* + * give the default key length + * OUT: -1: NG + * 0: fixed key cipher, key length not allowed + * positive: default key length + */ +int +default_keylen(class, type) + int class, type; +{ + + switch (class) { + case algclass_isakmp_enc: + case algclass_ipsec_enc: + break; + default: + return 0; + } + + switch (type) { + case algtype_blowfish: + case algtype_rc5: + case algtype_cast128: + case algtype_aes: + case algtype_twofish: + case algtype_camellia: + return 128; + default: + return 0; + } +} + +/* + * check key length + * OUT: -1: NG + * 0: OK + */ +int +check_keylen(class, type, len) + int class, type, len; +{ + int badrange; + + switch (class) { + case algclass_isakmp_enc: + case algclass_ipsec_enc: + break; + default: + /* unknown class, punt */ + plog(LLV_ERROR, LOCATION, NULL, + "unknown algclass %d\n", class); + return -1; + } + + /* key length must be multiple of 8 bytes - RFC2451 2.2 */ + switch (type) { + case algtype_blowfish: + case algtype_rc5: + case algtype_cast128: + case algtype_aes: + case algtype_twofish: + case algtype_camellia: + if (len % 8 != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "key length %d is not multiple of 8\n", len); + return -1; + } + break; + } + + /* key length range */ + badrange = 0; + switch (type) { + case algtype_blowfish: + if (len < 40 || 448 < len) + badrange++; + break; + case algtype_rc5: + if (len < 40 || 2040 < len) + badrange++; + break; + case algtype_cast128: + if (len < 40 || 128 < len) + badrange++; + break; + case algtype_aes: + if (!(len == 128 || len == 192 || len == 256)) + badrange++; + break; + case algtype_twofish: + if (len < 40 || 256 < len) + badrange++; + break; + case algtype_camellia: + if (!(len == 128 || len == 192 || len == 256)) + badrange++; + break; + default: + if (len) { + plog(LLV_ERROR, LOCATION, NULL, + "key length is not allowed"); + return -1; + } + break; + } + if (badrange) { + plog(LLV_ERROR, LOCATION, NULL, + "key length out of range\n"); + return -1; + } + + return 0; +} + +/* + * convert algorithm type to DOI value. + * OUT -1 : NG + * other: converted. + */ +int +algtype2doi(class, type) + int class, type; +{ + int res = -1; + + switch (class) { + case algclass_ipsec_enc: + res = alg_ipsec_encdef_doi(type); + break; + case algclass_ipsec_auth: + res = alg_ipsec_hmacdef_doi(type); + break; + case algclass_ipsec_comp: + res = alg_ipsec_compdef_doi(type); + break; + case algclass_isakmp_enc: + res = alg_oakley_encdef_doi(type); + break; + case algclass_isakmp_hash: + res = alg_oakley_hashdef_doi(type); + break; + case algclass_isakmp_dh: + res = alg_oakley_dhdef_doi(type); + break; + case algclass_isakmp_ameth: + res = alg_oakley_authdef_doi(type); + break; + } + return res; +} + +/* + * convert algorithm class to DOI value. + * OUT -1 : NG + * other: converted. + */ +int +algclass2doi(class) + int class; +{ + switch (class) { + case algclass_ipsec_enc: + return IPSECDOI_PROTO_IPSEC_ESP; + case algclass_ipsec_auth: + return IPSECDOI_ATTR_AUTH; + case algclass_ipsec_comp: + return IPSECDOI_PROTO_IPCOMP; + case algclass_isakmp_enc: + return OAKLEY_ATTR_ENC_ALG; + case algclass_isakmp_hash: + return OAKLEY_ATTR_HASH_ALG; + case algclass_isakmp_dh: + return OAKLEY_ATTR_GRP_DESC; + case algclass_isakmp_ameth: + return OAKLEY_ATTR_AUTH_METHOD; + default: + return -1; + } + /*NOTREACHED*/ + return -1; +} diff --git a/ipsec-tools/src/racoon/algorithm.h b/ipsec-tools/src/racoon/algorithm.h new file mode 100644 index 00000000..8b631b66 --- /dev/null +++ b/ipsec-tools/src/racoon/algorithm.h @@ -0,0 +1,216 @@ +/* $NetBSD: algorithm.h,v 1.5 2006/10/06 12:02:27 manu Exp $ */ + +/* Id: algorithm.h,v 1.10 2005/04/09 16:25:23 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ALGORITHM_H +#define _ALGORITHM_H + +#include + +/* algorithm class */ +enum { + algclass_ipsec_enc, + algclass_ipsec_auth, + algclass_ipsec_comp, + algclass_isakmp_enc, + algclass_isakmp_hash, + algclass_isakmp_dh, + algclass_isakmp_ameth, /* authentication method. */ +#define MAXALGCLASS 7 +}; + +#define ALG_DEFAULT_KEYLEN 64 + +#define ALGTYPE_NOTHING 0 + +/* algorithm type */ +enum algtype { + algtype_nothing = 0, + + /* enc */ + algtype_des_iv64, + algtype_des, + algtype_3des, + algtype_rc5, + algtype_idea, + algtype_cast128, + algtype_blowfish, + algtype_3idea, + algtype_des_iv32, + algtype_rc4, + algtype_null_enc, + algtype_aes, + algtype_twofish, + algtype_camellia, + + /* ipsec auth */ + algtype_hmac_md5, + algtype_hmac_sha1, + algtype_des_mac, + algtype_kpdk, + algtype_non_auth, + algtype_hmac_sha2_256, + algtype_hmac_sha2_384, + algtype_hmac_sha2_512, + + /* ipcomp */ + algtype_oui, + algtype_deflate, + algtype_lzs, + + /* hash */ + algtype_md5, + algtype_sha1, + algtype_tiger, + algtype_sha2_256, + algtype_sha2_384, + algtype_sha2_512, + + /* dh_group */ + algtype_modp768, + algtype_modp1024, + algtype_ec2n155, + algtype_ec2n185, + algtype_modp1536, + algtype_modp2048, + algtype_modp3072, + algtype_modp4096, + algtype_modp6144, + algtype_modp8192, + + /* authentication method. */ + algtype_psk, + algtype_dsssig, + algtype_rsasig, + algtype_rsaenc, + algtype_rsarev, + algtype_gssapikrb, +#ifdef ENABLE_HYBRID + algtype_hybrid_rsa_s, + algtype_hybrid_dss_s, + algtype_hybrid_rsa_c, + algtype_hybrid_dss_c, + algtype_xauth_psk_s, + algtype_xauth_psk_c, + algtype_xauth_rsa_s, + algtype_xauth_rsa_c, +#endif +}; + +struct hmac_algorithm { + char *name; + int type; + int doi; + caddr_t (*init) __P((vchar_t *)); + void (*update) __P((caddr_t, vchar_t *)); + vchar_t *(*final) __P((caddr_t)); + int (*hashlen) __P((void)); + vchar_t *(*one) __P((vchar_t *, vchar_t *)); +}; + +struct hash_algorithm { + char *name; + int type; + int doi; + caddr_t (*init) __P((void)); + void (*update) __P((caddr_t, vchar_t *)); + vchar_t *(*final) __P((caddr_t)); + int (*hashlen) __P((void)); + vchar_t *(*one) __P((vchar_t *)); +}; + +struct enc_algorithm { + char *name; + int type; + int doi; + int blocklen; + vchar_t *(*encrypt) __P((vchar_t *, vchar_t *, vchar_t *)); + vchar_t *(*decrypt) __P((vchar_t *, vchar_t *, vchar_t *)); + int (*weakkey) __P((vchar_t *)); + int (*keylen) __P((int)); +}; + +/* dh group */ +struct dh_algorithm { + char *name; + int type; + int doi; + struct dhgroup *dhgroup; +}; + +/* ipcomp, auth meth, dh group */ +struct misc_algorithm { + char *name; + int type; + int doi; +}; + +extern int alg_oakley_hashdef_ok __P((int)); +extern int alg_oakley_hashdef_doi __P((int)); +extern int alg_oakley_hashdef_hashlen __P((int)); +extern vchar_t *alg_oakley_hashdef_one __P((int, vchar_t *)); + +extern int alg_oakley_hmacdef_doi __P((int)); +extern vchar_t *alg_oakley_hmacdef_one __P((int, vchar_t *, vchar_t *)); + +extern int alg_oakley_encdef_ok __P((int)); +extern int alg_oakley_encdef_doi __P((int)); +extern int alg_oakley_encdef_keylen __P((int, int)); +extern int alg_oakley_encdef_blocklen __P((int)); +extern vchar_t *alg_oakley_encdef_decrypt __P((int, vchar_t *, vchar_t *, vchar_t *)); +extern vchar_t *alg_oakley_encdef_encrypt __P((int, vchar_t *, vchar_t *, vchar_t *)); + +extern int alg_ipsec_encdef_doi __P((int)); +extern int alg_ipsec_encdef_keylen __P((int, int)); + +extern int alg_ipsec_hmacdef_doi __P((int)); +extern int alg_ipsec_hmacdef_hashlen __P((int)); + +extern int alg_ipsec_compdef_doi __P((int)); + +extern int alg_oakley_dhdef_doi __P((int)); +extern int alg_oakley_dhdef_ok __P((int)); +extern struct dhgroup *alg_oakley_dhdef_group __P((int)); + +extern int alg_oakley_authdef_doi __P((int)); + +extern int default_keylen __P((int, int)); +extern int check_keylen __P((int, int, int)); +extern int algtype2doi __P((int, int)); +extern int algclass2doi __P((int)); + +extern const char *alg_oakley_encdef_name __P((int)); +extern const char *alg_oakley_hashdef_name __P((int)); +extern const char *alg_oakley_dhdef_name __P((int)); +extern const char *alg_oakley_authdef_name __P((int)); + +#endif /* _ALGORITHM_H */ diff --git a/ipsec-tools/src/racoon/backupsa.c b/ipsec-tools/src/racoon/backupsa.c new file mode 100644 index 00000000..82d74ca8 --- /dev/null +++ b/ipsec-tools/src/racoon/backupsa.c @@ -0,0 +1,469 @@ +/* $NetBSD: backupsa.c,v 1.10 2010/04/02 15:15:00 christos Exp $ */ + +/* $KAME: backupsa.c,v 1.16 2001/12/31 20:13:40 thorpej Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include PATH_IPSEC_H + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "str2val.h" +#include "plog.h" +#include "debug.h" + +#include "localconf.h" +#include "sockmisc.h" +#include "safefile.h" +#include "backupsa.h" +#include "libpfkey.h" + +/* + * (time string)%(sa parameter) + * (time string) := ex. Nov 24 18:22:48 1986 + * (sa parameter) := + * src dst satype spi mode reqid wsize \ + * e_type e_keylen a_type a_keylen flags \ + * l_alloc l_bytes l_addtime l_usetime seq keymat + */ +static char *format = "%b %d %T %Y"; /* time format */ +static char *strmon[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +static char *str2tmx __P((char *, struct tm *)); +static int str2num __P((char *, int)); + +/* + * output the sa parameter. + */ +int +backupsa_to_file(sa_args) + struct pfkey_send_sa_args *sa_args; +{ + char buf[1024]; + struct tm *tm; + time_t t; + char *p, *k; + int len, l, i; + FILE *fp; + + p = buf; + len = sizeof(buf); + + t = time(NULL); + tm = localtime(&t); + l = strftime(p, len, format, tm); + p += l; + len -= l; + if (len < 0) + goto err; + + l = snprintf(p, len, "%%"); + if (l < 0 || l >= len) + goto err; + p += l; + len -= l; + if (len < 0) + goto err; + + i = getnameinfo(sa_args->src, sysdep_sa_len(sa_args->src), p, len, NULL, 0, NIFLAGS); + if (i != 0) + goto err; + l = strlen(p); + p += l; + len -= l; + if (len < 0) + goto err; + + l = snprintf(p, len, " "); + if (l < 0 || l >= len) + goto err; + p += l; + len -= l; + if (len < 0) + goto err; + + i = getnameinfo(sa_args->dst, sysdep_sa_len(sa_args->dst), p, len, NULL, 0, NIFLAGS); + if (i != 0) + goto err; + l = strlen(p); + p += l; + len -= l; + if (len < 0) + goto err; + + l = snprintf(p, len, + " %u %lu %u %u %u " + "%u %u %u %u %u " + "%u %llu %llu %llu %u", + sa_args->satype, (unsigned long)ntohl(sa_args->spi), + sa_args->mode, sa_args->reqid, sa_args->wsize, sa_args->e_type, + sa_args->e_keylen, sa_args->a_type, sa_args->a_keylen, + sa_args->flags, sa_args->l_alloc, + (unsigned long long)sa_args->l_bytes, + (unsigned long long)sa_args->l_addtime, + (unsigned long long)sa_args->l_usetime, sa_args->seq); + + if (l < 0 || l >= len) + goto err; + p += l; + len -= l; + if (len < 0) + goto err; + + k = val2str(sa_args->keymat, sa_args->e_keylen + sa_args->a_keylen); + l = snprintf(p, len, " %s", k); + racoon_free(k); + if (l < 0 || l >= len) + goto err; + p += l; + len -= l; + if (len < 0) + goto err; + + /* open the file and write the SA parameter */ + if (safefile(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], 1) != 0 || + (fp = fopen(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], "a")) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to open the backup file %s.\n", + lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]); + return -1; + } + fprintf(fp, "%s\n", buf); + fclose(fp); + + return 0; + +err: + plog(LLV_ERROR, LOCATION, NULL, + "SA cannot be saved to a file.\n"); + return -1; +} + +int +backupsa_from_file() +{ + FILE *fp; + char buf[512]; + struct tm tm; + time_t created, current; + char *p, *q; + size_t keymatlen; + int line; + struct pfkey_send_sa_args sa_args; + + memset(&sa_args, 0, sizeof(sa_args)); + + if (safefile(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], 1) == 0) + fp = fopen(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], "r"); + else + fp = NULL; + if (fp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to open the backup file %s.\n", + lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]); + return -1; + } + + current = time(NULL); + + for(line = 1; fgets(buf, sizeof(buf), fp) != NULL; line++) { + /* comment line */ + if (buf[0] == '#') + continue; + + memset(&tm, 0, sizeof(tm)); + p = str2tmx(buf, &tm); + if (*p != '%') { + err: + plog(LLV_ERROR, LOCATION, NULL, + "illegal format line#%d in %s: %s\n", + line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], + buf); + goto next; + } + created = mktime(&tm); + p++; + + for (q = p; *q != '\0' && !isspace((int)*q); q++) + ; + *q = '\0'; + if ((sa_args.src = str2saddr(p, NULL)) == NULL) + goto next; + p = q + 1; + + for (q = p; *q != '\0' && !isspace((int)*q); q++) + ; + *q = '\0'; + if ((sa_args.dst = str2saddr(p, NULL)) == NULL) + goto next; + p = q + 1; + +#define GETNEXTNUM(value, function) \ +do { \ + char *y; \ + for (q = p; *q != '\0' && !isspace((int)*q); q++) \ + ; \ + *q = '\0'; \ + (value) = function(p, &y, 10); \ + if ((value) == 0 && *y != '\0') \ + goto next; \ + p = q + 1; \ +} while (/*CONSTCOND*/0); + + GETNEXTNUM(sa_args.satype, strtoul); + GETNEXTNUM(sa_args.spi, strtoul); + sa_args.spi = ntohl(sa_args.spi); + GETNEXTNUM(sa_args.mode, strtoul); + GETNEXTNUM(sa_args.reqid, strtoul); + GETNEXTNUM(sa_args.wsize, strtoul); + GETNEXTNUM(sa_args.e_type, strtoul); + GETNEXTNUM(sa_args.e_keylen, strtoul); + GETNEXTNUM(sa_args.a_type, strtoul); + GETNEXTNUM(sa_args.a_keylen, strtoul); + GETNEXTNUM(sa_args.flags, strtoul); + GETNEXTNUM(sa_args.l_alloc, strtoul); + GETNEXTNUM(sa_args.l_bytes, strtouq); + GETNEXTNUM(sa_args.l_addtime, strtouq); + GETNEXTNUM(sa_args.l_usetime, strtouq); + GETNEXTNUM(sa_args.seq, strtoul); + +#undef GETNEXTNUM + + sa_args.keymat = str2val(p, 16, &keymatlen); + if (sa_args.keymat == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "illegal format(keymat) line#%d in %s: %s\n", + line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], + buf); + goto next; + } + + if (created + sa_args.l_addtime < current) { + plog(LLV_DEBUG, LOCATION, NULL, + "ignore this line#%d in %s due to expiration\n", + line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]); + goto next; + } + sa_args.l_addtime -= current - created; + + if (pfkey_send_add2(&sa_args) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "restore SA failed line#%d in %s: %s\n", + line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], + ipsec_strerror()); + } + +next: + if (sa_args.src != NULL) { + racoon_free(sa_args.src); + sa_args.src = NULL; + } + if (sa_args.dst != NULL) { + racoon_free(sa_args.dst); + sa_args.dst = NULL; + } + if (sa_args.keymat != NULL) { + racoon_free(sa_args.keymat); + sa_args.keymat = NULL; + } + } + + fclose(fp); + + /* + * There is a possibility that an abnormal system down will happen + * again before new negotiation will be started. so racoon clears + * the backup file here. it's ok that old SAs are remained in the + * file. any old SA will not be installed because racoon checks the + * lifetime and compare with current time. + */ + + return 0; +} + +int +backupsa_clean() +{ + FILE *fp; + + /* simply return if the file is not defined. */ + if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]) + return 0; + + fp = fopen(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], "w+"); + if (fp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to clean the backup file %s.\n", + lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]); + return -1; + } + fclose(fp); + return 0; +} + +/* + * convert fixed string into the tm structure. + * The fixed string is like 'Nov 24 18:22:48 1986'. + * static char *format = "%b %d %T %Y"; + */ +static char * +str2tmx(char *p, struct tm *tm) +{ + int i, len; + + /* Month */ + for (i = 0; i < sizeof(strmon)/sizeof(strmon[0]); i++) { + if (strncasecmp(p, strmon[i], strlen(strmon[i])) == 0) { + tm->tm_mon = i; + break; + } + } + if (i == sizeof(strmon)/sizeof(strmon[0])) + return 0; + p += strlen(strmon[i]); + if (*p++ != ' ') + return 0; + + /* Day */ + len = 2; + tm->tm_mday = str2num(p, len); + if (tm->tm_mday == -1 || tm->tm_mday > 31) + return 0; + p += len; + if (*p++ != ' ') + return 0; + + /* Hour */ + len = 2; + tm->tm_hour = str2num(p, len); + if (tm->tm_hour == -1 || tm->tm_hour > 24) + return 0; + p += len; + if (*p++ != ':') + return 0; + + /* Min */ + len = 2; + tm->tm_min = str2num(p, len); + if (tm->tm_min == -1 || tm->tm_min > 60) + return 0; + p += len; + if (*p++ != ':') + return 0; + + /* Sec */ + len = 2; + tm->tm_sec = str2num(p, len); + if (tm->tm_sec == -1 || tm->tm_sec > 60) + return 0; + p += len; + if (*p++ != ' ') + return 0; + + /* Year */ + len = 4; + tm->tm_year = str2num(p, len); + if (tm->tm_year == -1 || tm->tm_year < 1900) + return 0; + tm->tm_year -= 1900; + p += len; + + return p; +} + +static int +str2num(p, len) + char *p; + int len; +{ + int res, i; + + res = 0; + for (i = len; i > 0; i--) { + if (!isdigit((int)*p)) + return -1; + res *= 10; + res += *p - '0'; + p++; + } + + return res; +} + +#ifdef TEST +#include +int +main() +{ + struct tm tm; + time_t t; + char *buf = "Nov 24 18:22:48 1986 "; + const char *p; + + memset(&tm, 0, sizeof(tm)); + p = str2tmx(buf, &tm); + printf("[%x]\n", *p); + t = mktime(&tm); + if (t == -1) + printf("mktime failed."); + if ((p = ctime(&t)) == NULL) + p = "?"; + printf("[%s]\n", p); + + exit(0); +} +#endif diff --git a/ipsec-tools/src/racoon/backupsa.h b/ipsec-tools/src/racoon/backupsa.h new file mode 100644 index 00000000..e563791a --- /dev/null +++ b/ipsec-tools/src/racoon/backupsa.h @@ -0,0 +1,41 @@ +/* $NetBSD: backupsa.h,v 1.5 2006/12/09 05:52:57 manu Exp $ */ + +/* Id: backupsa.h,v 1.3 2004/06/11 16:00:15 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _BACKUPSA_H +#define _BACKUPSA_H + +extern int backupsa_to_file __P((struct pfkey_send_sa_args *)); +extern int backupsa_from_file __P((void)); +extern int backupsa_clean __P((void)); + +#endif /* _BACKUPSA_H */ diff --git a/ipsec-tools/src/racoon/cfparse.c b/ipsec-tools/src/racoon/cfparse.c new file mode 100644 index 00000000..19c60e78 --- /dev/null +++ b/ipsec-tools/src/racoon/cfparse.c @@ -0,0 +1,5871 @@ +/* A Bison parser, made by GNU Bison 2.6.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + 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 3 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.6.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* Copy the first part of user declarations. */ +/* Line 336 of yacc.c */ +#line 5 "cfparse.y" + +/* + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 and 2003 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include PATH_IPSEC_H + +#ifdef ENABLE_HYBRID +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "str2val.h" +#include "genlist.h" +#include "debug.h" + +#include "admin.h" +#include "privsep.h" +#include "cfparse_proto.h" +#include "cftoken_proto.h" +#include "algorithm.h" +#include "localconf.h" +#include "policy.h" +#include "sainfo.h" +#include "oakley.h" +#include "pfkey.h" +#include "remoteconf.h" +#include "grabmyaddr.h" +#include "isakmp_var.h" +#include "handler.h" +#include "isakmp.h" +#include "nattraversal.h" +#include "isakmp_frag.h" +#ifdef ENABLE_HYBRID +#include "resolv.h" +#include "isakmp_unity.h" +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif +#include "ipsec_doi.h" +#include "strnames.h" +#include "gcmalloc.h" +#ifdef HAVE_GSSAPI +#include "gssapi.h" +#endif +#include "vendorid.h" +#include "rsalist.h" +#include "crypto_openssl.h" + +struct secprotospec { + int prop_no; + int trns_no; + int strength; /* for isakmp/ipsec */ + int encklen; /* for isakmp/ipsec */ + time_t lifetime; /* for isakmp */ + int lifebyte; /* for isakmp */ + int proto_id; /* for ipsec (isakmp?) */ + int ipsec_level; /* for ipsec */ + int encmode; /* for ipsec */ + int vendorid; /* for isakmp */ + char *gssid; + struct sockaddr *remote; + int algclass[MAXALGCLASS]; + + struct secprotospec *next; /* the tail is the most prefiered. */ + struct secprotospec *prev; +}; + +static int num2dhgroup[] = { + 0, + OAKLEY_ATTR_GRP_DESC_MODP768, + OAKLEY_ATTR_GRP_DESC_MODP1024, + OAKLEY_ATTR_GRP_DESC_EC2N155, + OAKLEY_ATTR_GRP_DESC_EC2N185, + OAKLEY_ATTR_GRP_DESC_MODP1536, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + OAKLEY_ATTR_GRP_DESC_MODP2048, + OAKLEY_ATTR_GRP_DESC_MODP3072, + OAKLEY_ATTR_GRP_DESC_MODP4096, + OAKLEY_ATTR_GRP_DESC_MODP6144, + OAKLEY_ATTR_GRP_DESC_MODP8192 +}; + +static struct remoteconf *cur_rmconf; +static int tmpalgtype[MAXALGCLASS]; +static struct sainfo *cur_sainfo; +static int cur_algclass; +static int oldloglevel = LLV_BASE; + +static struct secprotospec *newspspec __P((void)); +static void insspspec __P((struct remoteconf *, struct secprotospec *)); +void dupspspec_list __P((struct remoteconf *dst, struct remoteconf *src)); +void flushspspec __P((struct remoteconf *)); +static void adminsock_conf __P((vchar_t *, vchar_t *, vchar_t *, int)); + +static int set_isakmp_proposal __P((struct remoteconf *)); +static void clean_tmpalgtype __P((void)); +static int expand_isakmpspec __P((int, int, int *, + int, int, time_t, int, int, int, char *, struct remoteconf *)); + +void freeetypes (struct etypes **etypes); + +static int load_x509(const char *file, char **filenameptr, + vchar_t **certptr) +{ + char path[PATH_MAX]; + + getpathname(path, sizeof(path), LC_PATHTYPE_CERT, file); + *certptr = eay_get_x509cert(path); + if (*certptr == NULL) + return -1; + + *filenameptr = racoon_strdup(file); + STRDUP_FATAL(*filenameptr); + + return 0; +} + +static int process_rmconf() +{ + + /* check a exchange mode */ + if (cur_rmconf->etypes == NULL) { + yyerror("no exchange mode specified.\n"); + return -1; + } + + if (cur_rmconf->idvtype == IDTYPE_UNDEFINED) + cur_rmconf->idvtype = IDTYPE_ADDRESS; + + if (cur_rmconf->idvtype == IDTYPE_ASN1DN) { + if (cur_rmconf->mycertfile) { + if (cur_rmconf->idv) + yywarn("Both CERT and ASN1 ID " + "are set. Hope this is OK.\n"); + /* TODO: Preparse the DN here */ + } else if (cur_rmconf->idv) { + /* OK, using asn1dn without X.509. */ + } else { + yyerror("ASN1 ID not specified " + "and no CERT defined!\n"); + return -1; + } + } + + if (duprmconf_finish(cur_rmconf)) + return -1; + + if (set_isakmp_proposal(cur_rmconf) != 0) + return -1; + + /* DH group settting if aggressive mode is there. */ + if (check_etypeok(cur_rmconf, (void*) ISAKMP_ETYPE_AGG)) { + struct isakmpsa *p; + int b = 0; + + /* DH group */ + for (p = cur_rmconf->proposal; p; p = p->next) { + if (b == 0 || (b && b == p->dh_group)) { + b = p->dh_group; + continue; + } + yyerror("DH group must be equal " + "in all proposals " + "when aggressive mode is " + "used.\n"); + return -1; + } + cur_rmconf->dh_group = b; + + if (cur_rmconf->dh_group == 0) { + yyerror("DH group must be set in the proposal.\n"); + return -1; + } + + /* DH group settting if PFS is required. */ + if (oakley_setdhgroup(cur_rmconf->dh_group, + &cur_rmconf->dhgrp) < 0) { + yyerror("failed to set DH value.\n"); + return -1; + } + } + + insrmconf(cur_rmconf); + + return 0; +} + + +/* Line 336 of yacc.c */ +#line 310 "cfparse.c" + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "y.tab.h". */ +#ifndef YY_Y_TAB_H +# define YY_Y_TAB_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + PRIVSEP = 258, + USER = 259, + GROUP = 260, + CHROOT = 261, + PATH = 262, + PATHTYPE = 263, + INCLUDE = 264, + PFKEY_BUFFER = 265, + LOGGING = 266, + LOGLEV = 267, + PADDING = 268, + PAD_RANDOMIZE = 269, + PAD_RANDOMIZELEN = 270, + PAD_MAXLEN = 271, + PAD_STRICT = 272, + PAD_EXCLTAIL = 273, + LISTEN = 274, + X_ISAKMP = 275, + X_ISAKMP_NATT = 276, + X_ADMIN = 277, + STRICT_ADDRESS = 278, + ADMINSOCK = 279, + DISABLED = 280, + LDAPCFG = 281, + LDAP_HOST = 282, + LDAP_PORT = 283, + LDAP_PVER = 284, + LDAP_BASE = 285, + LDAP_BIND_DN = 286, + LDAP_BIND_PW = 287, + LDAP_SUBTREE = 288, + LDAP_ATTR_USER = 289, + LDAP_ATTR_ADDR = 290, + LDAP_ATTR_MASK = 291, + LDAP_ATTR_GROUP = 292, + LDAP_ATTR_MEMBER = 293, + RADCFG = 294, + RAD_AUTH = 295, + RAD_ACCT = 296, + RAD_TIMEOUT = 297, + RAD_RETRIES = 298, + MODECFG = 299, + CFG_NET4 = 300, + CFG_MASK4 = 301, + CFG_DNS4 = 302, + CFG_NBNS4 = 303, + CFG_DEFAULT_DOMAIN = 304, + CFG_AUTH_SOURCE = 305, + CFG_AUTH_GROUPS = 306, + CFG_SYSTEM = 307, + CFG_RADIUS = 308, + CFG_PAM = 309, + CFG_LDAP = 310, + CFG_LOCAL = 311, + CFG_NONE = 312, + CFG_GROUP_SOURCE = 313, + CFG_ACCOUNTING = 314, + CFG_CONF_SOURCE = 315, + CFG_MOTD = 316, + CFG_POOL_SIZE = 317, + CFG_AUTH_THROTTLE = 318, + CFG_SPLIT_NETWORK = 319, + CFG_SPLIT_LOCAL = 320, + CFG_SPLIT_INCLUDE = 321, + CFG_SPLIT_DNS = 322, + CFG_PFS_GROUP = 323, + CFG_SAVE_PASSWD = 324, + RETRY = 325, + RETRY_COUNTER = 326, + RETRY_INTERVAL = 327, + RETRY_PERSEND = 328, + RETRY_PHASE1 = 329, + RETRY_PHASE2 = 330, + NATT_KA = 331, + ALGORITHM_CLASS = 332, + ALGORITHMTYPE = 333, + STRENGTHTYPE = 334, + SAINFO = 335, + FROM = 336, + REMOTE = 337, + ANONYMOUS = 338, + CLIENTADDR = 339, + INHERIT = 340, + REMOTE_ADDRESS = 341, + EXCHANGE_MODE = 342, + EXCHANGETYPE = 343, + DOI = 344, + DOITYPE = 345, + SITUATION = 346, + SITUATIONTYPE = 347, + CERTIFICATE_TYPE = 348, + CERTTYPE = 349, + PEERS_CERTFILE = 350, + CA_TYPE = 351, + VERIFY_CERT = 352, + SEND_CERT = 353, + SEND_CR = 354, + MATCH_EMPTY_CR = 355, + IDENTIFIERTYPE = 356, + IDENTIFIERQUAL = 357, + MY_IDENTIFIER = 358, + PEERS_IDENTIFIER = 359, + VERIFY_IDENTIFIER = 360, + DNSSEC = 361, + CERT_X509 = 362, + CERT_PLAINRSA = 363, + NONCE_SIZE = 364, + DH_GROUP = 365, + KEEPALIVE = 366, + PASSIVE = 367, + INITIAL_CONTACT = 368, + NAT_TRAVERSAL = 369, + REMOTE_FORCE_LEVEL = 370, + PROPOSAL_CHECK = 371, + PROPOSAL_CHECK_LEVEL = 372, + GENERATE_POLICY = 373, + GENERATE_LEVEL = 374, + SUPPORT_PROXY = 375, + PROPOSAL = 376, + EXEC_PATH = 377, + EXEC_COMMAND = 378, + EXEC_SUCCESS = 379, + EXEC_FAILURE = 380, + GSS_ID = 381, + GSS_ID_ENC = 382, + GSS_ID_ENCTYPE = 383, + COMPLEX_BUNDLE = 384, + DPD = 385, + DPD_DELAY = 386, + DPD_RETRY = 387, + DPD_MAXFAIL = 388, + PH1ID = 389, + XAUTH_LOGIN = 390, + WEAK_PHASE1_CHECK = 391, + REKEY = 392, + PREFIX = 393, + PORT = 394, + PORTANY = 395, + UL_PROTO = 396, + ANY = 397, + IKE_FRAG = 398, + ESP_FRAG = 399, + MODE_CFG = 400, + PFS_GROUP = 401, + LIFETIME = 402, + LIFETYPE_TIME = 403, + LIFETYPE_BYTE = 404, + STRENGTH = 405, + REMOTEID = 406, + SCRIPT = 407, + PHASE1_UP = 408, + PHASE1_DOWN = 409, + PHASE1_DEAD = 410, + NUMBER = 411, + SWITCH = 412, + BOOLEAN = 413, + HEXSTRING = 414, + QUOTEDSTRING = 415, + ADDRSTRING = 416, + ADDRRANGE = 417, + UNITTYPE_BYTE = 418, + UNITTYPE_KBYTES = 419, + UNITTYPE_MBYTES = 420, + UNITTYPE_TBYTES = 421, + UNITTYPE_SEC = 422, + UNITTYPE_MIN = 423, + UNITTYPE_HOUR = 424, + EOS = 425, + BOC = 426, + EOC = 427, + COMMA = 428 + }; +#endif +/* Tokens. */ +#define PRIVSEP 258 +#define USER 259 +#define GROUP 260 +#define CHROOT 261 +#define PATH 262 +#define PATHTYPE 263 +#define INCLUDE 264 +#define PFKEY_BUFFER 265 +#define LOGGING 266 +#define LOGLEV 267 +#define PADDING 268 +#define PAD_RANDOMIZE 269 +#define PAD_RANDOMIZELEN 270 +#define PAD_MAXLEN 271 +#define PAD_STRICT 272 +#define PAD_EXCLTAIL 273 +#define LISTEN 274 +#define X_ISAKMP 275 +#define X_ISAKMP_NATT 276 +#define X_ADMIN 277 +#define STRICT_ADDRESS 278 +#define ADMINSOCK 279 +#define DISABLED 280 +#define LDAPCFG 281 +#define LDAP_HOST 282 +#define LDAP_PORT 283 +#define LDAP_PVER 284 +#define LDAP_BASE 285 +#define LDAP_BIND_DN 286 +#define LDAP_BIND_PW 287 +#define LDAP_SUBTREE 288 +#define LDAP_ATTR_USER 289 +#define LDAP_ATTR_ADDR 290 +#define LDAP_ATTR_MASK 291 +#define LDAP_ATTR_GROUP 292 +#define LDAP_ATTR_MEMBER 293 +#define RADCFG 294 +#define RAD_AUTH 295 +#define RAD_ACCT 296 +#define RAD_TIMEOUT 297 +#define RAD_RETRIES 298 +#define MODECFG 299 +#define CFG_NET4 300 +#define CFG_MASK4 301 +#define CFG_DNS4 302 +#define CFG_NBNS4 303 +#define CFG_DEFAULT_DOMAIN 304 +#define CFG_AUTH_SOURCE 305 +#define CFG_AUTH_GROUPS 306 +#define CFG_SYSTEM 307 +#define CFG_RADIUS 308 +#define CFG_PAM 309 +#define CFG_LDAP 310 +#define CFG_LOCAL 311 +#define CFG_NONE 312 +#define CFG_GROUP_SOURCE 313 +#define CFG_ACCOUNTING 314 +#define CFG_CONF_SOURCE 315 +#define CFG_MOTD 316 +#define CFG_POOL_SIZE 317 +#define CFG_AUTH_THROTTLE 318 +#define CFG_SPLIT_NETWORK 319 +#define CFG_SPLIT_LOCAL 320 +#define CFG_SPLIT_INCLUDE 321 +#define CFG_SPLIT_DNS 322 +#define CFG_PFS_GROUP 323 +#define CFG_SAVE_PASSWD 324 +#define RETRY 325 +#define RETRY_COUNTER 326 +#define RETRY_INTERVAL 327 +#define RETRY_PERSEND 328 +#define RETRY_PHASE1 329 +#define RETRY_PHASE2 330 +#define NATT_KA 331 +#define ALGORITHM_CLASS 332 +#define ALGORITHMTYPE 333 +#define STRENGTHTYPE 334 +#define SAINFO 335 +#define FROM 336 +#define REMOTE 337 +#define ANONYMOUS 338 +#define CLIENTADDR 339 +#define INHERIT 340 +#define REMOTE_ADDRESS 341 +#define EXCHANGE_MODE 342 +#define EXCHANGETYPE 343 +#define DOI 344 +#define DOITYPE 345 +#define SITUATION 346 +#define SITUATIONTYPE 347 +#define CERTIFICATE_TYPE 348 +#define CERTTYPE 349 +#define PEERS_CERTFILE 350 +#define CA_TYPE 351 +#define VERIFY_CERT 352 +#define SEND_CERT 353 +#define SEND_CR 354 +#define MATCH_EMPTY_CR 355 +#define IDENTIFIERTYPE 356 +#define IDENTIFIERQUAL 357 +#define MY_IDENTIFIER 358 +#define PEERS_IDENTIFIER 359 +#define VERIFY_IDENTIFIER 360 +#define DNSSEC 361 +#define CERT_X509 362 +#define CERT_PLAINRSA 363 +#define NONCE_SIZE 364 +#define DH_GROUP 365 +#define KEEPALIVE 366 +#define PASSIVE 367 +#define INITIAL_CONTACT 368 +#define NAT_TRAVERSAL 369 +#define REMOTE_FORCE_LEVEL 370 +#define PROPOSAL_CHECK 371 +#define PROPOSAL_CHECK_LEVEL 372 +#define GENERATE_POLICY 373 +#define GENERATE_LEVEL 374 +#define SUPPORT_PROXY 375 +#define PROPOSAL 376 +#define EXEC_PATH 377 +#define EXEC_COMMAND 378 +#define EXEC_SUCCESS 379 +#define EXEC_FAILURE 380 +#define GSS_ID 381 +#define GSS_ID_ENC 382 +#define GSS_ID_ENCTYPE 383 +#define COMPLEX_BUNDLE 384 +#define DPD 385 +#define DPD_DELAY 386 +#define DPD_RETRY 387 +#define DPD_MAXFAIL 388 +#define PH1ID 389 +#define XAUTH_LOGIN 390 +#define WEAK_PHASE1_CHECK 391 +#define REKEY 392 +#define PREFIX 393 +#define PORT 394 +#define PORTANY 395 +#define UL_PROTO 396 +#define ANY 397 +#define IKE_FRAG 398 +#define ESP_FRAG 399 +#define MODE_CFG 400 +#define PFS_GROUP 401 +#define LIFETIME 402 +#define LIFETYPE_TIME 403 +#define LIFETYPE_BYTE 404 +#define STRENGTH 405 +#define REMOTEID 406 +#define SCRIPT 407 +#define PHASE1_UP 408 +#define PHASE1_DOWN 409 +#define PHASE1_DEAD 410 +#define NUMBER 411 +#define SWITCH 412 +#define BOOLEAN 413 +#define HEXSTRING 414 +#define QUOTEDSTRING 415 +#define ADDRSTRING 416 +#define ADDRRANGE 417 +#define UNITTYPE_BYTE 418 +#define UNITTYPE_KBYTES 419 +#define UNITTYPE_MBYTES 420 +#define UNITTYPE_TBYTES 421 +#define UNITTYPE_SEC 422 +#define UNITTYPE_MIN 423 +#define UNITTYPE_HOUR 424 +#define EOS 425 +#define BOC 426 +#define EOC 427 +#define COMMA 428 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 350 of yacc.c */ +#line 247 "cfparse.y" + + unsigned long num; + vchar_t *val; + struct remoteconf *rmconf; + struct sockaddr *saddr; + struct sainfoalg *alg; + + +/* Line 350 of yacc.c */ +#line 708 "cfparse.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE yylval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !YY_Y_TAB_H */ + +/* Copy the second part of user declarations. */ + +/* Line 353 of yacc.c */ +#line 736 "cfparse.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 2 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 534 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 174 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 204 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 381 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 691 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 428 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 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, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 4, 7, 9, 11, 13, 15, 17, + 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, + 42, 43, 46, 47, 52, 53, 58, 59, 64, 65, + 70, 71, 76, 77, 83, 84, 89, 93, 97, 101, + 105, 107, 112, 113, 116, 117, 122, 123, 128, 129, + 134, 135, 140, 141, 146, 151, 152, 155, 156, 161, + 162, 167, 168, 176, 177, 182, 183, 188, 189, 193, + 196, 197, 199, 200, 206, 207, 210, 211, 217, 218, + 225, 226, 232, 233, 240, 241, 246, 247, 252, 253, + 259, 260, 263, 264, 269, 270, 275, 276, 281, 282, + 287, 288, 293, 294, 299, 300, 305, 306, 311, 312, + 317, 318, 323, 324, 329, 330, 335, 340, 341, 344, + 345, 350, 351, 356, 360, 364, 365, 371, 372, 378, + 379, 384, 385, 390, 391, 396, 397, 402, 403, 408, + 409, 414, 415, 420, 421, 426, 427, 432, 433, 438, + 439, 444, 445, 450, 451, 456, 457, 462, 463, 468, + 469, 474, 475, 480, 481, 486, 487, 492, 493, 498, + 499, 504, 506, 510, 512, 514, 518, 520, 522, 526, + 529, 531, 535, 537, 539, 543, 545, 550, 551, 554, + 555, 560, 561, 567, 568, 573, 574, 580, 581, 587, + 588, 594, 595, 596, 605, 607, 610, 613, 616, 619, + 622, 628, 635, 638, 639, 643, 646, 647, 650, 651, + 656, 657, 662, 663, 670, 671, 678, 679, 684, 686, + 687, 692, 695, 696, 698, 699, 701, 703, 705, 707, + 709, 710, 712, 713, 720, 721, 726, 727, 734, 735, + 740, 742, 744, 748, 751, 753, 754, 757, 758, 763, + 764, 769, 770, 775, 776, 781, 784, 785, 790, 791, + 797, 798, 804, 805, 810, 811, 817, 818, 823, 824, + 829, 830, 835, 836, 841, 842, 848, 849, 856, 857, + 862, 863, 869, 870, 877, 878, 883, 884, 889, 890, + 895, 896, 901, 902, 907, 908, 913, 914, 919, 920, + 926, 927, 933, 934, 940, 941, 946, 947, 952, 953, + 958, 959, 964, 965, 970, 971, 976, 977, 982, 983, + 988, 989, 994, 995, 1000, 1001, 1006, 1007, 1012, 1013, + 1018, 1019, 1024, 1025, 1030, 1031, 1038, 1039, 1044, 1045, + 1052, 1053, 1059, 1060, 1063, 1064, 1070, 1071, 1076, 1078, + 1080, 1081, 1083, 1085, 1086, 1089, 1090, 1097, 1098, 1105, + 1106, 1111, 1112, 1117, 1118, 1124, 1126, 1128, 1130, 1132, + 1134, 1136 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int16 yyrhs[] = +{ + 175, 0, -1, -1, 175, 176, -1, 177, -1, 185, + -1, 189, -1, 190, -1, 191, -1, 192, -1, 194, + -1, 202, -1, 223, -1, 213, -1, 239, -1, 277, + -1, 286, -1, 306, -1, 187, -1, 3, 171, 178, + 172, -1, -1, 178, 179, -1, -1, 4, 160, 180, + 170, -1, -1, 4, 156, 181, 170, -1, -1, 5, + 160, 182, 170, -1, -1, 5, 156, 183, 170, -1, + -1, 6, 160, 184, 170, -1, -1, 7, 8, 160, + 186, 170, -1, -1, 129, 157, 188, 170, -1, 9, + 160, 170, -1, 10, 156, 170, -1, 127, 128, 170, + -1, 11, 193, 170, -1, 12, -1, 13, 171, 195, + 172, -1, -1, 195, 196, -1, -1, 14, 157, 197, + 170, -1, -1, 15, 157, 198, 170, -1, -1, 16, + 156, 199, 170, -1, -1, 17, 157, 200, 170, -1, + -1, 18, 157, 201, 170, -1, 19, 171, 203, 172, + -1, -1, 203, 204, -1, -1, 20, 211, 205, 170, + -1, -1, 21, 211, 206, 170, -1, -1, 24, 160, + 160, 160, 156, 207, 170, -1, -1, 24, 160, 208, + 170, -1, -1, 24, 25, 209, 170, -1, -1, 23, + 210, 170, -1, 161, 212, -1, -1, 139, -1, -1, + 39, 214, 171, 215, 172, -1, -1, 215, 216, -1, + -1, 40, 160, 160, 217, 170, -1, -1, 40, 160, + 156, 160, 218, 170, -1, -1, 41, 160, 160, 219, + 170, -1, -1, 41, 160, 156, 160, 220, 170, -1, + -1, 42, 156, 221, 170, -1, -1, 43, 156, 222, + 170, -1, -1, 26, 224, 171, 225, 172, -1, -1, + 225, 226, -1, -1, 29, 156, 227, 170, -1, -1, + 27, 160, 228, 170, -1, -1, 28, 156, 229, 170, + -1, -1, 30, 160, 230, 170, -1, -1, 33, 157, + 231, 170, -1, -1, 31, 160, 232, 170, -1, -1, + 32, 160, 233, 170, -1, -1, 34, 160, 234, 170, + -1, -1, 35, 160, 235, 170, -1, -1, 36, 160, + 236, 170, -1, -1, 37, 160, 237, 170, -1, -1, + 38, 160, 238, 170, -1, 44, 171, 240, 172, -1, + -1, 240, 241, -1, -1, 45, 161, 242, 170, -1, + -1, 46, 161, 243, 170, -1, 47, 267, 170, -1, + 48, 269, 170, -1, -1, 64, 65, 271, 244, 170, + -1, -1, 64, 66, 271, 245, 170, -1, -1, 67, + 275, 246, 170, -1, -1, 49, 160, 247, 170, -1, + -1, 50, 52, 248, 170, -1, -1, 50, 53, 249, + 170, -1, -1, 50, 54, 250, 170, -1, -1, 50, + 55, 251, 170, -1, -1, 51, 273, 252, 170, -1, + -1, 58, 52, 253, 170, -1, -1, 58, 55, 254, + 170, -1, -1, 59, 57, 255, 170, -1, -1, 59, + 52, 256, 170, -1, -1, 59, 53, 257, 170, -1, + -1, 59, 54, 258, 170, -1, -1, 62, 156, 259, + 170, -1, -1, 68, 156, 260, 170, -1, -1, 69, + 157, 261, 170, -1, -1, 63, 156, 262, 170, -1, + -1, 60, 56, 263, 170, -1, -1, 60, 53, 264, + 170, -1, -1, 60, 55, 265, 170, -1, -1, 61, + 160, 266, 170, -1, 268, -1, 268, 173, 267, -1, + 161, -1, 270, -1, 270, 173, 269, -1, 161, -1, + 272, -1, 271, 173, 272, -1, 161, 138, -1, 274, + -1, 274, 173, 273, -1, 160, -1, 276, -1, 276, + 173, 275, -1, 160, -1, 70, 171, 278, 172, -1, + -1, 278, 279, -1, -1, 71, 156, 280, 170, -1, + -1, 72, 156, 376, 281, 170, -1, -1, 73, 156, + 282, 170, -1, -1, 74, 156, 376, 283, 170, -1, + -1, 75, 156, 376, 284, 170, -1, -1, 76, 156, + 376, 285, 170, -1, -1, -1, 80, 287, 289, 291, + 171, 292, 288, 172, -1, 83, -1, 83, 84, -1, + 83, 290, -1, 290, 83, -1, 290, 84, -1, 290, + 290, -1, 101, 161, 302, 303, 304, -1, 101, 161, + 162, 302, 303, 304, -1, 101, 160, -1, -1, 81, + 101, 368, -1, 5, 160, -1, -1, 292, 293, -1, + -1, 146, 367, 294, 170, -1, -1, 151, 156, 295, + 170, -1, -1, 147, 148, 156, 376, 296, 170, -1, + -1, 147, 149, 156, 377, 297, 170, -1, -1, 77, + 298, 299, 170, -1, 301, -1, -1, 301, 300, 173, + 299, -1, 78, 305, -1, -1, 138, -1, -1, 139, + -1, 140, -1, 156, -1, 141, -1, 142, -1, -1, + 156, -1, -1, 82, 160, 85, 160, 307, 311, -1, + -1, 82, 160, 308, 312, -1, -1, 82, 313, 85, + 313, 309, 311, -1, -1, 82, 313, 310, 312, -1, + 312, -1, 170, -1, 171, 314, 172, -1, 83, 212, + -1, 211, -1, -1, 314, 315, -1, -1, 86, 211, + 316, 170, -1, -1, 87, 317, 363, 170, -1, -1, + 89, 90, 318, 170, -1, -1, 91, 92, 319, 170, + -1, 93, 364, -1, -1, 95, 160, 320, 170, -1, + -1, 95, 107, 160, 321, 170, -1, -1, 95, 108, + 160, 322, 170, -1, -1, 95, 106, 323, 170, -1, + -1, 96, 107, 160, 324, 170, -1, -1, 97, 157, + 325, 170, -1, -1, 98, 157, 326, 170, -1, -1, + 99, 157, 327, 170, -1, -1, 100, 157, 328, 170, + -1, -1, 103, 101, 368, 329, 170, -1, -1, 103, + 101, 102, 368, 330, 170, -1, -1, 135, 368, 331, + 170, -1, -1, 104, 101, 368, 332, 170, -1, -1, + 104, 101, 102, 368, 333, 170, -1, -1, 105, 157, + 334, 170, -1, -1, 109, 156, 335, 170, -1, -1, + 110, 336, 367, 170, -1, -1, 112, 157, 337, 170, + -1, -1, 143, 157, 338, 170, -1, -1, 143, 115, + 339, 170, -1, -1, 144, 156, 340, 170, -1, -1, + 152, 160, 153, 341, 170, -1, -1, 152, 160, 154, + 342, 170, -1, -1, 152, 160, 155, 343, 170, -1, + -1, 145, 157, 344, 170, -1, -1, 136, 157, 345, + 170, -1, -1, 118, 157, 346, 170, -1, -1, 118, + 119, 347, 170, -1, -1, 120, 157, 348, 170, -1, + -1, 113, 157, 349, 170, -1, -1, 114, 157, 350, + 170, -1, -1, 114, 115, 351, 170, -1, -1, 130, + 157, 352, 170, -1, -1, 131, 156, 353, 170, -1, + -1, 132, 156, 354, 170, -1, -1, 133, 156, 355, + 170, -1, -1, 137, 157, 356, 170, -1, -1, 137, + 115, 357, 170, -1, -1, 134, 156, 358, 170, -1, + -1, 147, 148, 156, 376, 359, 170, -1, -1, 116, + 117, 360, 170, -1, -1, 147, 149, 156, 377, 361, + 170, -1, -1, 121, 362, 171, 369, 172, -1, -1, + 363, 88, -1, -1, 107, 160, 160, 365, 170, -1, + -1, 108, 160, 366, 170, -1, 78, -1, 156, -1, + -1, 161, -1, 160, -1, -1, 369, 370, -1, -1, + 147, 148, 156, 376, 371, 170, -1, -1, 147, 149, + 156, 377, 372, 170, -1, -1, 110, 367, 373, 170, + -1, -1, 126, 160, 374, 170, -1, -1, 77, 78, + 305, 375, 170, -1, 167, -1, 168, -1, 169, -1, + 163, -1, 164, -1, 165, -1, 166, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 336, 336, 338, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, 351, 352, 353, 354, 355, 360, + 362, 364, 368, 367, 378, 378, 380, 379, 390, 390, + 391, 391, 397, 396, 417, 417, 422, 436, 443, 455, + 458, 472, 474, 476, 479, 479, 480, 480, 481, 481, + 482, 482, 483, 483, 488, 490, 492, 496, 495, 502, + 501, 513, 512, 522, 521, 531, 530, 539, 539, 542, + 554, 555, 560, 560, 577, 579, 583, 582, 601, 600, + 619, 618, 637, 636, 655, 654, 664, 663, 676, 676, + 687, 689, 693, 692, 704, 703, 715, 714, 724, 723, + 735, 734, 744, 743, 755, 754, 766, 765, 777, 776, + 788, 787, 799, 798, 810, 809, 824, 826, 828, 832, + 831, 843, 842, 853, 855, 858, 857, 867, 866, 876, + 875, 883, 882, 895, 894, 904, 903, 917, 916, 930, + 929, 943, 942, 950, 949, 959, 958, 972, 971, 981, + 980, 990, 989, 1003, 1002, 1016, 1015, 1026, 1025, 1035, + 1034, 1044, 1043, 1053, 1052, 1062, 1061, 1075, 1074, 1088, + 1087, 1101, 1102, 1105, 1122, 1123, 1126, 1143, 1144, 1147, + 1170, 1171, 1174, 1208, 1209, 1212, 1249, 1251, 1253, 1257, + 1256, 1262, 1261, 1267, 1266, 1272, 1271, 1277, 1276, 1282, + 1281, 1298, 1306, 1297, 1345, 1350, 1355, 1360, 1365, 1370, + 1377, 1426, 1491, 1520, 1523, 1548, 1561, 1563, 1567, 1566, + 1572, 1571, 1577, 1576, 1582, 1581, 1593, 1593, 1600, 1605, + 1604, 1611, 1667, 1668, 1671, 1672, 1673, 1676, 1677, 1678, + 1681, 1682, 1688, 1687, 1718, 1717, 1738, 1737, 1761, 1760, + 1777, 1778, 1786, 1793, 1799, 1808, 1810, 1814, 1813, 1823, + 1822, 1827, 1827, 1828, 1828, 1829, 1831, 1830, 1851, 1850, + 1868, 1867, 1898, 1897, 1912, 1911, 1928, 1928, 1929, 1929, + 1930, 1930, 1931, 1931, 1933, 1932, 1942, 1941, 1951, 1950, + 1968, 1967, 1985, 1984, 2001, 2001, 2002, 2002, 2004, 2003, + 2009, 2009, 2010, 2010, 2011, 2011, 2012, 2012, 2022, 2022, + 2029, 2029, 2036, 2036, 2043, 2043, 2044, 2044, 2047, 2047, + 2048, 2048, 2049, 2049, 2050, 2050, 2052, 2051, 2063, 2062, + 2074, 2073, 2082, 2081, 2091, 2090, 2100, 2099, 2108, 2108, + 2109, 2109, 2111, 2110, 2116, 2115, 2120, 2120, 2122, 2121, + 2136, 2135, 2146, 2148, 2172, 2171, 2193, 2192, 2226, 2234, + 2246, 2247, 2248, 2250, 2252, 2256, 2255, 2261, 2260, 2273, + 2272, 2278, 2277, 2291, 2290, 2388, 2389, 2390, 2393, 2394, + 2395, 2396 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "PRIVSEP", "USER", "GROUP", "CHROOT", + "PATH", "PATHTYPE", "INCLUDE", "PFKEY_BUFFER", "LOGGING", "LOGLEV", + "PADDING", "PAD_RANDOMIZE", "PAD_RANDOMIZELEN", "PAD_MAXLEN", + "PAD_STRICT", "PAD_EXCLTAIL", "LISTEN", "X_ISAKMP", "X_ISAKMP_NATT", + "X_ADMIN", "STRICT_ADDRESS", "ADMINSOCK", "DISABLED", "LDAPCFG", + "LDAP_HOST", "LDAP_PORT", "LDAP_PVER", "LDAP_BASE", "LDAP_BIND_DN", + "LDAP_BIND_PW", "LDAP_SUBTREE", "LDAP_ATTR_USER", "LDAP_ATTR_ADDR", + "LDAP_ATTR_MASK", "LDAP_ATTR_GROUP", "LDAP_ATTR_MEMBER", "RADCFG", + "RAD_AUTH", "RAD_ACCT", "RAD_TIMEOUT", "RAD_RETRIES", "MODECFG", + "CFG_NET4", "CFG_MASK4", "CFG_DNS4", "CFG_NBNS4", "CFG_DEFAULT_DOMAIN", + "CFG_AUTH_SOURCE", "CFG_AUTH_GROUPS", "CFG_SYSTEM", "CFG_RADIUS", + "CFG_PAM", "CFG_LDAP", "CFG_LOCAL", "CFG_NONE", "CFG_GROUP_SOURCE", + "CFG_ACCOUNTING", "CFG_CONF_SOURCE", "CFG_MOTD", "CFG_POOL_SIZE", + "CFG_AUTH_THROTTLE", "CFG_SPLIT_NETWORK", "CFG_SPLIT_LOCAL", + "CFG_SPLIT_INCLUDE", "CFG_SPLIT_DNS", "CFG_PFS_GROUP", "CFG_SAVE_PASSWD", + "RETRY", "RETRY_COUNTER", "RETRY_INTERVAL", "RETRY_PERSEND", + "RETRY_PHASE1", "RETRY_PHASE2", "NATT_KA", "ALGORITHM_CLASS", + "ALGORITHMTYPE", "STRENGTHTYPE", "SAINFO", "FROM", "REMOTE", "ANONYMOUS", + "CLIENTADDR", "INHERIT", "REMOTE_ADDRESS", "EXCHANGE_MODE", + "EXCHANGETYPE", "DOI", "DOITYPE", "SITUATION", "SITUATIONTYPE", + "CERTIFICATE_TYPE", "CERTTYPE", "PEERS_CERTFILE", "CA_TYPE", + "VERIFY_CERT", "SEND_CERT", "SEND_CR", "MATCH_EMPTY_CR", + "IDENTIFIERTYPE", "IDENTIFIERQUAL", "MY_IDENTIFIER", "PEERS_IDENTIFIER", + "VERIFY_IDENTIFIER", "DNSSEC", "CERT_X509", "CERT_PLAINRSA", + "NONCE_SIZE", "DH_GROUP", "KEEPALIVE", "PASSIVE", "INITIAL_CONTACT", + "NAT_TRAVERSAL", "REMOTE_FORCE_LEVEL", "PROPOSAL_CHECK", + "PROPOSAL_CHECK_LEVEL", "GENERATE_POLICY", "GENERATE_LEVEL", + "SUPPORT_PROXY", "PROPOSAL", "EXEC_PATH", "EXEC_COMMAND", "EXEC_SUCCESS", + "EXEC_FAILURE", "GSS_ID", "GSS_ID_ENC", "GSS_ID_ENCTYPE", + "COMPLEX_BUNDLE", "DPD", "DPD_DELAY", "DPD_RETRY", "DPD_MAXFAIL", + "PH1ID", "XAUTH_LOGIN", "WEAK_PHASE1_CHECK", "REKEY", "PREFIX", "PORT", + "PORTANY", "UL_PROTO", "ANY", "IKE_FRAG", "ESP_FRAG", "MODE_CFG", + "PFS_GROUP", "LIFETIME", "LIFETYPE_TIME", "LIFETYPE_BYTE", "STRENGTH", + "REMOTEID", "SCRIPT", "PHASE1_UP", "PHASE1_DOWN", "PHASE1_DEAD", + "NUMBER", "SWITCH", "BOOLEAN", "HEXSTRING", "QUOTEDSTRING", "ADDRSTRING", + "ADDRRANGE", "UNITTYPE_BYTE", "UNITTYPE_KBYTES", "UNITTYPE_MBYTES", + "UNITTYPE_TBYTES", "UNITTYPE_SEC", "UNITTYPE_MIN", "UNITTYPE_HOUR", + "EOS", "BOC", "EOC", "COMMA", "$accept", "statements", "statement", + "privsep_statement", "privsep_stmts", "privsep_stmt", "$@1", "$@2", + "$@3", "$@4", "$@5", "path_statement", "$@6", "special_statement", "$@7", + "include_statement", "pfkey_statement", "gssenc_statement", + "logging_statement", "log_level", "padding_statement", "padding_stmts", + "padding_stmt", "$@8", "$@9", "$@10", "$@11", "$@12", "listen_statement", + "listen_stmts", "listen_stmt", "$@13", "$@14", "$@15", "$@16", "$@17", + "$@18", "ike_addrinfo_port", "ike_port", "radcfg_statement", "$@19", + "radcfg_stmts", "radcfg_stmt", "$@20", "$@21", "$@22", "$@23", "$@24", + "$@25", "ldapcfg_statement", "$@26", "ldapcfg_stmts", "ldapcfg_stmt", + "$@27", "$@28", "$@29", "$@30", "$@31", "$@32", "$@33", "$@34", "$@35", + "$@36", "$@37", "$@38", "modecfg_statement", "modecfg_stmts", + "modecfg_stmt", "$@39", "$@40", "$@41", "$@42", "$@43", "$@44", "$@45", + "$@46", "$@47", "$@48", "$@49", "$@50", "$@51", "$@52", "$@53", "$@54", + "$@55", "$@56", "$@57", "$@58", "$@59", "$@60", "$@61", "$@62", "$@63", + "addrdnslist", "addrdns", "addrwinslist", "addrwins", "splitnetlist", + "splitnet", "authgrouplist", "authgroup", "splitdnslist", "splitdns", + "timer_statement", "timer_stmts", "timer_stmt", "$@64", "$@65", "$@66", + "$@67", "$@68", "$@69", "sainfo_statement", "$@70", "$@71", + "sainfo_name", "sainfo_id", "sainfo_param", "sainfo_specs", + "sainfo_spec", "$@72", "$@73", "$@74", "$@75", "$@76", "algorithms", + "$@77", "algorithm", "prefix", "port", "ul_proto", "keylength", + "remote_statement", "$@78", "$@79", "$@80", "$@81", + "remote_specs_inherit_block", "remote_specs_block", "remote_index", + "remote_specs", "remote_spec", "$@82", "$@83", "$@84", "$@85", "$@86", + "$@87", "$@88", "$@89", "$@90", "$@91", "$@92", "$@93", "$@94", "$@95", + "$@96", "$@97", "$@98", "$@99", "$@100", "$@101", "$@102", "$@103", + "$@104", "$@105", "$@106", "$@107", "$@108", "$@109", "$@110", "$@111", + "$@112", "$@113", "$@114", "$@115", "$@116", "$@117", "$@118", "$@119", + "$@120", "$@121", "$@122", "$@123", "$@124", "$@125", "$@126", "$@127", + "$@128", "exchange_types", "cert_spec", "$@129", "$@130", "dh_group_num", + "identifierstring", "isakmpproposal_specs", "isakmpproposal_spec", + "$@131", "$@132", "$@133", "$@134", "$@135", "unittype_time", + "unittype_byte", YY_NULL +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 428 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint16 yyr1[] = +{ + 0, 174, 175, 175, 176, 176, 176, 176, 176, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, + 178, 178, 180, 179, 181, 179, 182, 179, 183, 179, + 184, 179, 186, 185, 188, 187, 189, 190, 191, 192, + 193, 194, 195, 195, 197, 196, 198, 196, 199, 196, + 200, 196, 201, 196, 202, 203, 203, 205, 204, 206, + 204, 207, 204, 208, 204, 209, 204, 210, 204, 211, + 212, 212, 214, 213, 215, 215, 217, 216, 218, 216, + 219, 216, 220, 216, 221, 216, 222, 216, 224, 223, + 225, 225, 227, 226, 228, 226, 229, 226, 230, 226, + 231, 226, 232, 226, 233, 226, 234, 226, 235, 226, + 236, 226, 237, 226, 238, 226, 239, 240, 240, 242, + 241, 243, 241, 241, 241, 244, 241, 245, 241, 246, + 241, 247, 241, 248, 241, 249, 241, 250, 241, 251, + 241, 252, 241, 253, 241, 254, 241, 255, 241, 256, + 241, 257, 241, 258, 241, 259, 241, 260, 241, 261, + 241, 262, 241, 263, 241, 264, 241, 265, 241, 266, + 241, 267, 267, 268, 269, 269, 270, 271, 271, 272, + 273, 273, 274, 275, 275, 276, 277, 278, 278, 280, + 279, 281, 279, 282, 279, 283, 279, 284, 279, 285, + 279, 287, 288, 286, 289, 289, 289, 289, 289, 289, + 290, 290, 290, 291, 291, 291, 292, 292, 294, 293, + 295, 293, 296, 293, 297, 293, 298, 293, 299, 300, + 299, 301, 302, 302, 303, 303, 303, 304, 304, 304, + 305, 305, 307, 306, 308, 306, 309, 306, 310, 306, + 311, 311, 312, 313, 313, 314, 314, 316, 315, 317, + 315, 318, 315, 319, 315, 315, 320, 315, 321, 315, + 322, 315, 323, 315, 324, 315, 325, 315, 326, 315, + 327, 315, 328, 315, 329, 315, 330, 315, 331, 315, + 332, 315, 333, 315, 334, 315, 335, 315, 336, 315, + 337, 315, 338, 315, 339, 315, 340, 315, 341, 315, + 342, 315, 343, 315, 344, 315, 345, 315, 346, 315, + 347, 315, 348, 315, 349, 315, 350, 315, 351, 315, + 352, 315, 353, 315, 354, 315, 355, 315, 356, 315, + 357, 315, 358, 315, 359, 315, 360, 315, 361, 315, + 362, 315, 363, 363, 365, 364, 366, 364, 367, 367, + 368, 368, 368, 369, 369, 371, 370, 372, 370, 373, + 370, 374, 370, 375, 370, 376, 376, 376, 377, 377, + 377, 377 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 0, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, + 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, + 0, 4, 0, 5, 0, 4, 3, 3, 3, 3, + 1, 4, 0, 2, 0, 4, 0, 4, 0, 4, + 0, 4, 0, 4, 4, 0, 2, 0, 4, 0, + 4, 0, 7, 0, 4, 0, 4, 0, 3, 2, + 0, 1, 0, 5, 0, 2, 0, 5, 0, 6, + 0, 5, 0, 6, 0, 4, 0, 4, 0, 5, + 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, + 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, + 0, 4, 0, 4, 0, 4, 4, 0, 2, 0, + 4, 0, 4, 3, 3, 0, 5, 0, 5, 0, + 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, + 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, + 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, + 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, + 4, 1, 3, 1, 1, 3, 1, 1, 3, 2, + 1, 3, 1, 1, 3, 1, 4, 0, 2, 0, + 4, 0, 5, 0, 4, 0, 5, 0, 5, 0, + 5, 0, 0, 8, 1, 2, 2, 2, 2, 2, + 5, 6, 2, 0, 3, 2, 0, 2, 0, 4, + 0, 4, 0, 6, 0, 6, 0, 4, 1, 0, + 4, 2, 0, 1, 0, 1, 1, 1, 1, 1, + 0, 1, 0, 6, 0, 4, 0, 6, 0, 4, + 1, 1, 3, 2, 1, 0, 2, 0, 4, 0, + 4, 0, 4, 0, 4, 2, 0, 4, 0, 5, + 0, 5, 0, 4, 0, 5, 0, 4, 0, 4, + 0, 4, 0, 4, 0, 5, 0, 6, 0, 4, + 0, 5, 0, 6, 0, 4, 0, 4, 0, 4, + 0, 4, 0, 4, 0, 4, 0, 4, 0, 5, + 0, 5, 0, 5, 0, 4, 0, 4, 0, 4, + 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, + 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, + 0, 4, 0, 4, 0, 6, 0, 4, 0, 6, + 0, 5, 0, 2, 0, 5, 0, 4, 1, 1, + 0, 1, 1, 0, 2, 0, 6, 0, 6, 0, + 4, 0, 4, 0, 5, 1, 1, 1, 1, 1, + 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint16 yydefact[] = +{ + 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 88, 72, 0, 0, 201, 0, 0, 0, 3, 4, + 5, 18, 6, 7, 8, 9, 10, 11, 13, 12, + 14, 15, 16, 17, 20, 0, 0, 0, 40, 0, + 42, 55, 0, 0, 117, 187, 0, 70, 244, 70, + 254, 248, 0, 34, 0, 32, 36, 37, 39, 0, + 0, 90, 74, 0, 0, 204, 0, 213, 0, 71, + 253, 0, 0, 69, 0, 0, 38, 0, 0, 0, + 0, 19, 21, 0, 0, 0, 0, 0, 0, 41, + 43, 0, 0, 67, 0, 54, 56, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 116, 118, 0, 0, + 0, 0, 0, 0, 186, 188, 205, 206, 212, 232, + 0, 0, 0, 207, 208, 209, 242, 255, 245, 246, + 249, 35, 24, 22, 28, 26, 30, 33, 44, 46, + 48, 50, 52, 57, 59, 0, 65, 63, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 89, 91, 0, 0, 0, 0, 73, 75, 119, 121, + 173, 0, 171, 176, 0, 174, 131, 133, 135, 137, + 139, 182, 141, 180, 143, 145, 149, 151, 153, 147, + 165, 167, 163, 169, 155, 161, 0, 0, 185, 129, + 183, 157, 159, 189, 0, 193, 0, 0, 0, 233, + 232, 234, 215, 360, 216, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 0, 0, 0, 94, 96, 92, 98, 102, 104, + 100, 106, 108, 110, 112, 114, 0, 0, 84, 86, + 0, 0, 123, 0, 124, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 125, 177, 127, 0, + 0, 0, 0, 0, 375, 376, 377, 191, 0, 195, + 197, 199, 234, 235, 236, 0, 362, 361, 214, 202, + 251, 243, 250, 0, 259, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, + 0, 0, 0, 0, 0, 350, 0, 0, 0, 0, + 0, 360, 0, 0, 0, 0, 0, 0, 0, 252, + 256, 247, 25, 23, 29, 27, 31, 45, 47, 49, + 51, 53, 58, 60, 66, 0, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 76, 0, 80, 0, 0, 120, 122, 172, 175, 132, + 134, 136, 138, 140, 142, 181, 144, 146, 150, 152, + 154, 148, 166, 168, 164, 170, 156, 162, 179, 0, + 0, 0, 130, 184, 158, 160, 190, 0, 194, 0, + 0, 0, 0, 238, 239, 237, 210, 226, 0, 0, + 0, 0, 217, 257, 352, 261, 263, 0, 0, 265, + 272, 0, 0, 266, 0, 276, 278, 280, 282, 360, + 360, 294, 296, 0, 300, 324, 328, 326, 346, 320, + 318, 322, 0, 330, 332, 334, 336, 342, 288, 316, + 340, 338, 304, 302, 306, 314, 0, 0, 0, 61, + 95, 97, 93, 99, 103, 105, 101, 107, 109, 111, + 113, 115, 78, 0, 82, 0, 85, 87, 178, 126, + 128, 192, 196, 198, 200, 211, 0, 358, 359, 218, + 0, 0, 220, 203, 0, 0, 0, 0, 0, 356, + 0, 268, 270, 0, 274, 0, 0, 0, 0, 360, + 284, 360, 290, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 363, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 308, 310, 312, 0, 0, 77, 0, 81, 240, 0, + 228, 0, 0, 0, 0, 258, 353, 260, 262, 264, + 354, 0, 273, 0, 0, 267, 0, 277, 279, 281, + 283, 286, 0, 292, 0, 295, 297, 299, 301, 325, + 329, 327, 347, 321, 319, 323, 0, 331, 333, 335, + 337, 343, 289, 317, 341, 339, 305, 303, 307, 315, + 344, 378, 379, 380, 381, 348, 0, 0, 0, 62, + 79, 83, 241, 231, 227, 0, 219, 222, 224, 221, + 0, 357, 269, 271, 275, 0, 285, 0, 291, 0, + 0, 0, 0, 351, 364, 0, 0, 309, 311, 313, + 0, 0, 0, 355, 287, 293, 240, 369, 371, 0, + 0, 345, 349, 230, 223, 225, 373, 0, 0, 0, + 0, 0, 370, 372, 365, 367, 374, 0, 0, 366, + 368 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 1, 18, 19, 54, 82, 229, 228, 231, 230, + 232, 20, 83, 21, 77, 22, 23, 24, 25, 39, + 26, 59, 90, 233, 234, 235, 236, 237, 27, 60, + 96, 238, 239, 563, 243, 241, 155, 50, 70, 28, + 43, 98, 177, 493, 564, 495, 566, 383, 384, 29, + 42, 97, 171, 369, 367, 368, 370, 373, 371, 372, + 374, 375, 376, 377, 378, 30, 63, 117, 260, 261, + 410, 411, 289, 266, 267, 268, 269, 270, 271, 273, + 274, 278, 275, 276, 277, 283, 291, 292, 284, 281, + 279, 280, 282, 181, 182, 184, 185, 286, 287, 192, + 193, 209, 210, 31, 64, 125, 293, 417, 298, 419, + 420, 421, 32, 46, 431, 67, 68, 132, 309, 432, + 571, 574, 661, 662, 506, 569, 635, 570, 221, 305, + 426, 633, 33, 225, 72, 227, 75, 311, 312, 51, + 226, 350, 514, 434, 516, 517, 523, 583, 584, 520, + 586, 525, 526, 527, 528, 592, 645, 550, 594, 647, + 533, 534, 453, 536, 555, 554, 556, 626, 627, 628, + 557, 551, 542, 541, 543, 537, 539, 538, 545, 546, + 547, 548, 553, 552, 549, 655, 540, 656, 462, 515, + 439, 640, 581, 509, 308, 606, 654, 687, 688, 677, + 678, 681, 297, 625 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -542 +static const yytype_int16 yypact[] = +{ + -542, 42, -542, -124, 46, -87, -72, 82, -63, -39, + -542, -542, -29, -15, -542, -50, 34, 7, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, 12, 10, 21, -542, 25, + -542, -542, 38, 40, -542, -542, 30, 66, 89, 66, + -542, 143, 37, -542, 3, -542, -542, -542, -542, -4, + -5, -542, -542, 29, -9, 35, -11, 36, 45, -542, + -542, 72, 63, -542, -45, 63, -542, 71, -53, -13, + 76, -542, -542, 73, 85, 87, 90, 88, 99, -542, + -542, 94, 94, -542, -8, -542, -542, -7, -6, 96, + 97, 102, 104, 107, 106, 108, 54, 81, 4, 110, + 103, 115, 122, 112, 118, 109, -542, -542, 119, 120, + 121, 123, 124, 125, -542, -542, -542, -542, -542, -90, + 113, 177, 111, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, 114, -542, 126, 127, 129, + 132, 130, 131, 133, 135, 134, 136, 137, 138, 139, + -542, -542, 140, 141, 146, 147, -542, -542, -542, -542, + -542, 142, 144, -542, 145, 148, -542, -542, -542, -542, + -542, -542, -542, 149, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, 150, 150, -542, -542, + 151, -542, -542, -542, 14, -542, 14, 14, 14, -542, + 157, 50, -542, 32, -542, 27, 117, 27, 153, 155, + 156, 158, 159, 160, 161, 162, 163, 164, 165, 166, + -542, 167, 154, 168, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -12, -3, -542, -542, + 169, 170, -542, 102, -542, 104, 171, 173, 174, 175, + 176, 178, 108, 179, 180, 181, 182, 183, 184, 185, + 187, 188, 189, 190, 191, 172, 192, -542, 192, 193, + 112, 194, 196, 197, -542, -542, -542, -542, 198, -542, + -542, -542, 50, -542, -542, -1, -542, -542, -542, -21, + -542, -542, -542, 94, -542, 214, 213, 92, -37, 199, + 152, 205, 212, 215, 206, 207, 216, 218, -542, 219, + 220, -57, 201, -75, 221, -542, 222, 224, 225, 226, + 227, 32, 228, -30, -20, 230, 231, 70, 210, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, 233, -542, 217, 223, 229, + 232, 234, 235, 236, 237, 238, 239, 240, 241, 211, + -542, 243, -542, 242, 244, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, 150, + 245, 246, -542, -542, -542, -542, -542, 247, -542, 248, + 249, 250, -1, -542, -542, -542, -542, -542, -38, 75, + 257, 203, -542, -542, -542, -542, -542, 261, 262, -542, + -542, 263, 264, -542, 265, -542, -542, -542, -542, -59, + -56, -542, -542, -38, -542, -542, -542, -542, -542, -542, + -542, -542, 255, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, 271, 272, 31, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, 259, -542, 260, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, 269, -542, -542, -542, + 275, 276, -542, -542, 266, -49, 267, 268, 273, -542, + 270, -542, -542, 274, -542, 277, 278, 279, 280, 32, + -542, 32, -542, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, -542, 292, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 14, 13, + -542, -542, -542, 306, 307, -542, 308, -542, 323, 310, + 309, 311, 14, 13, 313, -542, -542, -542, -542, -542, + -542, 314, -542, 315, 316, -542, 317, -542, -542, -542, + -542, -542, 318, -542, 319, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -27, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, 320, 321, 322, -542, + -542, -542, -542, -542, -542, 324, -542, -542, -542, -542, + 325, -542, -542, -542, -542, 326, -542, 328, -542, 312, + -38, 333, 91, -542, -542, 329, 330, -542, -542, -542, + 269, 331, 332, -542, -542, -542, 323, -542, -542, 338, + 347, -542, -542, -542, -542, -542, -542, 334, 335, 14, + 13, 336, -542, -542, -542, -542, -542, 337, 339, -542, + -542 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -88, 342, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, 20, -542, 48, -542, 327, -93, 47, + -542, 105, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, 86, -542, -542, -542, + -542, -542, -542, -542, -542, -340, -542, -542, 293, 95, + -95, -282, -542, -542, -542, -542, -542, 208, 98, 360, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, + -542, -542, -542, -448, -335, -542, -542, -542, -542, -542, + -542, -542, -216, -541 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -230 +static const yytype_int16 yytable[] = +{ + 299, 300, 301, 153, 154, 535, 468, 78, 79, 80, + 84, 85, 86, 87, 88, 91, 92, 156, 93, 94, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 638, 47, 172, 173, 174, 175, 47, 576, + 507, 130, 2, 529, 459, 3, 531, 34, 219, 4, + 649, 5, 6, 7, 35, 8, 427, 200, 456, 201, + 202, 9, 118, 119, 120, 121, 122, 123, 10, 440, + 441, 442, 220, 36, 99, 100, 101, 102, 103, 104, + 105, 11, 460, 650, 37, 470, 12, 106, 107, 108, + 109, 110, 111, 112, 38, 472, 113, 114, 115, 651, + 457, 306, 307, 142, 306, 307, 194, 143, 40, 195, + 48, 49, 13, 65, 530, 532, 49, 131, 508, 126, + 652, 577, 14, 443, 15, 428, 429, 471, 133, 134, + 430, 66, 41, 196, 197, 198, 66, 473, 199, 685, + 423, 424, 44, 144, 379, 653, 66, 145, 380, 128, + 129, 127, 157, 381, 135, 425, 45, 382, 187, 188, + 189, 190, 52, 124, 53, 170, 176, 95, 89, 16, + 138, 17, 55, 140, 71, 81, 621, 622, 623, 624, + 56, 294, 295, 296, 560, 561, 562, 206, 207, 303, + 304, 57, 306, 307, 591, 58, 593, 310, 137, 437, + 438, 116, 667, 313, 314, 69, 315, 76, 316, 61, + 317, 62, 318, 319, 320, 321, 322, 323, 476, 477, + 324, 325, 326, 510, 511, 433, 327, 328, 74, 329, + 330, 331, 136, 332, 137, 333, 146, 334, 335, 669, + 670, 141, 148, 147, 149, 151, 150, 336, 337, 338, + 339, 340, 341, 342, 343, 49, 152, 178, 179, 204, + 344, 345, 346, 180, 347, 183, 212, 186, 191, 348, + 203, 205, 208, 222, 211, 213, 214, 215, 223, 216, + 217, 218, 224, 387, 240, 245, 242, 244, 246, 349, + 247, 248, 250, 249, 251, 219, 252, 253, 254, 255, + 256, 257, 258, 259, 435, 436, 444, 449, 450, 445, + 408, 285, 262, 388, 365, 264, 498, 263, 458, 395, + 673, 265, 272, 352, 290, 353, 354, 505, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 366, 385, + 386, 389, 620, 390, 391, 392, 393, 568, 394, 396, + 397, 398, 399, 400, 401, 402, 637, 403, 404, 405, + 406, 407, 446, 412, 414, 409, 415, 416, 418, 447, + 478, 492, 448, 451, 452, 513, 454, 455, 461, 463, + 464, 465, 466, 467, 676, 469, 474, 480, 475, 479, + 666, 73, 0, 481, 0, 413, 0, 422, 0, 482, + 0, 0, 483, 494, 484, 485, 486, 487, 488, 489, + 490, 491, 496, 512, 497, 499, 500, 501, 502, 503, + 504, 518, 519, 521, 522, 524, 544, 558, 559, 565, + 567, 572, 573, 580, 139, 351, 575, 578, 579, 0, + 582, 0, 0, 0, 585, 0, 0, 587, 588, 589, + 590, 595, 596, 597, 598, 599, 600, 601, 602, 603, + 604, 605, 607, 684, 608, 609, 610, 611, 612, 613, + 614, 615, 616, 617, 618, 619, 629, 630, 631, 632, + 634, 636, -229, 639, 641, 642, 643, 644, 646, 648, + 657, 658, 659, 668, 679, 663, 664, 660, 665, 671, + 672, 674, 675, 680, 682, 683, 686, 689, 0, 690, + 0, 0, 0, 302, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 288 +}; + +#define yypact_value_is_default(yystate) \ + ((yystate) == (-542)) + +#define yytable_value_is_error(yytable_value) \ + YYID (0) + +static const yytype_int16 yycheck[] = +{ + 216, 217, 218, 91, 92, 453, 341, 4, 5, 6, + 14, 15, 16, 17, 18, 20, 21, 25, 23, 24, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 573, 83, 40, 41, 42, 43, 83, 88, + 78, 5, 0, 102, 119, 3, 102, 171, 138, 7, + 77, 9, 10, 11, 8, 13, 77, 53, 115, 55, + 56, 19, 71, 72, 73, 74, 75, 76, 26, 106, + 107, 108, 162, 160, 45, 46, 47, 48, 49, 50, + 51, 39, 157, 110, 156, 115, 44, 58, 59, 60, + 61, 62, 63, 64, 12, 115, 67, 68, 69, 126, + 157, 160, 161, 156, 160, 161, 52, 160, 171, 55, + 160, 161, 70, 83, 449, 450, 161, 81, 156, 84, + 147, 170, 80, 160, 82, 146, 147, 157, 83, 84, + 151, 101, 171, 52, 53, 54, 101, 157, 57, 680, + 141, 142, 171, 156, 156, 172, 101, 160, 160, 160, + 161, 65, 160, 156, 68, 156, 171, 160, 52, 53, + 54, 55, 128, 172, 157, 172, 172, 172, 172, 127, + 72, 129, 160, 75, 85, 172, 163, 164, 165, 166, + 170, 167, 168, 169, 153, 154, 155, 65, 66, 139, + 140, 170, 160, 161, 529, 170, 531, 170, 171, 107, + 108, 172, 650, 86, 87, 139, 89, 170, 91, 171, + 93, 171, 95, 96, 97, 98, 99, 100, 148, 149, + 103, 104, 105, 148, 149, 313, 109, 110, 85, 112, + 113, 114, 160, 116, 171, 118, 160, 120, 121, 148, + 149, 170, 157, 170, 157, 157, 156, 130, 131, 132, + 133, 134, 135, 136, 137, 161, 157, 161, 161, 156, + 143, 144, 145, 161, 147, 161, 157, 160, 160, 152, + 160, 156, 160, 160, 156, 156, 156, 156, 101, 156, + 156, 156, 171, 263, 170, 156, 160, 160, 156, 172, + 160, 160, 157, 160, 160, 138, 160, 160, 160, 160, + 160, 160, 156, 156, 90, 92, 107, 101, 101, 157, + 138, 161, 170, 265, 160, 170, 409, 173, 117, 272, + 660, 173, 173, 170, 173, 170, 170, 422, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 558, 170, 170, 170, 170, 78, 170, 170, + 170, 170, 170, 170, 170, 170, 572, 170, 170, 170, + 170, 170, 157, 170, 170, 173, 170, 170, 170, 157, + 160, 160, 157, 157, 156, 172, 157, 157, 157, 157, + 156, 156, 156, 156, 666, 157, 156, 170, 157, 156, + 78, 49, -1, 170, -1, 290, -1, 302, -1, 170, + -1, -1, 170, 160, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 156, 170, 170, 170, 170, 170, 170, + 170, 160, 160, 160, 160, 160, 171, 156, 156, 170, + 170, 156, 156, 160, 74, 227, 170, 170, 170, -1, + 170, -1, -1, -1, 170, -1, -1, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 679, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 156, + 170, 170, 173, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 160, 156, 170, 170, 173, 170, 170, + 170, 170, 170, 156, 170, 170, 170, 170, -1, 170, + -1, -1, -1, 220, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 207 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint16 yystos[] = +{ + 0, 175, 0, 3, 7, 9, 10, 11, 13, 19, + 26, 39, 44, 70, 80, 82, 127, 129, 176, 177, + 185, 187, 189, 190, 191, 192, 194, 202, 213, 223, + 239, 277, 286, 306, 171, 8, 160, 156, 12, 193, + 171, 171, 224, 214, 171, 171, 287, 83, 160, 161, + 211, 313, 128, 157, 178, 160, 170, 170, 170, 195, + 203, 171, 171, 240, 278, 83, 101, 289, 290, 139, + 212, 85, 308, 212, 85, 310, 170, 188, 4, 5, + 6, 172, 179, 186, 14, 15, 16, 17, 18, 172, + 196, 20, 21, 23, 24, 172, 204, 225, 215, 45, + 46, 47, 48, 49, 50, 51, 58, 59, 60, 61, + 62, 63, 64, 67, 68, 69, 172, 241, 71, 72, + 73, 74, 75, 76, 172, 279, 84, 290, 160, 161, + 5, 81, 291, 83, 84, 290, 160, 171, 312, 313, + 312, 170, 156, 160, 156, 160, 160, 170, 157, 157, + 156, 157, 157, 211, 211, 210, 25, 160, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 172, 226, 40, 41, 42, 43, 172, 216, 161, 161, + 161, 267, 268, 161, 269, 270, 160, 52, 53, 54, + 55, 160, 273, 274, 52, 55, 52, 53, 54, 57, + 53, 55, 56, 160, 156, 156, 65, 66, 160, 275, + 276, 156, 157, 156, 156, 156, 156, 156, 156, 138, + 162, 302, 160, 101, 171, 307, 314, 309, 181, 180, + 183, 182, 184, 197, 198, 199, 200, 201, 205, 206, + 170, 209, 160, 208, 160, 156, 156, 160, 160, 160, + 157, 160, 160, 160, 160, 160, 160, 160, 156, 156, + 242, 243, 170, 173, 170, 173, 247, 248, 249, 250, + 251, 252, 173, 253, 254, 256, 257, 258, 255, 264, + 265, 263, 266, 259, 262, 161, 271, 272, 271, 246, + 173, 260, 261, 280, 167, 168, 169, 376, 282, 376, + 376, 376, 302, 139, 140, 303, 160, 161, 368, 292, + 170, 311, 312, 86, 87, 89, 91, 93, 95, 96, + 97, 98, 99, 100, 103, 104, 105, 109, 110, 112, + 113, 114, 116, 118, 120, 121, 130, 131, 132, 133, + 134, 135, 136, 137, 143, 144, 145, 147, 152, 172, + 315, 311, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 160, 170, 228, 229, 227, + 230, 232, 233, 231, 234, 235, 236, 237, 238, 156, + 160, 156, 160, 221, 222, 170, 170, 267, 269, 170, + 170, 170, 170, 170, 170, 273, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 138, 173, + 244, 245, 170, 275, 170, 170, 170, 281, 170, 283, + 284, 285, 303, 141, 142, 156, 304, 77, 146, 147, + 151, 288, 293, 211, 317, 90, 92, 107, 108, 364, + 106, 107, 108, 160, 107, 157, 157, 157, 157, 101, + 101, 157, 156, 336, 157, 157, 115, 157, 117, 119, + 157, 157, 362, 157, 156, 156, 156, 156, 368, 157, + 115, 157, 115, 157, 156, 157, 148, 149, 160, 156, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 160, 217, 160, 219, 170, 170, 272, 170, + 170, 170, 170, 170, 170, 304, 298, 78, 156, 367, + 148, 149, 156, 172, 316, 363, 318, 319, 160, 160, + 323, 160, 160, 320, 160, 325, 326, 327, 328, 102, + 368, 102, 368, 334, 335, 367, 337, 349, 351, 350, + 360, 347, 346, 348, 171, 352, 353, 354, 355, 358, + 331, 345, 357, 356, 339, 338, 340, 344, 156, 156, + 153, 154, 155, 207, 218, 170, 220, 170, 78, 299, + 301, 294, 156, 156, 295, 170, 88, 170, 170, 170, + 160, 366, 170, 321, 322, 170, 324, 170, 170, 170, + 170, 368, 329, 368, 332, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 369, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 376, 163, 164, 165, 166, 377, 341, 342, 343, 170, + 170, 170, 156, 305, 170, 300, 170, 376, 377, 170, + 365, 170, 170, 170, 170, 330, 170, 333, 170, 77, + 110, 126, 147, 172, 370, 359, 361, 170, 170, 170, + 173, 296, 297, 170, 170, 170, 78, 367, 160, 148, + 149, 170, 170, 299, 170, 170, 305, 373, 374, 156, + 156, 375, 170, 170, 376, 377, 170, 371, 372, 170, + 170 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + + + +/* This macro is provided for backward compatibility. */ + +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULL; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 22: +/* Line 1787 of yacc.c */ +#line 368 "cfparse.y" + { + struct passwd *pw; + + if ((pw = getpwnam((yyvsp[(2) - (2)].val)->v)) == NULL) { + yyerror("unknown user \"%s\"", (yyvsp[(2) - (2)].val)->v); + return -1; + } + lcconf->uid = pw->pw_uid; + } + break; + + case 24: +/* Line 1787 of yacc.c */ +#line 378 "cfparse.y" + { lcconf->uid = (yyvsp[(2) - (2)].num); } + break; + + case 26: +/* Line 1787 of yacc.c */ +#line 380 "cfparse.y" + { + struct group *gr; + + if ((gr = getgrnam((yyvsp[(2) - (2)].val)->v)) == NULL) { + yyerror("unknown group \"%s\"", (yyvsp[(2) - (2)].val)->v); + return -1; + } + lcconf->gid = gr->gr_gid; + } + break; + + case 28: +/* Line 1787 of yacc.c */ +#line 390 "cfparse.y" + { lcconf->gid = (yyvsp[(2) - (2)].num); } + break; + + case 30: +/* Line 1787 of yacc.c */ +#line 391 "cfparse.y" + { lcconf->chroot = (yyvsp[(2) - (2)].val)->v; } + break; + + case 32: +/* Line 1787 of yacc.c */ +#line 397 "cfparse.y" + { + if ((yyvsp[(2) - (3)].num) >= LC_PATHTYPE_MAX) { + yyerror("invalid path type %d", (yyvsp[(2) - (3)].num)); + return -1; + } + + /* free old pathinfo */ + if (lcconf->pathinfo[(yyvsp[(2) - (3)].num)]) + racoon_free(lcconf->pathinfo[(yyvsp[(2) - (3)].num)]); + + /* set new pathinfo */ + lcconf->pathinfo[(yyvsp[(2) - (3)].num)] = racoon_strdup((yyvsp[(3) - (3)].val)->v); + STRDUP_FATAL(lcconf->pathinfo[(yyvsp[(2) - (3)].num)]); + vfree((yyvsp[(3) - (3)].val)); + } + break; + + case 34: +/* Line 1787 of yacc.c */ +#line 417 "cfparse.y" + { lcconf->complex_bundle = (yyvsp[(2) - (2)].num); } + break; + + case 36: +/* Line 1787 of yacc.c */ +#line 423 "cfparse.y" + { + char path[MAXPATHLEN]; + + getpathname(path, sizeof(path), + LC_PATHTYPE_INCLUDE, (yyvsp[(2) - (3)].val)->v); + vfree((yyvsp[(2) - (3)].val)); + if (yycf_switch_buffer(path) != 0) + return -1; + } + break; + + case 37: +/* Line 1787 of yacc.c */ +#line 437 "cfparse.y" + { + lcconf->pfkey_buffer_size = (yyvsp[(2) - (3)].num); + } + break; + + case 38: +/* Line 1787 of yacc.c */ +#line 444 "cfparse.y" + { + if ((yyvsp[(2) - (3)].num) >= LC_GSSENC_MAX) { + yyerror("invalid GSS ID encoding %d", (yyvsp[(2) - (3)].num)); + return -1; + } + lcconf->gss_id_enc = (yyvsp[(2) - (3)].num); + } + break; + + case 40: +/* Line 1787 of yacc.c */ +#line 459 "cfparse.y" + { + /* + * set the loglevel to the value specified + * in the configuration file plus the number + * of -d options specified on the command line + */ + loglevel += (yyvsp[(1) - (1)].num) - oldloglevel; + oldloglevel = (yyvsp[(1) - (1)].num); + } + break; + + case 44: +/* Line 1787 of yacc.c */ +#line 479 "cfparse.y" + { lcconf->pad_random = (yyvsp[(2) - (2)].num); } + break; + + case 46: +/* Line 1787 of yacc.c */ +#line 480 "cfparse.y" + { lcconf->pad_randomlen = (yyvsp[(2) - (2)].num); } + break; + + case 48: +/* Line 1787 of yacc.c */ +#line 481 "cfparse.y" + { lcconf->pad_maxsize = (yyvsp[(2) - (2)].num); } + break; + + case 50: +/* Line 1787 of yacc.c */ +#line 482 "cfparse.y" + { lcconf->pad_strict = (yyvsp[(2) - (2)].num); } + break; + + case 52: +/* Line 1787 of yacc.c */ +#line 483 "cfparse.y" + { lcconf->pad_excltail = (yyvsp[(2) - (2)].num); } + break; + + case 57: +/* Line 1787 of yacc.c */ +#line 496 "cfparse.y" + { + myaddr_listen((yyvsp[(2) - (2)].saddr), FALSE); + racoon_free((yyvsp[(2) - (2)].saddr)); + } + break; + + case 59: +/* Line 1787 of yacc.c */ +#line 502 "cfparse.y" + { +#ifdef ENABLE_NATT + myaddr_listen((yyvsp[(2) - (2)].saddr), TRUE); + racoon_free((yyvsp[(2) - (2)].saddr)); +#else + racoon_free((yyvsp[(2) - (2)].saddr)); + yyerror("NAT-T support not compiled in."); +#endif + } + break; + + case 61: +/* Line 1787 of yacc.c */ +#line 513 "cfparse.y" + { +#ifdef ENABLE_ADMINPORT + adminsock_conf((yyvsp[(2) - (5)].val), (yyvsp[(3) - (5)].val), (yyvsp[(4) - (5)].val), (yyvsp[(5) - (5)].num)); +#else + yywarn("admin port support not compiled in"); +#endif + } + break; + + case 63: +/* Line 1787 of yacc.c */ +#line 522 "cfparse.y" + { +#ifdef ENABLE_ADMINPORT + adminsock_conf((yyvsp[(2) - (2)].val), NULL, NULL, -1); +#else + yywarn("admin port support not compiled in"); +#endif + } + break; + + case 65: +/* Line 1787 of yacc.c */ +#line 531 "cfparse.y" + { +#ifdef ENABLE_ADMINPORT + adminsock_path = NULL; +#else + yywarn("admin port support not compiled in"); +#endif + } + break; + + case 67: +/* Line 1787 of yacc.c */ +#line 539 "cfparse.y" + { lcconf->strict_address = TRUE; } + break; + + case 69: +/* Line 1787 of yacc.c */ +#line 543 "cfparse.y" + { + char portbuf[10]; + + snprintf(portbuf, sizeof(portbuf), "%ld", (yyvsp[(2) - (2)].num)); + (yyval.saddr) = str2saddr((yyvsp[(1) - (2)].val)->v, portbuf); + vfree((yyvsp[(1) - (2)].val)); + if (!(yyval.saddr)) + return -1; + } + break; + + case 70: +/* Line 1787 of yacc.c */ +#line 554 "cfparse.y" + { (yyval.num) = PORT_ISAKMP; } + break; + + case 71: +/* Line 1787 of yacc.c */ +#line 555 "cfparse.y" + { (yyval.num) = (yyvsp[(1) - (1)].num); } + break; + + case 72: +/* Line 1787 of yacc.c */ +#line 560 "cfparse.y" + { +#ifndef ENABLE_HYBRID + yyerror("racoon not configured with --enable-hybrid"); + return -1; +#endif +#ifndef HAVE_LIBRADIUS + yyerror("racoon not configured with --with-libradius"); + return -1; +#endif +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + xauth_rad_config.timeout = 3; + xauth_rad_config.retries = 3; +#endif +#endif + } + break; + + case 76: +/* Line 1787 of yacc.c */ +#line 583 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + int i = xauth_rad_config.auth_server_count; + if (i == RADIUS_MAX_SERVERS) { + yyerror("maximum radius auth servers exceeded"); + return -1; + } + + xauth_rad_config.auth_server_list[i].host = vdup((yyvsp[(2) - (3)].val)); + xauth_rad_config.auth_server_list[i].secret = vdup((yyvsp[(3) - (3)].val)); + xauth_rad_config.auth_server_list[i].port = 0; // default port + xauth_rad_config.auth_server_count++; +#endif +#endif + } + break; + + case 78: +/* Line 1787 of yacc.c */ +#line 601 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + int i = xauth_rad_config.auth_server_count; + if (i == RADIUS_MAX_SERVERS) { + yyerror("maximum radius auth servers exceeded"); + return -1; + } + + xauth_rad_config.auth_server_list[i].host = vdup((yyvsp[(2) - (4)].val)); + xauth_rad_config.auth_server_list[i].secret = vdup((yyvsp[(4) - (4)].val)); + xauth_rad_config.auth_server_list[i].port = (yyvsp[(3) - (4)].num); + xauth_rad_config.auth_server_count++; +#endif +#endif + } + break; + + case 80: +/* Line 1787 of yacc.c */ +#line 619 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + int i = xauth_rad_config.acct_server_count; + if (i == RADIUS_MAX_SERVERS) { + yyerror("maximum radius account servers exceeded"); + return -1; + } + + xauth_rad_config.acct_server_list[i].host = vdup((yyvsp[(2) - (3)].val)); + xauth_rad_config.acct_server_list[i].secret = vdup((yyvsp[(3) - (3)].val)); + xauth_rad_config.acct_server_list[i].port = 0; // default port + xauth_rad_config.acct_server_count++; +#endif +#endif + } + break; + + case 82: +/* Line 1787 of yacc.c */ +#line 637 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + int i = xauth_rad_config.acct_server_count; + if (i == RADIUS_MAX_SERVERS) { + yyerror("maximum radius account servers exceeded"); + return -1; + } + + xauth_rad_config.acct_server_list[i].host = vdup((yyvsp[(2) - (4)].val)); + xauth_rad_config.acct_server_list[i].secret = vdup((yyvsp[(4) - (4)].val)); + xauth_rad_config.acct_server_list[i].port = (yyvsp[(3) - (4)].num); + xauth_rad_config.acct_server_count++; +#endif +#endif + } + break; + + case 84: +/* Line 1787 of yacc.c */ +#line 655 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + xauth_rad_config.timeout = (yyvsp[(2) - (2)].num); +#endif +#endif + } + break; + + case 86: +/* Line 1787 of yacc.c */ +#line 664 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + xauth_rad_config.retries = (yyvsp[(2) - (2)].num); +#endif +#endif + } + break; + + case 88: +/* Line 1787 of yacc.c */ +#line 676 "cfparse.y" + { +#ifndef ENABLE_HYBRID + yyerror("racoon not configured with --enable-hybrid"); + return -1; +#endif +#ifndef HAVE_LIBLDAP + yyerror("racoon not configured with --with-libldap"); + return -1; +#endif + } + break; + + case 92: +/* Line 1787 of yacc.c */ +#line 693 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (((yyvsp[(2) - (2)].num)<2)||((yyvsp[(2) - (2)].num)>3)) + yyerror("invalid ldap protocol version (2|3)"); + xauth_ldap_config.pver = (yyvsp[(2) - (2)].num); +#endif +#endif + } + break; + + case 94: +/* Line 1787 of yacc.c */ +#line 704 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.host != NULL) + vfree(xauth_ldap_config.host); + xauth_ldap_config.host = vdup((yyvsp[(2) - (2)].val)); +#endif +#endif + } + break; + + case 96: +/* Line 1787 of yacc.c */ +#line 715 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + xauth_ldap_config.port = (yyvsp[(2) - (2)].num); +#endif +#endif + } + break; + + case 98: +/* Line 1787 of yacc.c */ +#line 724 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.base != NULL) + vfree(xauth_ldap_config.base); + xauth_ldap_config.base = vdup((yyvsp[(2) - (2)].val)); +#endif +#endif + } + break; + + case 100: +/* Line 1787 of yacc.c */ +#line 735 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + xauth_ldap_config.subtree = (yyvsp[(2) - (2)].num); +#endif +#endif + } + break; + + case 102: +/* Line 1787 of yacc.c */ +#line 744 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.bind_dn != NULL) + vfree(xauth_ldap_config.bind_dn); + xauth_ldap_config.bind_dn = vdup((yyvsp[(2) - (2)].val)); +#endif +#endif + } + break; + + case 104: +/* Line 1787 of yacc.c */ +#line 755 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.bind_pw != NULL) + vfree(xauth_ldap_config.bind_pw); + xauth_ldap_config.bind_pw = vdup((yyvsp[(2) - (2)].val)); +#endif +#endif + } + break; + + case 106: +/* Line 1787 of yacc.c */ +#line 766 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.attr_user != NULL) + vfree(xauth_ldap_config.attr_user); + xauth_ldap_config.attr_user = vdup((yyvsp[(2) - (2)].val)); +#endif +#endif + } + break; + + case 108: +/* Line 1787 of yacc.c */ +#line 777 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.attr_addr != NULL) + vfree(xauth_ldap_config.attr_addr); + xauth_ldap_config.attr_addr = vdup((yyvsp[(2) - (2)].val)); +#endif +#endif + } + break; + + case 110: +/* Line 1787 of yacc.c */ +#line 788 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.attr_mask != NULL) + vfree(xauth_ldap_config.attr_mask); + xauth_ldap_config.attr_mask = vdup((yyvsp[(2) - (2)].val)); +#endif +#endif + } + break; + + case 112: +/* Line 1787 of yacc.c */ +#line 799 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.attr_group != NULL) + vfree(xauth_ldap_config.attr_group); + xauth_ldap_config.attr_group = vdup((yyvsp[(2) - (2)].val)); +#endif +#endif + } + break; + + case 114: +/* Line 1787 of yacc.c */ +#line 810 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.attr_member != NULL) + vfree(xauth_ldap_config.attr_member); + xauth_ldap_config.attr_member = vdup((yyvsp[(2) - (2)].val)); +#endif +#endif + } + break; + + case 119: +/* Line 1787 of yacc.c */ +#line 832 "cfparse.y" + { +#ifdef ENABLE_HYBRID + if (inet_pton(AF_INET, (yyvsp[(2) - (2)].val)->v, + &isakmp_cfg_config.network4) != 1) + yyerror("bad IPv4 network address."); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 121: +/* Line 1787 of yacc.c */ +#line 843 "cfparse.y" + { +#ifdef ENABLE_HYBRID + if (inet_pton(AF_INET, (yyvsp[(2) - (2)].val)->v, + &isakmp_cfg_config.netmask4) != 1) + yyerror("bad IPv4 netmask address."); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 125: +/* Line 1787 of yacc.c */ +#line 858 "cfparse.y" + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.splitnet_type = UNITY_LOCAL_LAN; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 127: +/* Line 1787 of yacc.c */ +#line 867 "cfparse.y" + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.splitnet_type = UNITY_SPLIT_INCLUDE; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 129: +/* Line 1787 of yacc.c */ +#line 876 "cfparse.y" + { +#ifndef ENABLE_HYBRID + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 131: +/* Line 1787 of yacc.c */ +#line 883 "cfparse.y" + { +#ifdef ENABLE_HYBRID + strncpy(&isakmp_cfg_config.default_domain[0], + (yyvsp[(2) - (2)].val)->v, MAXPATHLEN); + isakmp_cfg_config.default_domain[MAXPATHLEN] = '\0'; + vfree((yyvsp[(2) - (2)].val)); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 133: +/* Line 1787 of yacc.c */ +#line 895 "cfparse.y" + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 135: +/* Line 1787 of yacc.c */ +#line 904 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_RADIUS; +#else /* HAVE_LIBRADIUS */ + yyerror("racoon not configured with --with-libradius"); +#endif /* HAVE_LIBRADIUS */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 137: +/* Line 1787 of yacc.c */ +#line 917 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBPAM + isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_PAM; +#else /* HAVE_LIBPAM */ + yyerror("racoon not configured with --with-libpam"); +#endif /* HAVE_LIBPAM */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 139: +/* Line 1787 of yacc.c */ +#line 930 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_LDAP; +#else /* HAVE_LIBLDAP */ + yyerror("racoon not configured with --with-libldap"); +#endif /* HAVE_LIBLDAP */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 141: +/* Line 1787 of yacc.c */ +#line 943 "cfparse.y" + { +#ifndef ENABLE_HYBRID + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 143: +/* Line 1787 of yacc.c */ +#line 950 "cfparse.y" + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 145: +/* Line 1787 of yacc.c */ +#line 959 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_LDAP; +#else /* HAVE_LIBLDAP */ + yyerror("racoon not configured with --with-libldap"); +#endif /* HAVE_LIBLDAP */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 147: +/* Line 1787 of yacc.c */ +#line 972 "cfparse.y" + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 149: +/* Line 1787 of yacc.c */ +#line 981 "cfparse.y" + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_SYSTEM; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 151: +/* Line 1787 of yacc.c */ +#line 990 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_RADIUS; +#else /* HAVE_LIBRADIUS */ + yyerror("racoon not configured with --with-libradius"); +#endif /* HAVE_LIBRADIUS */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 153: +/* Line 1787 of yacc.c */ +#line 1003 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBPAM + isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_PAM; +#else /* HAVE_LIBPAM */ + yyerror("racoon not configured with --with-libpam"); +#endif /* HAVE_LIBPAM */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 155: +/* Line 1787 of yacc.c */ +#line 1016 "cfparse.y" + { +#ifdef ENABLE_HYBRID + if (isakmp_cfg_resize_pool((yyvsp[(2) - (2)].num)) != 0) + yyerror("cannot allocate memory for pool"); +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 157: +/* Line 1787 of yacc.c */ +#line 1026 "cfparse.y" + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.pfs_group = (yyvsp[(2) - (2)].num); +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 159: +/* Line 1787 of yacc.c */ +#line 1035 "cfparse.y" + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.save_passwd = (yyvsp[(2) - (2)].num); +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 161: +/* Line 1787 of yacc.c */ +#line 1044 "cfparse.y" + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.auth_throttle = (yyvsp[(2) - (2)].num); +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 163: +/* Line 1787 of yacc.c */ +#line 1053 "cfparse.y" + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL; +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 165: +/* Line 1787 of yacc.c */ +#line 1062 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_RADIUS; +#else /* HAVE_LIBRADIUS */ + yyerror("racoon not configured with --with-libradius"); +#endif /* HAVE_LIBRADIUS */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 167: +/* Line 1787 of yacc.c */ +#line 1075 "cfparse.y" + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LDAP; +#else /* HAVE_LIBLDAP */ + yyerror("racoon not configured with --with-libldap"); +#endif /* HAVE_LIBLDAP */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + break; + + case 169: +/* Line 1787 of yacc.c */ +#line 1088 "cfparse.y" + { +#ifdef ENABLE_HYBRID + strncpy(&isakmp_cfg_config.motd[0], (yyvsp[(2) - (2)].val)->v, MAXPATHLEN); + isakmp_cfg_config.motd[MAXPATHLEN] = '\0'; + vfree((yyvsp[(2) - (2)].val)); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 173: +/* Line 1787 of yacc.c */ +#line 1106 "cfparse.y" + { +#ifdef ENABLE_HYBRID + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + + if (icc->dns4_index > MAXNS) + yyerror("No more than %d DNS", MAXNS); + if (inet_pton(AF_INET, (yyvsp[(1) - (1)].val)->v, + &icc->dns4[icc->dns4_index++]) != 1) + yyerror("bad IPv4 DNS address."); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 176: +/* Line 1787 of yacc.c */ +#line 1127 "cfparse.y" + { +#ifdef ENABLE_HYBRID + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + + if (icc->nbns4_index > MAXWINS) + yyerror("No more than %d WINS", MAXWINS); + if (inet_pton(AF_INET, (yyvsp[(1) - (1)].val)->v, + &icc->nbns4[icc->nbns4_index++]) != 1) + yyerror("bad IPv4 WINS address."); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 179: +/* Line 1787 of yacc.c */ +#line 1148 "cfparse.y" + { +#ifdef ENABLE_HYBRID + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + struct unity_network network; + memset(&network,0,sizeof(network)); + + if (inet_pton(AF_INET, (yyvsp[(1) - (2)].val)->v, &network.addr4) != 1) + yyerror("bad IPv4 SPLIT address."); + + /* Turn $2 (the prefix) into a subnet mask */ + network.mask4.s_addr = ((yyvsp[(2) - (2)].num)) ? htonl(~((1 << (32 - (yyvsp[(2) - (2)].num))) - 1)) : 0; + + /* add the network to our list */ + if (splitnet_list_add(&icc->splitnet_list, &network,&icc->splitnet_count)) + yyerror("Unable to allocate split network"); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 182: +/* Line 1787 of yacc.c */ +#line 1175 "cfparse.y" + { +#ifdef ENABLE_HYBRID + char * groupname = NULL; + char ** grouplist = NULL; + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + + grouplist = racoon_realloc(icc->grouplist, + sizeof(char**)*(icc->groupcount+1)); + if (grouplist == NULL) { + yyerror("unable to allocate auth group list"); + return -1; + } + + groupname = racoon_malloc((yyvsp[(1) - (1)].val)->l+1); + if (groupname == NULL) { + yyerror("unable to allocate auth group name"); + return -1; + } + + memcpy(groupname,(yyvsp[(1) - (1)].val)->v,(yyvsp[(1) - (1)].val)->l); + groupname[(yyvsp[(1) - (1)].val)->l]=0; + grouplist[icc->groupcount]=groupname; + icc->grouplist = grouplist; + icc->groupcount++; + + vfree((yyvsp[(1) - (1)].val)); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 185: +/* Line 1787 of yacc.c */ +#line 1213 "cfparse.y" + { +#ifdef ENABLE_HYBRID + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + + if (!icc->splitdns_len) + { + icc->splitdns_list = racoon_malloc((yyvsp[(1) - (1)].val)->l); + if(icc->splitdns_list == NULL) { + yyerror("error allocating splitdns list buffer"); + return -1; + } + memcpy(icc->splitdns_list,(yyvsp[(1) - (1)].val)->v,(yyvsp[(1) - (1)].val)->l); + icc->splitdns_len = (yyvsp[(1) - (1)].val)->l; + } + else + { + int len = icc->splitdns_len + (yyvsp[(1) - (1)].val)->l + 1; + icc->splitdns_list = racoon_realloc(icc->splitdns_list,len); + if(icc->splitdns_list == NULL) { + yyerror("error allocating splitdns list buffer"); + return -1; + } + icc->splitdns_list[icc->splitdns_len] = ','; + memcpy(icc->splitdns_list + icc->splitdns_len + 1, (yyvsp[(1) - (1)].val)->v, (yyvsp[(1) - (1)].val)->l); + icc->splitdns_len = len; + } + vfree((yyvsp[(1) - (1)].val)); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 189: +/* Line 1787 of yacc.c */ +#line 1257 "cfparse.y" + { + lcconf->retry_counter = (yyvsp[(2) - (2)].num); + } + break; + + case 191: +/* Line 1787 of yacc.c */ +#line 1262 "cfparse.y" + { + lcconf->retry_interval = (yyvsp[(2) - (3)].num) * (yyvsp[(3) - (3)].num); + } + break; + + case 193: +/* Line 1787 of yacc.c */ +#line 1267 "cfparse.y" + { + lcconf->count_persend = (yyvsp[(2) - (2)].num); + } + break; + + case 195: +/* Line 1787 of yacc.c */ +#line 1272 "cfparse.y" + { + lcconf->retry_checkph1 = (yyvsp[(2) - (3)].num) * (yyvsp[(3) - (3)].num); + } + break; + + case 197: +/* Line 1787 of yacc.c */ +#line 1277 "cfparse.y" + { + lcconf->wait_ph2complete = (yyvsp[(2) - (3)].num) * (yyvsp[(3) - (3)].num); + } + break; + + case 199: +/* Line 1787 of yacc.c */ +#line 1282 "cfparse.y" + { +#ifdef ENABLE_NATT + if (libipsec_opt & LIBIPSEC_OPT_NATT) + lcconf->natt_ka_interval = (yyvsp[(2) - (3)].num) * (yyvsp[(3) - (3)].num); + else + yyerror("libipsec lacks NAT-T support"); +#else + yyerror("NAT-T support not compiled in."); +#endif + } + break; + + case 201: +/* Line 1787 of yacc.c */ +#line 1298 "cfparse.y" + { + cur_sainfo = newsainfo(); + if (cur_sainfo == NULL) { + yyerror("failed to allocate sainfo"); + return -1; + } + } + break; + + case 202: +/* Line 1787 of yacc.c */ +#line 1306 "cfparse.y" + { + struct sainfo *check; + + /* default */ + if (cur_sainfo->algs[algclass_ipsec_enc] == 0) { + yyerror("no encryption algorithm at %s", + sainfo2str(cur_sainfo)); + return -1; + } + if (cur_sainfo->algs[algclass_ipsec_auth] == 0) { + yyerror("no authentication algorithm at %s", + sainfo2str(cur_sainfo)); + return -1; + } + if (cur_sainfo->algs[algclass_ipsec_comp] == 0) { + yyerror("no compression algorithm at %s", + sainfo2str(cur_sainfo)); + return -1; + } + + /* duplicate check */ + check = getsainfo(cur_sainfo->idsrc, + cur_sainfo->iddst, + cur_sainfo->id_i, + NULL, + cur_sainfo->remoteid); + + if (check && ((check->idsrc != SAINFO_ANONYMOUS) && + (cur_sainfo->idsrc != SAINFO_ANONYMOUS))) { + yyerror("duplicated sainfo: %s", + sainfo2str(cur_sainfo)); + return -1; + } + + inssainfo(cur_sainfo); + } + break; + + case 204: +/* Line 1787 of yacc.c */ +#line 1346 "cfparse.y" + { + cur_sainfo->idsrc = SAINFO_ANONYMOUS; + cur_sainfo->iddst = SAINFO_ANONYMOUS; + } + break; + + case 205: +/* Line 1787 of yacc.c */ +#line 1351 "cfparse.y" + { + cur_sainfo->idsrc = SAINFO_ANONYMOUS; + cur_sainfo->iddst = SAINFO_CLIENTADDR; + } + break; + + case 206: +/* Line 1787 of yacc.c */ +#line 1356 "cfparse.y" + { + cur_sainfo->idsrc = SAINFO_ANONYMOUS; + cur_sainfo->iddst = (yyvsp[(2) - (2)].val); + } + break; + + case 207: +/* Line 1787 of yacc.c */ +#line 1361 "cfparse.y" + { + cur_sainfo->idsrc = (yyvsp[(1) - (2)].val); + cur_sainfo->iddst = SAINFO_ANONYMOUS; + } + break; + + case 208: +/* Line 1787 of yacc.c */ +#line 1366 "cfparse.y" + { + cur_sainfo->idsrc = (yyvsp[(1) - (2)].val); + cur_sainfo->iddst = SAINFO_CLIENTADDR; + } + break; + + case 209: +/* Line 1787 of yacc.c */ +#line 1371 "cfparse.y" + { + cur_sainfo->idsrc = (yyvsp[(1) - (2)].val); + cur_sainfo->iddst = (yyvsp[(2) - (2)].val); + } + break; + + case 210: +/* Line 1787 of yacc.c */ +#line 1378 "cfparse.y" + { + char portbuf[10]; + struct sockaddr *saddr; + + if (((yyvsp[(5) - (5)].num) == IPPROTO_ICMP || (yyvsp[(5) - (5)].num) == IPPROTO_ICMPV6) + && ((yyvsp[(4) - (5)].num) != IPSEC_PORT_ANY || (yyvsp[(4) - (5)].num) != IPSEC_PORT_ANY)) { + yyerror("port number must be \"any\"."); + return -1; + } + + snprintf(portbuf, sizeof(portbuf), "%lu", (yyvsp[(4) - (5)].num)); + saddr = str2saddr((yyvsp[(2) - (5)].val)->v, portbuf); + vfree((yyvsp[(2) - (5)].val)); + if (saddr == NULL) + return -1; + + switch (saddr->sa_family) { + case AF_INET: + if ((yyvsp[(5) - (5)].num) == IPPROTO_ICMPV6) { + yyerror("upper layer protocol mismatched.\n"); + racoon_free(saddr); + return -1; + } + (yyval.val) = ipsecdoi_sockaddr2id(saddr, + (yyvsp[(3) - (5)].num) == ~0 ? (sizeof(struct in_addr) << 3): (yyvsp[(3) - (5)].num), + (yyvsp[(5) - (5)].num)); + break; +#ifdef INET6 + case AF_INET6: + if ((yyvsp[(5) - (5)].num) == IPPROTO_ICMP) { + yyerror("upper layer protocol mismatched.\n"); + racoon_free(saddr); + return -1; + } + (yyval.val) = ipsecdoi_sockaddr2id(saddr, + (yyvsp[(3) - (5)].num) == ~0 ? (sizeof(struct in6_addr) << 3): (yyvsp[(3) - (5)].num), + (yyvsp[(5) - (5)].num)); + break; +#endif + default: + yyerror("invalid family: %d", saddr->sa_family); + (yyval.val) = NULL; + break; + } + racoon_free(saddr); + if ((yyval.val) == NULL) + return -1; + } + break; + + case 211: +/* Line 1787 of yacc.c */ +#line 1427 "cfparse.y" + { + char portbuf[10]; + struct sockaddr *laddr = NULL, *haddr = NULL; + char *cur = NULL; + + if (((yyvsp[(6) - (6)].num) == IPPROTO_ICMP || (yyvsp[(6) - (6)].num) == IPPROTO_ICMPV6) + && ((yyvsp[(5) - (6)].num) != IPSEC_PORT_ANY || (yyvsp[(5) - (6)].num) != IPSEC_PORT_ANY)) { + yyerror("port number must be \"any\"."); + return -1; + } + + snprintf(portbuf, sizeof(portbuf), "%lu", (yyvsp[(5) - (6)].num)); + + laddr = str2saddr((yyvsp[(2) - (6)].val)->v, portbuf); + if (laddr == NULL) { + return -1; + } + vfree((yyvsp[(2) - (6)].val)); + haddr = str2saddr((yyvsp[(3) - (6)].val)->v, portbuf); + if (haddr == NULL) { + racoon_free(laddr); + return -1; + } + vfree((yyvsp[(3) - (6)].val)); + + switch (laddr->sa_family) { + case AF_INET: + if ((yyvsp[(6) - (6)].num) == IPPROTO_ICMPV6) { + yyerror("upper layer protocol mismatched.\n"); + if (laddr) + racoon_free(laddr); + if (haddr) + racoon_free(haddr); + return -1; + } + (yyval.val) = ipsecdoi_sockrange2id(laddr, haddr, + (yyvsp[(6) - (6)].num)); + break; +#ifdef INET6 + case AF_INET6: + if ((yyvsp[(6) - (6)].num) == IPPROTO_ICMP) { + yyerror("upper layer protocol mismatched.\n"); + if (laddr) + racoon_free(laddr); + if (haddr) + racoon_free(haddr); + return -1; + } + (yyval.val) = ipsecdoi_sockrange2id(laddr, haddr, + (yyvsp[(6) - (6)].num)); + break; +#endif + default: + yyerror("invalid family: %d", laddr->sa_family); + (yyval.val) = NULL; + break; + } + if (laddr) + racoon_free(laddr); + if (haddr) + racoon_free(haddr); + if ((yyval.val) == NULL) + return -1; + } + break; + + case 212: +/* Line 1787 of yacc.c */ +#line 1492 "cfparse.y" + { + struct ipsecdoi_id_b *id_b; + + if ((yyvsp[(1) - (2)].num) == IDTYPE_ASN1DN) { + yyerror("id type forbidden: %d", (yyvsp[(1) - (2)].num)); + (yyval.val) = NULL; + return -1; + } + + (yyvsp[(2) - (2)].val)->l--; + + (yyval.val) = vmalloc(sizeof(*id_b) + (yyvsp[(2) - (2)].val)->l); + if ((yyval.val) == NULL) { + yyerror("failed to allocate identifier"); + return -1; + } + + id_b = (struct ipsecdoi_id_b *)(yyval.val)->v; + id_b->type = idtype2doi((yyvsp[(1) - (2)].num)); + + id_b->proto_id = 0; + id_b->port = 0; + + memcpy((yyval.val)->v + sizeof(*id_b), (yyvsp[(2) - (2)].val)->v, (yyvsp[(2) - (2)].val)->l); + } + break; + + case 213: +/* Line 1787 of yacc.c */ +#line 1520 "cfparse.y" + { + cur_sainfo->id_i = NULL; + } + break; + + case 214: +/* Line 1787 of yacc.c */ +#line 1524 "cfparse.y" + { + struct ipsecdoi_id_b *id_b; + vchar_t *idv; + + if (set_identifier(&idv, (yyvsp[(2) - (3)].num), (yyvsp[(3) - (3)].val)) != 0) { + yyerror("failed to set identifer.\n"); + return -1; + } + cur_sainfo->id_i = vmalloc(sizeof(*id_b) + idv->l); + if (cur_sainfo->id_i == NULL) { + yyerror("failed to allocate identifier"); + return -1; + } + + id_b = (struct ipsecdoi_id_b *)cur_sainfo->id_i->v; + id_b->type = idtype2doi((yyvsp[(2) - (3)].num)); + + id_b->proto_id = 0; + id_b->port = 0; + + memcpy(cur_sainfo->id_i->v + sizeof(*id_b), + idv->v, idv->l); + vfree(idv); + } + break; + + case 215: +/* Line 1787 of yacc.c */ +#line 1549 "cfparse.y" + { +#ifdef ENABLE_HYBRID + if ((cur_sainfo->group = vdup((yyvsp[(2) - (2)].val))) == NULL) { + yyerror("failed to set sainfo xauth group.\n"); + return -1; + } +#else + yyerror("racoon not configured with --enable-hybrid"); + return -1; +#endif + } + break; + + case 218: +/* Line 1787 of yacc.c */ +#line 1567 "cfparse.y" + { + cur_sainfo->pfs_group = (yyvsp[(2) - (2)].num); + } + break; + + case 220: +/* Line 1787 of yacc.c */ +#line 1572 "cfparse.y" + { + cur_sainfo->remoteid = (yyvsp[(2) - (2)].num); + } + break; + + case 222: +/* Line 1787 of yacc.c */ +#line 1577 "cfparse.y" + { + cur_sainfo->lifetime = (yyvsp[(3) - (4)].num) * (yyvsp[(4) - (4)].num); + } + break; + + case 224: +/* Line 1787 of yacc.c */ +#line 1582 "cfparse.y" + { +#if 1 + yyerror("byte lifetime support is deprecated"); + return -1; +#else + cur_sainfo->lifebyte = fix_lifebyte((yyvsp[(3) - (4)].num) * (yyvsp[(4) - (4)].num)); + if (cur_sainfo->lifebyte == 0) + return -1; +#endif + } + break; + + case 226: +/* Line 1787 of yacc.c */ +#line 1593 "cfparse.y" + { + cur_algclass = (yyvsp[(1) - (1)].num); + } + break; + + case 228: +/* Line 1787 of yacc.c */ +#line 1601 "cfparse.y" + { + inssainfoalg(&cur_sainfo->algs[cur_algclass], (yyvsp[(1) - (1)].alg)); + } + break; + + case 229: +/* Line 1787 of yacc.c */ +#line 1605 "cfparse.y" + { + inssainfoalg(&cur_sainfo->algs[cur_algclass], (yyvsp[(1) - (1)].alg)); + } + break; + + case 231: +/* Line 1787 of yacc.c */ +#line 1612 "cfparse.y" + { + int defklen; + + (yyval.alg) = newsainfoalg(); + if ((yyval.alg) == NULL) { + yyerror("failed to get algorithm allocation"); + return -1; + } + + (yyval.alg)->alg = algtype2doi(cur_algclass, (yyvsp[(1) - (2)].num)); + if ((yyval.alg)->alg == -1) { + yyerror("algorithm mismatched"); + racoon_free((yyval.alg)); + (yyval.alg) = NULL; + return -1; + } + + defklen = default_keylen(cur_algclass, (yyvsp[(1) - (2)].num)); + if (defklen == 0) { + if ((yyvsp[(2) - (2)].num)) { + yyerror("keylen not allowed"); + racoon_free((yyval.alg)); + (yyval.alg) = NULL; + return -1; + } + } else { + if ((yyvsp[(2) - (2)].num) && check_keylen(cur_algclass, (yyvsp[(1) - (2)].num), (yyvsp[(2) - (2)].num)) < 0) { + yyerror("invalid keylen %d", (yyvsp[(2) - (2)].num)); + racoon_free((yyval.alg)); + (yyval.alg) = NULL; + return -1; + } + } + + if ((yyvsp[(2) - (2)].num)) + (yyval.alg)->encklen = (yyvsp[(2) - (2)].num); + else + (yyval.alg)->encklen = defklen; + + /* check if it's supported algorithm by kernel */ + if (!(cur_algclass == algclass_ipsec_auth && (yyvsp[(1) - (2)].num) == algtype_non_auth) + && pk_checkalg(cur_algclass, (yyvsp[(1) - (2)].num), (yyval.alg)->encklen)) { + int a = algclass2doi(cur_algclass); + int b = algtype2doi(cur_algclass, (yyvsp[(1) - (2)].num)); + if (a == IPSECDOI_ATTR_AUTH) + a = IPSECDOI_PROTO_IPSEC_AH; + yyerror("algorithm %s not supported by the kernel (missing module?)", + s_ipsecdoi_trns(a, b)); + racoon_free((yyval.alg)); + (yyval.alg) = NULL; + return -1; + } + } + break; + + case 232: +/* Line 1787 of yacc.c */ +#line 1667 "cfparse.y" + { (yyval.num) = ~0; } + break; + + case 233: +/* Line 1787 of yacc.c */ +#line 1668 "cfparse.y" + { (yyval.num) = (yyvsp[(1) - (1)].num); } + break; + + case 234: +/* Line 1787 of yacc.c */ +#line 1671 "cfparse.y" + { (yyval.num) = IPSEC_PORT_ANY; } + break; + + case 235: +/* Line 1787 of yacc.c */ +#line 1672 "cfparse.y" + { (yyval.num) = (yyvsp[(1) - (1)].num); } + break; + + case 236: +/* Line 1787 of yacc.c */ +#line 1673 "cfparse.y" + { (yyval.num) = IPSEC_PORT_ANY; } + break; + + case 237: +/* Line 1787 of yacc.c */ +#line 1676 "cfparse.y" + { (yyval.num) = (yyvsp[(1) - (1)].num); } + break; + + case 238: +/* Line 1787 of yacc.c */ +#line 1677 "cfparse.y" + { (yyval.num) = (yyvsp[(1) - (1)].num); } + break; + + case 239: +/* Line 1787 of yacc.c */ +#line 1678 "cfparse.y" + { (yyval.num) = IPSEC_ULPROTO_ANY; } + break; + + case 240: +/* Line 1787 of yacc.c */ +#line 1681 "cfparse.y" + { (yyval.num) = 0; } + break; + + case 241: +/* Line 1787 of yacc.c */ +#line 1682 "cfparse.y" + { (yyval.num) = (yyvsp[(1) - (1)].num); } + break; + + case 242: +/* Line 1787 of yacc.c */ +#line 1688 "cfparse.y" + { + struct remoteconf *from, *new; + + if (getrmconf_by_name((yyvsp[(2) - (4)].val)->v) != NULL) { + yyerror("named remoteconf \"%s\" already exists."); + return -1; + } + + from = getrmconf_by_name((yyvsp[(4) - (4)].val)->v); + if (from == NULL) { + yyerror("named parent remoteconf \"%s\" does not exist.", + (yyvsp[(4) - (4)].val)->v); + return -1; + } + + new = duprmconf_shallow(from); + if (new == NULL) { + yyerror("failed to duplicate remoteconf from \"%s\".", + (yyvsp[(4) - (4)].val)->v); + return -1; + } + + new->name = racoon_strdup((yyvsp[(2) - (4)].val)->v); + cur_rmconf = new; + + vfree((yyvsp[(2) - (4)].val)); + vfree((yyvsp[(4) - (4)].val)); + } + break; + + case 244: +/* Line 1787 of yacc.c */ +#line 1718 "cfparse.y" + { + struct remoteconf *new; + + if (getrmconf_by_name((yyvsp[(2) - (2)].val)->v) != NULL) { + yyerror("Named remoteconf \"%s\" already exists."); + return -1; + } + + new = newrmconf(); + if (new == NULL) { + yyerror("failed to get new remoteconf."); + return -1; + } + new->name = racoon_strdup((yyvsp[(2) - (2)].val)->v); + cur_rmconf = new; + + vfree((yyvsp[(2) - (2)].val)); + } + break; + + case 246: +/* Line 1787 of yacc.c */ +#line 1738 "cfparse.y" + { + struct remoteconf *from, *new; + + from = getrmconf((yyvsp[(4) - (4)].saddr), GETRMCONF_F_NO_ANONYMOUS); + if (from == NULL) { + yyerror("failed to get remoteconf for %s.", + saddr2str((yyvsp[(4) - (4)].saddr))); + return -1; + } + + new = duprmconf_shallow(from); + if (new == NULL) { + yyerror("failed to duplicate remoteconf from %s.", + saddr2str((yyvsp[(4) - (4)].saddr))); + return -1; + } + + racoon_free((yyvsp[(4) - (4)].saddr)); + new->remote = (yyvsp[(2) - (4)].saddr); + cur_rmconf = new; + } + break; + + case 248: +/* Line 1787 of yacc.c */ +#line 1761 "cfparse.y" + { + struct remoteconf *new; + + new = newrmconf(); + if (new == NULL) { + yyerror("failed to get new remoteconf."); + return -1; + } + + new->remote = (yyvsp[(2) - (2)].saddr); + cur_rmconf = new; + } + break; + + case 251: +/* Line 1787 of yacc.c */ +#line 1779 "cfparse.y" + { + if (process_rmconf() != 0) + return -1; + } + break; + + case 252: +/* Line 1787 of yacc.c */ +#line 1787 "cfparse.y" + { + if (process_rmconf() != 0) + return -1; + } + break; + + case 253: +/* Line 1787 of yacc.c */ +#line 1794 "cfparse.y" + { + (yyval.saddr) = newsaddr(sizeof(struct sockaddr)); + (yyval.saddr)->sa_family = AF_UNSPEC; + ((struct sockaddr_in *)(yyval.saddr))->sin_port = htons((yyvsp[(2) - (2)].num)); + } + break; + + case 254: +/* Line 1787 of yacc.c */ +#line 1800 "cfparse.y" + { + (yyval.saddr) = (yyvsp[(1) - (1)].saddr); + if ((yyval.saddr) == NULL) { + yyerror("failed to allocate sockaddr"); + return -1; + } + } + break; + + case 257: +/* Line 1787 of yacc.c */ +#line 1814 "cfparse.y" + { + if (cur_rmconf->remote != NULL) { + yyerror("remote_address already specified"); + return -1; + } + cur_rmconf->remote = (yyvsp[(2) - (2)].saddr); + } + break; + + case 259: +/* Line 1787 of yacc.c */ +#line 1823 "cfparse.y" + { + cur_rmconf->etypes = NULL; + } + break; + + case 261: +/* Line 1787 of yacc.c */ +#line 1827 "cfparse.y" + { cur_rmconf->doitype = (yyvsp[(2) - (2)].num); } + break; + + case 263: +/* Line 1787 of yacc.c */ +#line 1828 "cfparse.y" + { cur_rmconf->sittype = (yyvsp[(2) - (2)].num); } + break; + + case 266: +/* Line 1787 of yacc.c */ +#line 1831 "cfparse.y" + { + yywarn("This directive without certtype will be removed!\n"); + yywarn("Please use 'peers_certfile x509 \"%s\";' instead\n", (yyvsp[(2) - (2)].val)->v); + + if (cur_rmconf->peerscert != NULL) { + yyerror("peers_certfile already defined\n"); + return -1; + } + + if (load_x509((yyvsp[(2) - (2)].val)->v, &cur_rmconf->peerscertfile, + &cur_rmconf->peerscert)) { + yyerror("failed to load certificate \"%s\"\n", + (yyvsp[(2) - (2)].val)->v); + return -1; + } + + vfree((yyvsp[(2) - (2)].val)); + } + break; + + case 268: +/* Line 1787 of yacc.c */ +#line 1851 "cfparse.y" + { + if (cur_rmconf->peerscert != NULL) { + yyerror("peers_certfile already defined\n"); + return -1; + } + + if (load_x509((yyvsp[(3) - (3)].val)->v, &cur_rmconf->peerscertfile, + &cur_rmconf->peerscert)) { + yyerror("failed to load certificate \"%s\"\n", + (yyvsp[(3) - (3)].val)->v); + return -1; + } + + vfree((yyvsp[(3) - (3)].val)); + } + break; + + case 270: +/* Line 1787 of yacc.c */ +#line 1868 "cfparse.y" + { + char path[MAXPATHLEN]; + int ret = 0; + + if (cur_rmconf->peerscert != NULL) { + yyerror("peers_certfile already defined\n"); + return -1; + } + + cur_rmconf->peerscert = vmalloc(1); + if (cur_rmconf->peerscert == NULL) { + yyerror("failed to allocate peerscert"); + return -1; + } + cur_rmconf->peerscert->v[0] = ISAKMP_CERT_PLAINRSA; + + getpathname(path, sizeof(path), + LC_PATHTYPE_CERT, (yyvsp[(3) - (3)].val)->v); + if (rsa_parse_file(cur_rmconf->rsa_public, path, + RSA_TYPE_PUBLIC)) { + yyerror("Couldn't parse keyfile.\n", path); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, + "Public PlainRSA keyfile parsed: %s\n", path); + + vfree((yyvsp[(3) - (3)].val)); + } + break; + + case 272: +/* Line 1787 of yacc.c */ +#line 1898 "cfparse.y" + { + if (cur_rmconf->peerscert != NULL) { + yyerror("peers_certfile already defined\n"); + return -1; + } + cur_rmconf->peerscert = vmalloc(1); + if (cur_rmconf->peerscert == NULL) { + yyerror("failed to allocate peerscert"); + return -1; + } + cur_rmconf->peerscert->v[0] = ISAKMP_CERT_DNS; + } + break; + + case 274: +/* Line 1787 of yacc.c */ +#line 1912 "cfparse.y" + { + if (cur_rmconf->cacert != NULL) { + yyerror("ca_type already defined\n"); + return -1; + } + + if (load_x509((yyvsp[(3) - (3)].val)->v, &cur_rmconf->cacertfile, + &cur_rmconf->cacert)) { + yyerror("failed to load certificate \"%s\"\n", + (yyvsp[(3) - (3)].val)->v); + return -1; + } + + vfree((yyvsp[(3) - (3)].val)); + } + break; + + case 276: +/* Line 1787 of yacc.c */ +#line 1928 "cfparse.y" + { cur_rmconf->verify_cert = (yyvsp[(2) - (2)].num); } + break; + + case 278: +/* Line 1787 of yacc.c */ +#line 1929 "cfparse.y" + { cur_rmconf->send_cert = (yyvsp[(2) - (2)].num); } + break; + + case 280: +/* Line 1787 of yacc.c */ +#line 1930 "cfparse.y" + { cur_rmconf->send_cr = (yyvsp[(2) - (2)].num); } + break; + + case 282: +/* Line 1787 of yacc.c */ +#line 1931 "cfparse.y" + { cur_rmconf->match_empty_cr = (yyvsp[(2) - (2)].num); } + break; + + case 284: +/* Line 1787 of yacc.c */ +#line 1933 "cfparse.y" + { + if (set_identifier(&cur_rmconf->idv, (yyvsp[(2) - (3)].num), (yyvsp[(3) - (3)].val)) != 0) { + yyerror("failed to set identifer.\n"); + return -1; + } + cur_rmconf->idvtype = (yyvsp[(2) - (3)].num); + } + break; + + case 286: +/* Line 1787 of yacc.c */ +#line 1942 "cfparse.y" + { + if (set_identifier_qual(&cur_rmconf->idv, (yyvsp[(2) - (4)].num), (yyvsp[(4) - (4)].val), (yyvsp[(3) - (4)].num)) != 0) { + yyerror("failed to set identifer.\n"); + return -1; + } + cur_rmconf->idvtype = (yyvsp[(2) - (4)].num); + } + break; + + case 288: +/* Line 1787 of yacc.c */ +#line 1951 "cfparse.y" + { +#ifdef ENABLE_HYBRID + /* formerly identifier type login */ + if (xauth_rmconf_used(&cur_rmconf->xauth) == -1) { + yyerror("failed to allocate xauth state\n"); + return -1; + } + if ((cur_rmconf->xauth->login = vdup((yyvsp[(2) - (2)].val))) == NULL) { + yyerror("failed to set identifer.\n"); + return -1; + } +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + break; + + case 290: +/* Line 1787 of yacc.c */ +#line 1968 "cfparse.y" + { + struct idspec *id; + id = newidspec(); + if (id == NULL) { + yyerror("failed to allocate idspec"); + return -1; + } + if (set_identifier(&id->id, (yyvsp[(2) - (3)].num), (yyvsp[(3) - (3)].val)) != 0) { + yyerror("failed to set identifer.\n"); + racoon_free(id); + return -1; + } + id->idtype = (yyvsp[(2) - (3)].num); + genlist_append (cur_rmconf->idvl_p, id); + } + break; + + case 292: +/* Line 1787 of yacc.c */ +#line 1985 "cfparse.y" + { + struct idspec *id; + id = newidspec(); + if (id == NULL) { + yyerror("failed to allocate idspec"); + return -1; + } + if (set_identifier_qual(&id->id, (yyvsp[(2) - (4)].num), (yyvsp[(4) - (4)].val), (yyvsp[(3) - (4)].num)) != 0) { + yyerror("failed to set identifer.\n"); + racoon_free(id); + return -1; + } + id->idtype = (yyvsp[(2) - (4)].num); + genlist_append (cur_rmconf->idvl_p, id); + } + break; + + case 294: +/* Line 1787 of yacc.c */ +#line 2001 "cfparse.y" + { cur_rmconf->verify_identifier = (yyvsp[(2) - (2)].num); } + break; + + case 296: +/* Line 1787 of yacc.c */ +#line 2002 "cfparse.y" + { cur_rmconf->nonce_size = (yyvsp[(2) - (2)].num); } + break; + + case 298: +/* Line 1787 of yacc.c */ +#line 2004 "cfparse.y" + { + yyerror("dh_group cannot be defined here."); + return -1; + } + break; + + case 300: +/* Line 1787 of yacc.c */ +#line 2009 "cfparse.y" + { cur_rmconf->passive = (yyvsp[(2) - (2)].num); } + break; + + case 302: +/* Line 1787 of yacc.c */ +#line 2010 "cfparse.y" + { cur_rmconf->ike_frag = (yyvsp[(2) - (2)].num); } + break; + + case 304: +/* Line 1787 of yacc.c */ +#line 2011 "cfparse.y" + { cur_rmconf->ike_frag = ISAKMP_FRAG_FORCE; } + break; + + case 306: +/* Line 1787 of yacc.c */ +#line 2012 "cfparse.y" + { +#ifdef SADB_X_EXT_NAT_T_FRAG + if (libipsec_opt & LIBIPSEC_OPT_FRAG) + cur_rmconf->esp_frag = (yyvsp[(2) - (2)].num); + else + yywarn("libipsec lacks IKE frag support"); +#else + yywarn("Your kernel does not support esp_frag"); +#endif + } + break; + + case 308: +/* Line 1787 of yacc.c */ +#line 2022 "cfparse.y" + { + if (cur_rmconf->script[SCRIPT_PHASE1_UP] != NULL) + vfree(cur_rmconf->script[SCRIPT_PHASE1_UP]); + + cur_rmconf->script[SCRIPT_PHASE1_UP] = + script_path_add(vdup((yyvsp[(2) - (3)].val))); + } + break; + + case 310: +/* Line 1787 of yacc.c */ +#line 2029 "cfparse.y" + { + if (cur_rmconf->script[SCRIPT_PHASE1_DOWN] != NULL) + vfree(cur_rmconf->script[SCRIPT_PHASE1_DOWN]); + + cur_rmconf->script[SCRIPT_PHASE1_DOWN] = + script_path_add(vdup((yyvsp[(2) - (3)].val))); + } + break; + + case 312: +/* Line 1787 of yacc.c */ +#line 2036 "cfparse.y" + { + if (cur_rmconf->script[SCRIPT_PHASE1_DEAD] != NULL) + vfree(cur_rmconf->script[SCRIPT_PHASE1_DEAD]); + + cur_rmconf->script[SCRIPT_PHASE1_DEAD] = + script_path_add(vdup((yyvsp[(2) - (3)].val))); + } + break; + + case 314: +/* Line 1787 of yacc.c */ +#line 2043 "cfparse.y" + { cur_rmconf->mode_cfg = (yyvsp[(2) - (2)].num); } + break; + + case 316: +/* Line 1787 of yacc.c */ +#line 2044 "cfparse.y" + { + cur_rmconf->weak_phase1_check = (yyvsp[(2) - (2)].num); + } + break; + + case 318: +/* Line 1787 of yacc.c */ +#line 2047 "cfparse.y" + { cur_rmconf->gen_policy = (yyvsp[(2) - (2)].num); } + break; + + case 320: +/* Line 1787 of yacc.c */ +#line 2048 "cfparse.y" + { cur_rmconf->gen_policy = (yyvsp[(2) - (2)].num); } + break; + + case 322: +/* Line 1787 of yacc.c */ +#line 2049 "cfparse.y" + { cur_rmconf->support_proxy = (yyvsp[(2) - (2)].num); } + break; + + case 324: +/* Line 1787 of yacc.c */ +#line 2050 "cfparse.y" + { cur_rmconf->ini_contact = (yyvsp[(2) - (2)].num); } + break; + + case 326: +/* Line 1787 of yacc.c */ +#line 2052 "cfparse.y" + { +#ifdef ENABLE_NATT + if (libipsec_opt & LIBIPSEC_OPT_NATT) + cur_rmconf->nat_traversal = (yyvsp[(2) - (2)].num); + else + yyerror("libipsec lacks NAT-T support"); +#else + yyerror("NAT-T support not compiled in."); +#endif + } + break; + + case 328: +/* Line 1787 of yacc.c */ +#line 2063 "cfparse.y" + { +#ifdef ENABLE_NATT + if (libipsec_opt & LIBIPSEC_OPT_NATT) + cur_rmconf->nat_traversal = NATT_FORCE; + else + yyerror("libipsec lacks NAT-T support"); +#else + yyerror("NAT-T support not compiled in."); +#endif + } + break; + + case 330: +/* Line 1787 of yacc.c */ +#line 2074 "cfparse.y" + { +#ifdef ENABLE_DPD + cur_rmconf->dpd = (yyvsp[(2) - (2)].num); +#else + yyerror("DPD support not compiled in."); +#endif + } + break; + + case 332: +/* Line 1787 of yacc.c */ +#line 2082 "cfparse.y" + { +#ifdef ENABLE_DPD + cur_rmconf->dpd_interval = (yyvsp[(2) - (2)].num); +#else + yyerror("DPD support not compiled in."); +#endif + } + break; + + case 334: +/* Line 1787 of yacc.c */ +#line 2091 "cfparse.y" + { +#ifdef ENABLE_DPD + cur_rmconf->dpd_retry = (yyvsp[(2) - (2)].num); +#else + yyerror("DPD support not compiled in."); +#endif + } + break; + + case 336: +/* Line 1787 of yacc.c */ +#line 2100 "cfparse.y" + { +#ifdef ENABLE_DPD + cur_rmconf->dpd_maxfails = (yyvsp[(2) - (2)].num); +#else + yyerror("DPD support not compiled in."); +#endif + } + break; + + case 338: +/* Line 1787 of yacc.c */ +#line 2108 "cfparse.y" + { cur_rmconf->rekey = (yyvsp[(2) - (2)].num); } + break; + + case 340: +/* Line 1787 of yacc.c */ +#line 2109 "cfparse.y" + { cur_rmconf->rekey = REKEY_FORCE; } + break; + + case 342: +/* Line 1787 of yacc.c */ +#line 2111 "cfparse.y" + { + cur_rmconf->ph1id = (yyvsp[(2) - (2)].num); + } + break; + + case 344: +/* Line 1787 of yacc.c */ +#line 2116 "cfparse.y" + { + cur_rmconf->lifetime = (yyvsp[(3) - (4)].num) * (yyvsp[(4) - (4)].num); + } + break; + + case 346: +/* Line 1787 of yacc.c */ +#line 2120 "cfparse.y" + { cur_rmconf->pcheck_level = (yyvsp[(2) - (2)].num); } + break; + + case 348: +/* Line 1787 of yacc.c */ +#line 2122 "cfparse.y" + { +#if 1 + yyerror("byte lifetime support is deprecated in Phase1"); + return -1; +#else + yywarn("the lifetime of bytes in phase 1 " + "will be ignored at the moment."); + cur_rmconf->lifebyte = fix_lifebyte((yyvsp[(3) - (4)].num) * (yyvsp[(4) - (4)].num)); + if (cur_rmconf->lifebyte == 0) + return -1; +#endif + } + break; + + case 350: +/* Line 1787 of yacc.c */ +#line 2136 "cfparse.y" + { + struct secprotospec *spspec; + + spspec = newspspec(); + if (spspec == NULL) + return -1; + insspspec(cur_rmconf, spspec); + } + break; + + case 353: +/* Line 1787 of yacc.c */ +#line 2149 "cfparse.y" + { + struct etypes *new; + new = racoon_malloc(sizeof(struct etypes)); + if (new == NULL) { + yyerror("failed to allocate etypes"); + return -1; + } + new->type = (yyvsp[(2) - (2)].num); + new->next = NULL; + if (cur_rmconf->etypes == NULL) + cur_rmconf->etypes = new; + else { + struct etypes *p; + for (p = cur_rmconf->etypes; + p->next != NULL; + p = p->next) + ; + p->next = new; + } + } + break; + + case 354: +/* Line 1787 of yacc.c */ +#line 2172 "cfparse.y" + { + if (cur_rmconf->mycert != NULL) { + yyerror("certificate_type already defined\n"); + return -1; + } + + if (load_x509((yyvsp[(2) - (3)].val)->v, &cur_rmconf->mycertfile, + &cur_rmconf->mycert)) { + yyerror("failed to load certificate \"%s\"\n", + (yyvsp[(2) - (3)].val)->v); + return -1; + } + + cur_rmconf->myprivfile = racoon_strdup((yyvsp[(3) - (3)].val)->v); + STRDUP_FATAL(cur_rmconf->myprivfile); + + vfree((yyvsp[(2) - (3)].val)); + vfree((yyvsp[(3) - (3)].val)); + } + break; + + case 356: +/* Line 1787 of yacc.c */ +#line 2193 "cfparse.y" + { + char path[MAXPATHLEN]; + int ret = 0; + + if (cur_rmconf->mycert != NULL) { + yyerror("certificate_type already defined\n"); + return -1; + } + + cur_rmconf->mycert = vmalloc(1); + if (cur_rmconf->mycert == NULL) { + yyerror("failed to allocate mycert"); + return -1; + } + cur_rmconf->mycert->v[0] = ISAKMP_CERT_PLAINRSA; + + getpathname(path, sizeof(path), + LC_PATHTYPE_CERT, (yyvsp[(2) - (2)].val)->v); + cur_rmconf->send_cr = FALSE; + cur_rmconf->send_cert = FALSE; + cur_rmconf->verify_cert = FALSE; + if (rsa_parse_file(cur_rmconf->rsa_private, path, + RSA_TYPE_PRIVATE)) { + yyerror("Couldn't parse keyfile.\n", path); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, + "Private PlainRSA keyfile parsed: %s\n", path); + vfree((yyvsp[(2) - (2)].val)); + } + break; + + case 358: +/* Line 1787 of yacc.c */ +#line 2227 "cfparse.y" + { + (yyval.num) = algtype2doi(algclass_isakmp_dh, (yyvsp[(1) - (1)].num)); + if ((yyval.num) == -1) { + yyerror("must be DH group"); + return -1; + } + } + break; + + case 359: +/* Line 1787 of yacc.c */ +#line 2235 "cfparse.y" + { + if (ARRAYLEN(num2dhgroup) > (yyvsp[(1) - (1)].num) && num2dhgroup[(yyvsp[(1) - (1)].num)] != 0) { + (yyval.num) = num2dhgroup[(yyvsp[(1) - (1)].num)]; + } else { + yyerror("must be DH group"); + (yyval.num) = 0; + return -1; + } + } + break; + + case 360: +/* Line 1787 of yacc.c */ +#line 2246 "cfparse.y" + { (yyval.val) = NULL; } + break; + + case 361: +/* Line 1787 of yacc.c */ +#line 2247 "cfparse.y" + { (yyval.val) = (yyvsp[(1) - (1)].val); } + break; + + case 362: +/* Line 1787 of yacc.c */ +#line 2248 "cfparse.y" + { (yyval.val) = (yyvsp[(1) - (1)].val); } + break; + + case 365: +/* Line 1787 of yacc.c */ +#line 2256 "cfparse.y" + { + cur_rmconf->spspec->lifetime = (yyvsp[(3) - (4)].num) * (yyvsp[(4) - (4)].num); + } + break; + + case 367: +/* Line 1787 of yacc.c */ +#line 2261 "cfparse.y" + { +#if 1 + yyerror("byte lifetime support is deprecated"); + return -1; +#else + cur_rmconf->spspec->lifebyte = fix_lifebyte((yyvsp[(3) - (4)].num) * (yyvsp[(4) - (4)].num)); + if (cur_rmconf->spspec->lifebyte == 0) + return -1; +#endif + } + break; + + case 369: +/* Line 1787 of yacc.c */ +#line 2273 "cfparse.y" + { + cur_rmconf->spspec->algclass[algclass_isakmp_dh] = (yyvsp[(2) - (2)].num); + } + break; + + case 371: +/* Line 1787 of yacc.c */ +#line 2278 "cfparse.y" + { + if (cur_rmconf->spspec->vendorid != VENDORID_GSSAPI) { + yyerror("wrong Vendor ID for gssapi_id"); + return -1; + } + if (cur_rmconf->spspec->gssid != NULL) + racoon_free(cur_rmconf->spspec->gssid); + cur_rmconf->spspec->gssid = + racoon_strdup((yyvsp[(2) - (2)].val)->v); + STRDUP_FATAL(cur_rmconf->spspec->gssid); + } + break; + + case 373: +/* Line 1787 of yacc.c */ +#line 2291 "cfparse.y" + { + int doi; + int defklen; + + doi = algtype2doi((yyvsp[(1) - (3)].num), (yyvsp[(2) - (3)].num)); + if (doi == -1) { + yyerror("algorithm mismatched 1"); + return -1; + } + + switch ((yyvsp[(1) - (3)].num)) { + case algclass_isakmp_enc: + /* reject suppressed algorithms */ +#ifndef HAVE_OPENSSL_RC5_H + if ((yyvsp[(2) - (3)].num) == algtype_rc5) { + yyerror("algorithm %s not supported", + s_attr_isakmp_enc(doi)); + return -1; + } +#endif +#ifndef HAVE_OPENSSL_IDEA_H + if ((yyvsp[(2) - (3)].num) == algtype_idea) { + yyerror("algorithm %s not supported", + s_attr_isakmp_enc(doi)); + return -1; + } +#endif + + cur_rmconf->spspec->algclass[algclass_isakmp_enc] = doi; + defklen = default_keylen((yyvsp[(1) - (3)].num), (yyvsp[(2) - (3)].num)); + if (defklen == 0) { + if ((yyvsp[(3) - (3)].num)) { + yyerror("keylen not allowed"); + return -1; + } + } else { + if ((yyvsp[(3) - (3)].num) && check_keylen((yyvsp[(1) - (3)].num), (yyvsp[(2) - (3)].num), (yyvsp[(3) - (3)].num)) < 0) { + yyerror("invalid keylen %d", (yyvsp[(3) - (3)].num)); + return -1; + } + } + if ((yyvsp[(3) - (3)].num)) + cur_rmconf->spspec->encklen = (yyvsp[(3) - (3)].num); + else + cur_rmconf->spspec->encklen = defklen; + break; + case algclass_isakmp_hash: + cur_rmconf->spspec->algclass[algclass_isakmp_hash] = doi; + break; + case algclass_isakmp_ameth: + cur_rmconf->spspec->algclass[algclass_isakmp_ameth] = doi; + /* + * We may have to set the Vendor ID for the + * authentication method we're using. + */ + switch ((yyvsp[(2) - (3)].num)) { + case algtype_gssapikrb: + if (cur_rmconf->spspec->vendorid != + VENDORID_UNKNOWN) { + yyerror("Vendor ID mismatch " + "for auth method"); + return -1; + } + /* + * For interoperability with Win2k, + * we set the Vendor ID to "GSSAPI". + */ + cur_rmconf->spspec->vendorid = + VENDORID_GSSAPI; + break; + case algtype_rsasig: + if (oakley_get_certtype(cur_rmconf->peerscert) == ISAKMP_CERT_PLAINRSA) { + if (rsa_list_count(cur_rmconf->rsa_private) == 0) { + yyerror ("Private PlainRSA key not set. " + "Use directive 'certificate_type plainrsa ...'\n"); + return -1; + } + if (rsa_list_count(cur_rmconf->rsa_public) == 0) { + yyerror ("Public PlainRSA keys not set. " + "Use directive 'peers_certfile plainrsa ...'\n"); + return -1; + } + } + break; + default: + break; + } + break; + default: + yyerror("algorithm mismatched 2"); + return -1; + } + } + break; + + case 375: +/* Line 1787 of yacc.c */ +#line 2388 "cfparse.y" + { (yyval.num) = 1; } + break; + + case 376: +/* Line 1787 of yacc.c */ +#line 2389 "cfparse.y" + { (yyval.num) = 60; } + break; + + case 377: +/* Line 1787 of yacc.c */ +#line 2390 "cfparse.y" + { (yyval.num) = (60 * 60); } + break; + + case 378: +/* Line 1787 of yacc.c */ +#line 2393 "cfparse.y" + { (yyval.num) = 1; } + break; + + case 379: +/* Line 1787 of yacc.c */ +#line 2394 "cfparse.y" + { (yyval.num) = 1024; } + break; + + case 380: +/* Line 1787 of yacc.c */ +#line 2395 "cfparse.y" + { (yyval.num) = (1024 * 1024); } + break; + + case 381: +/* Line 1787 of yacc.c */ +#line 2396 "cfparse.y" + { (yyval.num) = (1024 * 1024 * 1024); } + break; + + +/* Line 1787 of yacc.c */ +#line 5198 "cfparse.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +/* Line 2048 of yacc.c */ +#line 2398 "cfparse.y" + + +static struct secprotospec * +newspspec() +{ + struct secprotospec *new; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) { + yyerror("failed to allocate spproto"); + return NULL; + } + + new->encklen = 0; /*XXX*/ + + /* + * Default to "uknown" vendor -- we will override this + * as necessary. When we send a Vendor ID payload, an + * "unknown" will be translated to a KAME/racoon ID. + */ + new->vendorid = VENDORID_UNKNOWN; + + return new; +} + +/* + * insert into head of list. + */ +static void +insspspec(rmconf, spspec) + struct remoteconf *rmconf; + struct secprotospec *spspec; +{ + if (rmconf->spspec != NULL) + rmconf->spspec->prev = spspec; + spspec->next = rmconf->spspec; + rmconf->spspec = spspec; +} + +static struct secprotospec * +dupspspec(spspec) + struct secprotospec *spspec; +{ + struct secprotospec *new; + + new = newspspec(); + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "dupspspec: malloc failed\n"); + return NULL; + } + memcpy(new, spspec, sizeof(*new)); + + if (spspec->gssid) { + new->gssid = racoon_strdup(spspec->gssid); + STRDUP_FATAL(new->gssid); + } + if (spspec->remote) { + new->remote = racoon_malloc(sizeof(*new->remote)); + if (new->remote == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "dupspspec: malloc failed (remote)\n"); + return NULL; + } + memcpy(new->remote, spspec->remote, sizeof(*new->remote)); + } + + return new; +} + +/* + * copy the whole list + */ +void +dupspspec_list(dst, src) + struct remoteconf *dst, *src; +{ + struct secprotospec *p, *new, *last; + + for(p = src->spspec, last = NULL; p; p = p->next, last = new) { + new = dupspspec(p); + if (new == NULL) + exit(1); + + new->prev = last; + new->next = NULL; /* not necessary but clean */ + + if (last) + last->next = new; + else /* first element */ + dst->spspec = new; + + } +} + +/* + * delete the whole list + */ +void +flushspspec(rmconf) + struct remoteconf *rmconf; +{ + struct secprotospec *p; + + while(rmconf->spspec != NULL) { + p = rmconf->spspec; + rmconf->spspec = p->next; + if (p->next != NULL) + p->next->prev = NULL; /* not necessary but clean */ + + if (p->gssid) + racoon_free(p->gssid); + if (p->remote) + racoon_free(p->remote); + racoon_free(p); + } + rmconf->spspec = NULL; +} + +/* set final acceptable proposal */ +static int +set_isakmp_proposal(rmconf) + struct remoteconf *rmconf; +{ + struct secprotospec *s; + int prop_no = 1; + int trns_no = 1; + int32_t types[MAXALGCLASS]; + + /* mandatory check */ + if (rmconf->spspec == NULL) { + yyerror("no remote specification found: %s.\n", + saddr2str(rmconf->remote)); + return -1; + } + for (s = rmconf->spspec; s != NULL; s = s->next) { + /* XXX need more to check */ + if (s->algclass[algclass_isakmp_enc] == 0) { + yyerror("encryption algorithm required."); + return -1; + } + if (s->algclass[algclass_isakmp_hash] == 0) { + yyerror("hash algorithm required."); + return -1; + } + if (s->algclass[algclass_isakmp_dh] == 0) { + yyerror("DH group required."); + return -1; + } + if (s->algclass[algclass_isakmp_ameth] == 0) { + yyerror("authentication method required."); + return -1; + } + } + + /* skip to last part */ + for (s = rmconf->spspec; s->next != NULL; s = s->next) + ; + + while (s != NULL) { + plog(LLV_DEBUG2, LOCATION, NULL, + "lifetime = %ld\n", (long) + (s->lifetime ? s->lifetime : rmconf->lifetime)); + plog(LLV_DEBUG2, LOCATION, NULL, + "lifebyte = %d\n", + s->lifebyte ? s->lifebyte : rmconf->lifebyte); + plog(LLV_DEBUG2, LOCATION, NULL, + "encklen=%d\n", s->encklen); + + memset(types, 0, ARRAYLEN(types)); + types[algclass_isakmp_enc] = s->algclass[algclass_isakmp_enc]; + types[algclass_isakmp_hash] = s->algclass[algclass_isakmp_hash]; + types[algclass_isakmp_dh] = s->algclass[algclass_isakmp_dh]; + types[algclass_isakmp_ameth] = + s->algclass[algclass_isakmp_ameth]; + + /* expanding spspec */ + clean_tmpalgtype(); + trns_no = expand_isakmpspec(prop_no, trns_no, types, + algclass_isakmp_enc, algclass_isakmp_ameth + 1, + s->lifetime ? s->lifetime : rmconf->lifetime, + s->lifebyte ? s->lifebyte : rmconf->lifebyte, + s->encklen, s->vendorid, s->gssid, + rmconf); + if (trns_no == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to expand isakmp proposal.\n"); + return -1; + } + + s = s->prev; + } + + if (rmconf->proposal == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no proposal found.\n"); + return -1; + } + + return 0; +} + +static void +clean_tmpalgtype() +{ + int i; + for (i = 0; i < MAXALGCLASS; i++) + tmpalgtype[i] = 0; /* means algorithm undefined. */ +} + +static int +expand_isakmpspec(prop_no, trns_no, types, + class, last, lifetime, lifebyte, encklen, vendorid, gssid, + rmconf) + int prop_no, trns_no; + int *types, class, last; + time_t lifetime; + int lifebyte; + int encklen; + int vendorid; + char *gssid; + struct remoteconf *rmconf; +{ + struct isakmpsa *new; + + /* debugging */ + { + int j; + char tb[10]; + plog(LLV_DEBUG2, LOCATION, NULL, + "p:%d t:%d\n", prop_no, trns_no); + for (j = class; j < MAXALGCLASS; j++) { + snprintf(tb, sizeof(tb), "%d", types[j]); + plog(LLV_DEBUG2, LOCATION, NULL, + "%s%s%s%s\n", + s_algtype(j, types[j]), + types[j] ? "(" : "", + tb[0] == '0' ? "" : tb, + types[j] ? ")" : ""); + } + plog(LLV_DEBUG2, LOCATION, NULL, "\n"); + } + +#define TMPALGTYPE2STR(n) \ + s_algtype(algclass_isakmp_##n, types[algclass_isakmp_##n]) + /* check mandatory values */ + if (types[algclass_isakmp_enc] == 0 + || types[algclass_isakmp_ameth] == 0 + || types[algclass_isakmp_hash] == 0 + || types[algclass_isakmp_dh] == 0) { + yyerror("few definition of algorithm " + "enc=%s ameth=%s hash=%s dhgroup=%s.\n", + TMPALGTYPE2STR(enc), + TMPALGTYPE2STR(ameth), + TMPALGTYPE2STR(hash), + TMPALGTYPE2STR(dh)); + return -1; + } +#undef TMPALGTYPE2STR + + /* set new sa */ + new = newisakmpsa(); + if (new == NULL) { + yyerror("failed to allocate isakmp sa"); + return -1; + } + new->prop_no = prop_no; + new->trns_no = trns_no++; + new->lifetime = lifetime; + new->lifebyte = lifebyte; + new->enctype = types[algclass_isakmp_enc]; + new->encklen = encklen; + new->authmethod = types[algclass_isakmp_ameth]; + new->hashtype = types[algclass_isakmp_hash]; + new->dh_group = types[algclass_isakmp_dh]; + new->vendorid = vendorid; +#ifdef HAVE_GSSAPI + if (new->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { + if (gssid != NULL) { + if ((new->gssid = vmalloc(strlen(gssid))) == NULL) { + racoon_free(new); + yyerror("failed to allocate gssid"); + return -1; + } + memcpy(new->gssid->v, gssid, new->gssid->l); + racoon_free(gssid); + } else { + /* + * Allocate the default ID so that it gets put + * into a GSS ID attribute during the Phase 1 + * exchange. + */ + new->gssid = gssapi_get_default_gss_id(); + } + } +#endif + insisakmpsa(new, rmconf); + + return trns_no; +} + +#if 0 +/* + * fix lifebyte. + * Must be more than 1024B because its unit is kilobytes. + * That is defined RFC2407. + */ +static int +fix_lifebyte(t) + unsigned long t; +{ + if (t < 1024) { + yyerror("byte size should be more than 1024B."); + return 0; + } + + return(t / 1024); +} +#endif + +int +cfparse() +{ + int error; + + yyerrorcount = 0; + yycf_init_buffer(); + + if (yycf_switch_buffer(lcconf->racoon_conf) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "could not read configuration file \"%s\"\n", + lcconf->racoon_conf); + return -1; + } + + error = yyparse(); + if (error != 0) { + if (yyerrorcount) { + plog(LLV_ERROR, LOCATION, NULL, + "fatal parse failure (%d errors)\n", + yyerrorcount); + } else { + plog(LLV_ERROR, LOCATION, NULL, + "fatal parse failure.\n"); + } + return -1; + } + + if (error == 0 && yyerrorcount) { + plog(LLV_ERROR, LOCATION, NULL, + "parse error is nothing, but yyerrorcount is %d.\n", + yyerrorcount); + exit(1); + } + + yycf_clean_buffer(); + + plog(LLV_DEBUG2, LOCATION, NULL, "parse successed.\n"); + + return 0; +} + +int +cfreparse() +{ + flushph2(); + flushph1(); + flushrmconf(); + flushsainfo(); + clean_tmpalgtype(); + return(cfparse()); +} + +#ifdef ENABLE_ADMINPORT +static void +adminsock_conf(path, owner, group, mode_dec) + vchar_t *path; + vchar_t *owner; + vchar_t *group; + int mode_dec; +{ + struct passwd *pw = NULL; + struct group *gr = NULL; + mode_t mode = 0; + uid_t uid; + gid_t gid; + int isnum; + + adminsock_path = path->v; + + if (owner == NULL) + return; + + errno = 0; + uid = atoi(owner->v); + isnum = !errno; + if (((pw = getpwnam(owner->v)) == NULL) && !isnum) + yyerror("User \"%s\" does not exist", owner->v); + + if (pw) + adminsock_owner = pw->pw_uid; + else + adminsock_owner = uid; + + if (group == NULL) + return; + + errno = 0; + gid = atoi(group->v); + isnum = !errno; + if (((gr = getgrnam(group->v)) == NULL) && !isnum) + yyerror("Group \"%s\" does not exist", group->v); + + if (gr) + adminsock_group = gr->gr_gid; + else + adminsock_group = gid; + + if (mode_dec == -1) + return; + + if (mode_dec > 777) + yyerror("Mode 0%03o is invalid", mode_dec); + if (mode_dec >= 400) { mode += 0400; mode_dec -= 400; } + if (mode_dec >= 200) { mode += 0200; mode_dec -= 200; } + if (mode_dec >= 100) { mode += 0200; mode_dec -= 100; } + + if (mode_dec > 77) + yyerror("Mode 0%03o is invalid", mode_dec); + if (mode_dec >= 40) { mode += 040; mode_dec -= 40; } + if (mode_dec >= 20) { mode += 020; mode_dec -= 20; } + if (mode_dec >= 10) { mode += 020; mode_dec -= 10; } + + if (mode_dec > 7) + yyerror("Mode 0%03o is invalid", mode_dec); + if (mode_dec >= 4) { mode += 04; mode_dec -= 4; } + if (mode_dec >= 2) { mode += 02; mode_dec -= 2; } + if (mode_dec >= 1) { mode += 02; mode_dec -= 1; } + + adminsock_mode = mode; + + return; +} +#endif diff --git a/ipsec-tools/src/racoon/cfparse.h b/ipsec-tools/src/racoon/cfparse.h new file mode 100644 index 00000000..71ea0a60 --- /dev/null +++ b/ipsec-tools/src/racoon/cfparse.h @@ -0,0 +1,434 @@ +/* A Bison parser, made by GNU Bison 2.6.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + 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 3 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef YY_CFPARSE_H +# define YY_CFPARSE_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + PRIVSEP = 258, + USER = 259, + GROUP = 260, + CHROOT = 261, + PATH = 262, + PATHTYPE = 263, + INCLUDE = 264, + PFKEY_BUFFER = 265, + LOGGING = 266, + LOGLEV = 267, + PADDING = 268, + PAD_RANDOMIZE = 269, + PAD_RANDOMIZELEN = 270, + PAD_MAXLEN = 271, + PAD_STRICT = 272, + PAD_EXCLTAIL = 273, + LISTEN = 274, + X_ISAKMP = 275, + X_ISAKMP_NATT = 276, + X_ADMIN = 277, + STRICT_ADDRESS = 278, + ADMINSOCK = 279, + DISABLED = 280, + LDAPCFG = 281, + LDAP_HOST = 282, + LDAP_PORT = 283, + LDAP_PVER = 284, + LDAP_BASE = 285, + LDAP_BIND_DN = 286, + LDAP_BIND_PW = 287, + LDAP_SUBTREE = 288, + LDAP_ATTR_USER = 289, + LDAP_ATTR_ADDR = 290, + LDAP_ATTR_MASK = 291, + LDAP_ATTR_GROUP = 292, + LDAP_ATTR_MEMBER = 293, + RADCFG = 294, + RAD_AUTH = 295, + RAD_ACCT = 296, + RAD_TIMEOUT = 297, + RAD_RETRIES = 298, + MODECFG = 299, + CFG_NET4 = 300, + CFG_MASK4 = 301, + CFG_DNS4 = 302, + CFG_NBNS4 = 303, + CFG_DEFAULT_DOMAIN = 304, + CFG_AUTH_SOURCE = 305, + CFG_AUTH_GROUPS = 306, + CFG_SYSTEM = 307, + CFG_RADIUS = 308, + CFG_PAM = 309, + CFG_LDAP = 310, + CFG_LOCAL = 311, + CFG_NONE = 312, + CFG_GROUP_SOURCE = 313, + CFG_ACCOUNTING = 314, + CFG_CONF_SOURCE = 315, + CFG_MOTD = 316, + CFG_POOL_SIZE = 317, + CFG_AUTH_THROTTLE = 318, + CFG_SPLIT_NETWORK = 319, + CFG_SPLIT_LOCAL = 320, + CFG_SPLIT_INCLUDE = 321, + CFG_SPLIT_DNS = 322, + CFG_PFS_GROUP = 323, + CFG_SAVE_PASSWD = 324, + RETRY = 325, + RETRY_COUNTER = 326, + RETRY_INTERVAL = 327, + RETRY_PERSEND = 328, + RETRY_PHASE1 = 329, + RETRY_PHASE2 = 330, + NATT_KA = 331, + ALGORITHM_CLASS = 332, + ALGORITHMTYPE = 333, + STRENGTHTYPE = 334, + SAINFO = 335, + FROM = 336, + REMOTE = 337, + ANONYMOUS = 338, + CLIENTADDR = 339, + INHERIT = 340, + REMOTE_ADDRESS = 341, + EXCHANGE_MODE = 342, + EXCHANGETYPE = 343, + DOI = 344, + DOITYPE = 345, + SITUATION = 346, + SITUATIONTYPE = 347, + CERTIFICATE_TYPE = 348, + CERTTYPE = 349, + PEERS_CERTFILE = 350, + CA_TYPE = 351, + VERIFY_CERT = 352, + SEND_CERT = 353, + SEND_CR = 354, + MATCH_EMPTY_CR = 355, + IDENTIFIERTYPE = 356, + IDENTIFIERQUAL = 357, + MY_IDENTIFIER = 358, + PEERS_IDENTIFIER = 359, + VERIFY_IDENTIFIER = 360, + DNSSEC = 361, + CERT_X509 = 362, + CERT_PLAINRSA = 363, + NONCE_SIZE = 364, + DH_GROUP = 365, + KEEPALIVE = 366, + PASSIVE = 367, + INITIAL_CONTACT = 368, + NAT_TRAVERSAL = 369, + REMOTE_FORCE_LEVEL = 370, + PROPOSAL_CHECK = 371, + PROPOSAL_CHECK_LEVEL = 372, + GENERATE_POLICY = 373, + GENERATE_LEVEL = 374, + SUPPORT_PROXY = 375, + PROPOSAL = 376, + EXEC_PATH = 377, + EXEC_COMMAND = 378, + EXEC_SUCCESS = 379, + EXEC_FAILURE = 380, + GSS_ID = 381, + GSS_ID_ENC = 382, + GSS_ID_ENCTYPE = 383, + COMPLEX_BUNDLE = 384, + DPD = 385, + DPD_DELAY = 386, + DPD_RETRY = 387, + DPD_MAXFAIL = 388, + PH1ID = 389, + XAUTH_LOGIN = 390, + WEAK_PHASE1_CHECK = 391, + REKEY = 392, + PREFIX = 393, + PORT = 394, + PORTANY = 395, + UL_PROTO = 396, + ANY = 397, + IKE_FRAG = 398, + ESP_FRAG = 399, + MODE_CFG = 400, + PFS_GROUP = 401, + LIFETIME = 402, + LIFETYPE_TIME = 403, + LIFETYPE_BYTE = 404, + STRENGTH = 405, + REMOTEID = 406, + SCRIPT = 407, + PHASE1_UP = 408, + PHASE1_DOWN = 409, + PHASE1_DEAD = 410, + NUMBER = 411, + SWITCH = 412, + BOOLEAN = 413, + HEXSTRING = 414, + QUOTEDSTRING = 415, + ADDRSTRING = 416, + ADDRRANGE = 417, + UNITTYPE_BYTE = 418, + UNITTYPE_KBYTES = 419, + UNITTYPE_MBYTES = 420, + UNITTYPE_TBYTES = 421, + UNITTYPE_SEC = 422, + UNITTYPE_MIN = 423, + UNITTYPE_HOUR = 424, + EOS = 425, + BOC = 426, + EOC = 427, + COMMA = 428 + }; +#endif +/* Tokens. */ +#define PRIVSEP 258 +#define USER 259 +#define GROUP 260 +#define CHROOT 261 +#define PATH 262 +#define PATHTYPE 263 +#define INCLUDE 264 +#define PFKEY_BUFFER 265 +#define LOGGING 266 +#define LOGLEV 267 +#define PADDING 268 +#define PAD_RANDOMIZE 269 +#define PAD_RANDOMIZELEN 270 +#define PAD_MAXLEN 271 +#define PAD_STRICT 272 +#define PAD_EXCLTAIL 273 +#define LISTEN 274 +#define X_ISAKMP 275 +#define X_ISAKMP_NATT 276 +#define X_ADMIN 277 +#define STRICT_ADDRESS 278 +#define ADMINSOCK 279 +#define DISABLED 280 +#define LDAPCFG 281 +#define LDAP_HOST 282 +#define LDAP_PORT 283 +#define LDAP_PVER 284 +#define LDAP_BASE 285 +#define LDAP_BIND_DN 286 +#define LDAP_BIND_PW 287 +#define LDAP_SUBTREE 288 +#define LDAP_ATTR_USER 289 +#define LDAP_ATTR_ADDR 290 +#define LDAP_ATTR_MASK 291 +#define LDAP_ATTR_GROUP 292 +#define LDAP_ATTR_MEMBER 293 +#define RADCFG 294 +#define RAD_AUTH 295 +#define RAD_ACCT 296 +#define RAD_TIMEOUT 297 +#define RAD_RETRIES 298 +#define MODECFG 299 +#define CFG_NET4 300 +#define CFG_MASK4 301 +#define CFG_DNS4 302 +#define CFG_NBNS4 303 +#define CFG_DEFAULT_DOMAIN 304 +#define CFG_AUTH_SOURCE 305 +#define CFG_AUTH_GROUPS 306 +#define CFG_SYSTEM 307 +#define CFG_RADIUS 308 +#define CFG_PAM 309 +#define CFG_LDAP 310 +#define CFG_LOCAL 311 +#define CFG_NONE 312 +#define CFG_GROUP_SOURCE 313 +#define CFG_ACCOUNTING 314 +#define CFG_CONF_SOURCE 315 +#define CFG_MOTD 316 +#define CFG_POOL_SIZE 317 +#define CFG_AUTH_THROTTLE 318 +#define CFG_SPLIT_NETWORK 319 +#define CFG_SPLIT_LOCAL 320 +#define CFG_SPLIT_INCLUDE 321 +#define CFG_SPLIT_DNS 322 +#define CFG_PFS_GROUP 323 +#define CFG_SAVE_PASSWD 324 +#define RETRY 325 +#define RETRY_COUNTER 326 +#define RETRY_INTERVAL 327 +#define RETRY_PERSEND 328 +#define RETRY_PHASE1 329 +#define RETRY_PHASE2 330 +#define NATT_KA 331 +#define ALGORITHM_CLASS 332 +#define ALGORITHMTYPE 333 +#define STRENGTHTYPE 334 +#define SAINFO 335 +#define FROM 336 +#define REMOTE 337 +#define ANONYMOUS 338 +#define CLIENTADDR 339 +#define INHERIT 340 +#define REMOTE_ADDRESS 341 +#define EXCHANGE_MODE 342 +#define EXCHANGETYPE 343 +#define DOI 344 +#define DOITYPE 345 +#define SITUATION 346 +#define SITUATIONTYPE 347 +#define CERTIFICATE_TYPE 348 +#define CERTTYPE 349 +#define PEERS_CERTFILE 350 +#define CA_TYPE 351 +#define VERIFY_CERT 352 +#define SEND_CERT 353 +#define SEND_CR 354 +#define MATCH_EMPTY_CR 355 +#define IDENTIFIERTYPE 356 +#define IDENTIFIERQUAL 357 +#define MY_IDENTIFIER 358 +#define PEERS_IDENTIFIER 359 +#define VERIFY_IDENTIFIER 360 +#define DNSSEC 361 +#define CERT_X509 362 +#define CERT_PLAINRSA 363 +#define NONCE_SIZE 364 +#define DH_GROUP 365 +#define KEEPALIVE 366 +#define PASSIVE 367 +#define INITIAL_CONTACT 368 +#define NAT_TRAVERSAL 369 +#define REMOTE_FORCE_LEVEL 370 +#define PROPOSAL_CHECK 371 +#define PROPOSAL_CHECK_LEVEL 372 +#define GENERATE_POLICY 373 +#define GENERATE_LEVEL 374 +#define SUPPORT_PROXY 375 +#define PROPOSAL 376 +#define EXEC_PATH 377 +#define EXEC_COMMAND 378 +#define EXEC_SUCCESS 379 +#define EXEC_FAILURE 380 +#define GSS_ID 381 +#define GSS_ID_ENC 382 +#define GSS_ID_ENCTYPE 383 +#define COMPLEX_BUNDLE 384 +#define DPD 385 +#define DPD_DELAY 386 +#define DPD_RETRY 387 +#define DPD_MAXFAIL 388 +#define PH1ID 389 +#define XAUTH_LOGIN 390 +#define WEAK_PHASE1_CHECK 391 +#define REKEY 392 +#define PREFIX 393 +#define PORT 394 +#define PORTANY 395 +#define UL_PROTO 396 +#define ANY 397 +#define IKE_FRAG 398 +#define ESP_FRAG 399 +#define MODE_CFG 400 +#define PFS_GROUP 401 +#define LIFETIME 402 +#define LIFETYPE_TIME 403 +#define LIFETYPE_BYTE 404 +#define STRENGTH 405 +#define REMOTEID 406 +#define SCRIPT 407 +#define PHASE1_UP 408 +#define PHASE1_DOWN 409 +#define PHASE1_DEAD 410 +#define NUMBER 411 +#define SWITCH 412 +#define BOOLEAN 413 +#define HEXSTRING 414 +#define QUOTEDSTRING 415 +#define ADDRSTRING 416 +#define ADDRRANGE 417 +#define UNITTYPE_BYTE 418 +#define UNITTYPE_KBYTES 419 +#define UNITTYPE_MBYTES 420 +#define UNITTYPE_TBYTES 421 +#define UNITTYPE_SEC 422 +#define UNITTYPE_MIN 423 +#define UNITTYPE_HOUR 424 +#define EOS 425 +#define BOC 426 +#define EOC 427 +#define COMMA 428 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 2049 of yacc.c */ +#line 247 "cfparse.y" + + unsigned long num; + vchar_t *val; + struct remoteconf *rmconf; + struct sockaddr *saddr; + struct sainfoalg *alg; + + +/* Line 2049 of yacc.c */ +#line 412 "cfparse.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE yylval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !YY_CFPARSE_H */ diff --git a/ipsec-tools/src/racoon/cfparse.y b/ipsec-tools/src/racoon/cfparse.y new file mode 100644 index 00000000..0d9bd670 --- /dev/null +++ b/ipsec-tools/src/racoon/cfparse.y @@ -0,0 +1,2841 @@ +/* $NetBSD: cfparse.y,v 1.42.2.1 2012/08/29 08:42:24 tteras Exp $ */ + +/* Id: cfparse.y,v 1.66 2006/08/22 18:17:17 manubsd Exp */ + +%{ +/* + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 and 2003 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include PATH_IPSEC_H + +#ifdef ENABLE_HYBRID +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "str2val.h" +#include "genlist.h" +#include "debug.h" + +#include "admin.h" +#include "privsep.h" +#include "cfparse_proto.h" +#include "cftoken_proto.h" +#include "algorithm.h" +#include "localconf.h" +#include "policy.h" +#include "sainfo.h" +#include "oakley.h" +#include "pfkey.h" +#include "remoteconf.h" +#include "grabmyaddr.h" +#include "isakmp_var.h" +#include "handler.h" +#include "isakmp.h" +#include "nattraversal.h" +#include "isakmp_frag.h" +#ifdef ENABLE_HYBRID +#include "resolv.h" +#include "isakmp_unity.h" +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif +#include "ipsec_doi.h" +#include "strnames.h" +#include "gcmalloc.h" +#ifdef HAVE_GSSAPI +#include "gssapi.h" +#endif +#include "vendorid.h" +#include "rsalist.h" +#include "crypto_openssl.h" + +struct secprotospec { + int prop_no; + int trns_no; + int strength; /* for isakmp/ipsec */ + int encklen; /* for isakmp/ipsec */ + time_t lifetime; /* for isakmp */ + int lifebyte; /* for isakmp */ + int proto_id; /* for ipsec (isakmp?) */ + int ipsec_level; /* for ipsec */ + int encmode; /* for ipsec */ + int vendorid; /* for isakmp */ + char *gssid; + struct sockaddr *remote; + int algclass[MAXALGCLASS]; + + struct secprotospec *next; /* the tail is the most prefiered. */ + struct secprotospec *prev; +}; + +static int num2dhgroup[] = { + 0, + OAKLEY_ATTR_GRP_DESC_MODP768, + OAKLEY_ATTR_GRP_DESC_MODP1024, + OAKLEY_ATTR_GRP_DESC_EC2N155, + OAKLEY_ATTR_GRP_DESC_EC2N185, + OAKLEY_ATTR_GRP_DESC_MODP1536, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + OAKLEY_ATTR_GRP_DESC_MODP2048, + OAKLEY_ATTR_GRP_DESC_MODP3072, + OAKLEY_ATTR_GRP_DESC_MODP4096, + OAKLEY_ATTR_GRP_DESC_MODP6144, + OAKLEY_ATTR_GRP_DESC_MODP8192 +}; + +static struct remoteconf *cur_rmconf; +static int tmpalgtype[MAXALGCLASS]; +static struct sainfo *cur_sainfo; +static int cur_algclass; +static int oldloglevel = LLV_BASE; + +static struct secprotospec *newspspec __P((void)); +static void insspspec __P((struct remoteconf *, struct secprotospec *)); +void dupspspec_list __P((struct remoteconf *dst, struct remoteconf *src)); +void flushspspec __P((struct remoteconf *)); +static void adminsock_conf __P((vchar_t *, vchar_t *, vchar_t *, int)); + +static int set_isakmp_proposal __P((struct remoteconf *)); +static void clean_tmpalgtype __P((void)); +static int expand_isakmpspec __P((int, int, int *, + int, int, time_t, int, int, int, char *, struct remoteconf *)); + +void freeetypes (struct etypes **etypes); + +static int load_x509(const char *file, char **filenameptr, + vchar_t **certptr) +{ + char path[PATH_MAX]; + + getpathname(path, sizeof(path), LC_PATHTYPE_CERT, file); + *certptr = eay_get_x509cert(path); + if (*certptr == NULL) + return -1; + + *filenameptr = racoon_strdup(file); + STRDUP_FATAL(*filenameptr); + + return 0; +} + +static int process_rmconf() +{ + + /* check a exchange mode */ + if (cur_rmconf->etypes == NULL) { + yyerror("no exchange mode specified.\n"); + return -1; + } + + if (cur_rmconf->idvtype == IDTYPE_UNDEFINED) + cur_rmconf->idvtype = IDTYPE_ADDRESS; + + if (cur_rmconf->idvtype == IDTYPE_ASN1DN) { + if (cur_rmconf->mycertfile) { + if (cur_rmconf->idv) + yywarn("Both CERT and ASN1 ID " + "are set. Hope this is OK.\n"); + /* TODO: Preparse the DN here */ + } else if (cur_rmconf->idv) { + /* OK, using asn1dn without X.509. */ + } else { + yyerror("ASN1 ID not specified " + "and no CERT defined!\n"); + return -1; + } + } + + if (duprmconf_finish(cur_rmconf)) + return -1; + + if (set_isakmp_proposal(cur_rmconf) != 0) + return -1; + + /* DH group settting if aggressive mode is there. */ + if (check_etypeok(cur_rmconf, (void*) ISAKMP_ETYPE_AGG)) { + struct isakmpsa *p; + int b = 0; + + /* DH group */ + for (p = cur_rmconf->proposal; p; p = p->next) { + if (b == 0 || (b && b == p->dh_group)) { + b = p->dh_group; + continue; + } + yyerror("DH group must be equal " + "in all proposals " + "when aggressive mode is " + "used.\n"); + return -1; + } + cur_rmconf->dh_group = b; + + if (cur_rmconf->dh_group == 0) { + yyerror("DH group must be set in the proposal.\n"); + return -1; + } + + /* DH group settting if PFS is required. */ + if (oakley_setdhgroup(cur_rmconf->dh_group, + &cur_rmconf->dhgrp) < 0) { + yyerror("failed to set DH value.\n"); + return -1; + } + } + + insrmconf(cur_rmconf); + + return 0; +} + +%} + +%union { + unsigned long num; + vchar_t *val; + struct remoteconf *rmconf; + struct sockaddr *saddr; + struct sainfoalg *alg; +} + + /* privsep */ +%token PRIVSEP USER GROUP CHROOT + /* path */ +%token PATH PATHTYPE + /* include */ +%token INCLUDE + /* PFKEY_BUFFER */ +%token PFKEY_BUFFER + /* logging */ +%token LOGGING LOGLEV + /* padding */ +%token PADDING PAD_RANDOMIZE PAD_RANDOMIZELEN PAD_MAXLEN PAD_STRICT PAD_EXCLTAIL + /* listen */ +%token LISTEN X_ISAKMP X_ISAKMP_NATT X_ADMIN STRICT_ADDRESS ADMINSOCK DISABLED + /* ldap config */ +%token LDAPCFG LDAP_HOST LDAP_PORT LDAP_PVER LDAP_BASE LDAP_BIND_DN LDAP_BIND_PW LDAP_SUBTREE +%token LDAP_ATTR_USER LDAP_ATTR_ADDR LDAP_ATTR_MASK LDAP_ATTR_GROUP LDAP_ATTR_MEMBER + /* radius config */ +%token RADCFG RAD_AUTH RAD_ACCT RAD_TIMEOUT RAD_RETRIES + /* modecfg */ +%token MODECFG CFG_NET4 CFG_MASK4 CFG_DNS4 CFG_NBNS4 CFG_DEFAULT_DOMAIN +%token CFG_AUTH_SOURCE CFG_AUTH_GROUPS CFG_SYSTEM CFG_RADIUS CFG_PAM CFG_LDAP CFG_LOCAL CFG_NONE +%token CFG_GROUP_SOURCE CFG_ACCOUNTING CFG_CONF_SOURCE CFG_MOTD CFG_POOL_SIZE CFG_AUTH_THROTTLE +%token CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL CFG_SPLIT_INCLUDE CFG_SPLIT_DNS +%token CFG_PFS_GROUP CFG_SAVE_PASSWD + + /* timer */ +%token RETRY RETRY_COUNTER RETRY_INTERVAL RETRY_PERSEND +%token RETRY_PHASE1 RETRY_PHASE2 NATT_KA + /* algorithm */ +%token ALGORITHM_CLASS ALGORITHMTYPE STRENGTHTYPE + /* sainfo */ +%token SAINFO FROM + /* remote */ +%token REMOTE ANONYMOUS CLIENTADDR INHERIT REMOTE_ADDRESS +%token EXCHANGE_MODE EXCHANGETYPE DOI DOITYPE SITUATION SITUATIONTYPE +%token CERTIFICATE_TYPE CERTTYPE PEERS_CERTFILE CA_TYPE +%token VERIFY_CERT SEND_CERT SEND_CR MATCH_EMPTY_CR +%token IDENTIFIERTYPE IDENTIFIERQUAL MY_IDENTIFIER +%token PEERS_IDENTIFIER VERIFY_IDENTIFIER +%token DNSSEC CERT_X509 CERT_PLAINRSA +%token NONCE_SIZE DH_GROUP KEEPALIVE PASSIVE INITIAL_CONTACT +%token NAT_TRAVERSAL REMOTE_FORCE_LEVEL +%token PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL +%token GENERATE_POLICY GENERATE_LEVEL SUPPORT_PROXY +%token PROPOSAL +%token EXEC_PATH EXEC_COMMAND EXEC_SUCCESS EXEC_FAILURE +%token GSS_ID GSS_ID_ENC GSS_ID_ENCTYPE +%token COMPLEX_BUNDLE +%token DPD DPD_DELAY DPD_RETRY DPD_MAXFAIL +%token PH1ID +%token XAUTH_LOGIN WEAK_PHASE1_CHECK +%token REKEY + +%token PREFIX PORT PORTANY UL_PROTO ANY IKE_FRAG ESP_FRAG MODE_CFG +%token PFS_GROUP LIFETIME LIFETYPE_TIME LIFETYPE_BYTE STRENGTH REMOTEID + +%token SCRIPT PHASE1_UP PHASE1_DOWN PHASE1_DEAD + +%token NUMBER SWITCH BOOLEAN +%token HEXSTRING QUOTEDSTRING ADDRSTRING ADDRRANGE +%token UNITTYPE_BYTE UNITTYPE_KBYTES UNITTYPE_MBYTES UNITTYPE_TBYTES +%token UNITTYPE_SEC UNITTYPE_MIN UNITTYPE_HOUR +%token EOS BOC EOC COMMA + +%type NUMBER BOOLEAN SWITCH keylength +%type PATHTYPE IDENTIFIERTYPE IDENTIFIERQUAL LOGLEV GSS_ID_ENCTYPE +%type ALGORITHM_CLASS dh_group_num +%type ALGORITHMTYPE STRENGTHTYPE +%type PREFIX prefix PORT port ike_port +%type ul_proto UL_PROTO +%type EXCHANGETYPE DOITYPE SITUATIONTYPE +%type CERTTYPE CERT_X509 CERT_PLAINRSA PROPOSAL_CHECK_LEVEL REMOTE_FORCE_LEVEL GENERATE_LEVEL +%type unittype_time unittype_byte +%type QUOTEDSTRING HEXSTRING ADDRSTRING ADDRRANGE sainfo_id +%type identifierstring +%type remote_index ike_addrinfo_port +%type algorithm + +%% + +statements + : /* nothing */ + | statements statement + ; +statement + : privsep_statement + | path_statement + | include_statement + | pfkey_statement + | gssenc_statement + | logging_statement + | padding_statement + | listen_statement + | ldapcfg_statement + | radcfg_statement + | modecfg_statement + | timer_statement + | sainfo_statement + | remote_statement + | special_statement + ; + + /* privsep */ +privsep_statement + : PRIVSEP BOC privsep_stmts EOC + ; +privsep_stmts + : /* nothing */ + | privsep_stmts privsep_stmt + ; +privsep_stmt + : USER QUOTEDSTRING + { + struct passwd *pw; + + if ((pw = getpwnam($2->v)) == NULL) { + yyerror("unknown user \"%s\"", $2->v); + return -1; + } + lcconf->uid = pw->pw_uid; + } + EOS + | USER NUMBER { lcconf->uid = $2; } EOS + | GROUP QUOTEDSTRING + { + struct group *gr; + + if ((gr = getgrnam($2->v)) == NULL) { + yyerror("unknown group \"%s\"", $2->v); + return -1; + } + lcconf->gid = gr->gr_gid; + } + EOS + | GROUP NUMBER { lcconf->gid = $2; } EOS + | CHROOT QUOTEDSTRING { lcconf->chroot = $2->v; } EOS + ; + + /* path */ +path_statement + : PATH PATHTYPE QUOTEDSTRING + { + if ($2 >= LC_PATHTYPE_MAX) { + yyerror("invalid path type %d", $2); + return -1; + } + + /* free old pathinfo */ + if (lcconf->pathinfo[$2]) + racoon_free(lcconf->pathinfo[$2]); + + /* set new pathinfo */ + lcconf->pathinfo[$2] = racoon_strdup($3->v); + STRDUP_FATAL(lcconf->pathinfo[$2]); + vfree($3); + } + EOS + ; + + /* special */ +special_statement + : COMPLEX_BUNDLE SWITCH { lcconf->complex_bundle = $2; } EOS + ; + + /* include */ +include_statement + : INCLUDE QUOTEDSTRING EOS + { + char path[MAXPATHLEN]; + + getpathname(path, sizeof(path), + LC_PATHTYPE_INCLUDE, $2->v); + vfree($2); + if (yycf_switch_buffer(path) != 0) + return -1; + } + ; + + /* pfkey_buffer */ +pfkey_statement + : PFKEY_BUFFER NUMBER EOS + { + lcconf->pfkey_buffer_size = $2; + } + ; + /* gss_id_enc */ +gssenc_statement + : GSS_ID_ENC GSS_ID_ENCTYPE EOS + { + if ($2 >= LC_GSSENC_MAX) { + yyerror("invalid GSS ID encoding %d", $2); + return -1; + } + lcconf->gss_id_enc = $2; + } + ; + + /* logging */ +logging_statement + : LOGGING log_level EOS + ; +log_level + : LOGLEV + { + /* + * set the loglevel to the value specified + * in the configuration file plus the number + * of -d options specified on the command line + */ + loglevel += $1 - oldloglevel; + oldloglevel = $1; + } + ; + + /* padding */ +padding_statement + : PADDING BOC padding_stmts EOC + ; +padding_stmts + : /* nothing */ + | padding_stmts padding_stmt + ; +padding_stmt + : PAD_RANDOMIZE SWITCH { lcconf->pad_random = $2; } EOS + | PAD_RANDOMIZELEN SWITCH { lcconf->pad_randomlen = $2; } EOS + | PAD_MAXLEN NUMBER { lcconf->pad_maxsize = $2; } EOS + | PAD_STRICT SWITCH { lcconf->pad_strict = $2; } EOS + | PAD_EXCLTAIL SWITCH { lcconf->pad_excltail = $2; } EOS + ; + + /* listen */ +listen_statement + : LISTEN BOC listen_stmts EOC + ; +listen_stmts + : /* nothing */ + | listen_stmts listen_stmt + ; +listen_stmt + : X_ISAKMP ike_addrinfo_port + { + myaddr_listen($2, FALSE); + racoon_free($2); + } + EOS + | X_ISAKMP_NATT ike_addrinfo_port + { +#ifdef ENABLE_NATT + myaddr_listen($2, TRUE); + racoon_free($2); +#else + racoon_free($2); + yyerror("NAT-T support not compiled in."); +#endif + } + EOS + | ADMINSOCK QUOTEDSTRING QUOTEDSTRING QUOTEDSTRING NUMBER + { +#ifdef ENABLE_ADMINPORT + adminsock_conf($2, $3, $4, $5); +#else + yywarn("admin port support not compiled in"); +#endif + } + EOS + | ADMINSOCK QUOTEDSTRING + { +#ifdef ENABLE_ADMINPORT + adminsock_conf($2, NULL, NULL, -1); +#else + yywarn("admin port support not compiled in"); +#endif + } + EOS + | ADMINSOCK DISABLED + { +#ifdef ENABLE_ADMINPORT + adminsock_path = NULL; +#else + yywarn("admin port support not compiled in"); +#endif + } + EOS + | STRICT_ADDRESS { lcconf->strict_address = TRUE; } EOS + ; +ike_addrinfo_port + : ADDRSTRING ike_port + { + char portbuf[10]; + + snprintf(portbuf, sizeof(portbuf), "%ld", $2); + $$ = str2saddr($1->v, portbuf); + vfree($1); + if (!$$) + return -1; + } + ; +ike_port + : /* nothing */ { $$ = PORT_ISAKMP; } + | PORT { $$ = $1; } + ; + + /* radius configuration */ +radcfg_statement + : RADCFG { +#ifndef ENABLE_HYBRID + yyerror("racoon not configured with --enable-hybrid"); + return -1; +#endif +#ifndef HAVE_LIBRADIUS + yyerror("racoon not configured with --with-libradius"); + return -1; +#endif +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + xauth_rad_config.timeout = 3; + xauth_rad_config.retries = 3; +#endif +#endif + } BOC radcfg_stmts EOC + ; +radcfg_stmts + : /* nothing */ + | radcfg_stmts radcfg_stmt + ; +radcfg_stmt + : RAD_AUTH QUOTEDSTRING QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + int i = xauth_rad_config.auth_server_count; + if (i == RADIUS_MAX_SERVERS) { + yyerror("maximum radius auth servers exceeded"); + return -1; + } + + xauth_rad_config.auth_server_list[i].host = vdup($2); + xauth_rad_config.auth_server_list[i].secret = vdup($3); + xauth_rad_config.auth_server_list[i].port = 0; // default port + xauth_rad_config.auth_server_count++; +#endif +#endif + } + EOS + | RAD_AUTH QUOTEDSTRING NUMBER QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + int i = xauth_rad_config.auth_server_count; + if (i == RADIUS_MAX_SERVERS) { + yyerror("maximum radius auth servers exceeded"); + return -1; + } + + xauth_rad_config.auth_server_list[i].host = vdup($2); + xauth_rad_config.auth_server_list[i].secret = vdup($4); + xauth_rad_config.auth_server_list[i].port = $3; + xauth_rad_config.auth_server_count++; +#endif +#endif + } + EOS + | RAD_ACCT QUOTEDSTRING QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + int i = xauth_rad_config.acct_server_count; + if (i == RADIUS_MAX_SERVERS) { + yyerror("maximum radius account servers exceeded"); + return -1; + } + + xauth_rad_config.acct_server_list[i].host = vdup($2); + xauth_rad_config.acct_server_list[i].secret = vdup($3); + xauth_rad_config.acct_server_list[i].port = 0; // default port + xauth_rad_config.acct_server_count++; +#endif +#endif + } + EOS + | RAD_ACCT QUOTEDSTRING NUMBER QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + int i = xauth_rad_config.acct_server_count; + if (i == RADIUS_MAX_SERVERS) { + yyerror("maximum radius account servers exceeded"); + return -1; + } + + xauth_rad_config.acct_server_list[i].host = vdup($2); + xauth_rad_config.acct_server_list[i].secret = vdup($4); + xauth_rad_config.acct_server_list[i].port = $3; + xauth_rad_config.acct_server_count++; +#endif +#endif + } + EOS + | RAD_TIMEOUT NUMBER + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + xauth_rad_config.timeout = $2; +#endif +#endif + } + EOS + | RAD_RETRIES NUMBER + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + xauth_rad_config.retries = $2; +#endif +#endif + } + EOS + ; + + /* ldap configuration */ +ldapcfg_statement + : LDAPCFG { +#ifndef ENABLE_HYBRID + yyerror("racoon not configured with --enable-hybrid"); + return -1; +#endif +#ifndef HAVE_LIBLDAP + yyerror("racoon not configured with --with-libldap"); + return -1; +#endif + } BOC ldapcfg_stmts EOC + ; +ldapcfg_stmts + : /* nothing */ + | ldapcfg_stmts ldapcfg_stmt + ; +ldapcfg_stmt + : LDAP_PVER NUMBER + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (($2<2)||($2>3)) + yyerror("invalid ldap protocol version (2|3)"); + xauth_ldap_config.pver = $2; +#endif +#endif + } + EOS + | LDAP_HOST QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.host != NULL) + vfree(xauth_ldap_config.host); + xauth_ldap_config.host = vdup($2); +#endif +#endif + } + EOS + | LDAP_PORT NUMBER + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + xauth_ldap_config.port = $2; +#endif +#endif + } + EOS + | LDAP_BASE QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.base != NULL) + vfree(xauth_ldap_config.base); + xauth_ldap_config.base = vdup($2); +#endif +#endif + } + EOS + | LDAP_SUBTREE SWITCH + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + xauth_ldap_config.subtree = $2; +#endif +#endif + } + EOS + | LDAP_BIND_DN QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.bind_dn != NULL) + vfree(xauth_ldap_config.bind_dn); + xauth_ldap_config.bind_dn = vdup($2); +#endif +#endif + } + EOS + | LDAP_BIND_PW QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.bind_pw != NULL) + vfree(xauth_ldap_config.bind_pw); + xauth_ldap_config.bind_pw = vdup($2); +#endif +#endif + } + EOS + | LDAP_ATTR_USER QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.attr_user != NULL) + vfree(xauth_ldap_config.attr_user); + xauth_ldap_config.attr_user = vdup($2); +#endif +#endif + } + EOS + | LDAP_ATTR_ADDR QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.attr_addr != NULL) + vfree(xauth_ldap_config.attr_addr); + xauth_ldap_config.attr_addr = vdup($2); +#endif +#endif + } + EOS + | LDAP_ATTR_MASK QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.attr_mask != NULL) + vfree(xauth_ldap_config.attr_mask); + xauth_ldap_config.attr_mask = vdup($2); +#endif +#endif + } + EOS + | LDAP_ATTR_GROUP QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.attr_group != NULL) + vfree(xauth_ldap_config.attr_group); + xauth_ldap_config.attr_group = vdup($2); +#endif +#endif + } + EOS + | LDAP_ATTR_MEMBER QUOTEDSTRING + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + if (xauth_ldap_config.attr_member != NULL) + vfree(xauth_ldap_config.attr_member); + xauth_ldap_config.attr_member = vdup($2); +#endif +#endif + } + EOS + ; + + /* modecfg */ +modecfg_statement + : MODECFG BOC modecfg_stmts EOC + ; +modecfg_stmts + : /* nothing */ + | modecfg_stmts modecfg_stmt + ; +modecfg_stmt + : CFG_NET4 ADDRSTRING + { +#ifdef ENABLE_HYBRID + if (inet_pton(AF_INET, $2->v, + &isakmp_cfg_config.network4) != 1) + yyerror("bad IPv4 network address."); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_MASK4 ADDRSTRING + { +#ifdef ENABLE_HYBRID + if (inet_pton(AF_INET, $2->v, + &isakmp_cfg_config.netmask4) != 1) + yyerror("bad IPv4 netmask address."); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_DNS4 addrdnslist + EOS + | CFG_NBNS4 addrwinslist + EOS + | CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL splitnetlist + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.splitnet_type = UNITY_LOCAL_LAN; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_SPLIT_NETWORK CFG_SPLIT_INCLUDE splitnetlist + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.splitnet_type = UNITY_SPLIT_INCLUDE; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_SPLIT_DNS splitdnslist + { +#ifndef ENABLE_HYBRID + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_DEFAULT_DOMAIN QUOTEDSTRING + { +#ifdef ENABLE_HYBRID + strncpy(&isakmp_cfg_config.default_domain[0], + $2->v, MAXPATHLEN); + isakmp_cfg_config.default_domain[MAXPATHLEN] = '\0'; + vfree($2); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_AUTH_SOURCE CFG_SYSTEM + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_AUTH_SOURCE CFG_RADIUS + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_RADIUS; +#else /* HAVE_LIBRADIUS */ + yyerror("racoon not configured with --with-libradius"); +#endif /* HAVE_LIBRADIUS */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_AUTH_SOURCE CFG_PAM + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBPAM + isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_PAM; +#else /* HAVE_LIBPAM */ + yyerror("racoon not configured with --with-libpam"); +#endif /* HAVE_LIBPAM */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_AUTH_SOURCE CFG_LDAP + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_LDAP; +#else /* HAVE_LIBLDAP */ + yyerror("racoon not configured with --with-libldap"); +#endif /* HAVE_LIBLDAP */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_AUTH_GROUPS authgrouplist + { +#ifndef ENABLE_HYBRID + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_GROUP_SOURCE CFG_SYSTEM + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_GROUP_SOURCE CFG_LDAP + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_LDAP; +#else /* HAVE_LIBLDAP */ + yyerror("racoon not configured with --with-libldap"); +#endif /* HAVE_LIBLDAP */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_ACCOUNTING CFG_NONE + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_ACCOUNTING CFG_SYSTEM + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_SYSTEM; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_ACCOUNTING CFG_RADIUS + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_RADIUS; +#else /* HAVE_LIBRADIUS */ + yyerror("racoon not configured with --with-libradius"); +#endif /* HAVE_LIBRADIUS */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_ACCOUNTING CFG_PAM + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBPAM + isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_PAM; +#else /* HAVE_LIBPAM */ + yyerror("racoon not configured with --with-libpam"); +#endif /* HAVE_LIBPAM */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_POOL_SIZE NUMBER + { +#ifdef ENABLE_HYBRID + if (isakmp_cfg_resize_pool($2) != 0) + yyerror("cannot allocate memory for pool"); +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_PFS_GROUP NUMBER + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.pfs_group = $2; +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_SAVE_PASSWD SWITCH + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.save_passwd = $2; +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_AUTH_THROTTLE NUMBER + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.auth_throttle = $2; +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_CONF_SOURCE CFG_LOCAL + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL; +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_CONF_SOURCE CFG_RADIUS + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBRADIUS + isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_RADIUS; +#else /* HAVE_LIBRADIUS */ + yyerror("racoon not configured with --with-libradius"); +#endif /* HAVE_LIBRADIUS */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_CONF_SOURCE CFG_LDAP + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LDAP; +#else /* HAVE_LIBLDAP */ + yyerror("racoon not configured with --with-libldap"); +#endif /* HAVE_LIBLDAP */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_MOTD QUOTEDSTRING + { +#ifdef ENABLE_HYBRID + strncpy(&isakmp_cfg_config.motd[0], $2->v, MAXPATHLEN); + isakmp_cfg_config.motd[MAXPATHLEN] = '\0'; + vfree($2); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + ; + +addrdnslist + : addrdns + | addrdns COMMA addrdnslist + ; +addrdns + : ADDRSTRING + { +#ifdef ENABLE_HYBRID + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + + if (icc->dns4_index > MAXNS) + yyerror("No more than %d DNS", MAXNS); + if (inet_pton(AF_INET, $1->v, + &icc->dns4[icc->dns4_index++]) != 1) + yyerror("bad IPv4 DNS address."); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + ; + +addrwinslist + : addrwins + | addrwins COMMA addrwinslist + ; +addrwins + : ADDRSTRING + { +#ifdef ENABLE_HYBRID + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + + if (icc->nbns4_index > MAXWINS) + yyerror("No more than %d WINS", MAXWINS); + if (inet_pton(AF_INET, $1->v, + &icc->nbns4[icc->nbns4_index++]) != 1) + yyerror("bad IPv4 WINS address."); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + ; + +splitnetlist + : splitnet + | splitnetlist COMMA splitnet + ; +splitnet + : ADDRSTRING PREFIX + { +#ifdef ENABLE_HYBRID + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + struct unity_network network; + memset(&network,0,sizeof(network)); + + if (inet_pton(AF_INET, $1->v, &network.addr4) != 1) + yyerror("bad IPv4 SPLIT address."); + + /* Turn $2 (the prefix) into a subnet mask */ + network.mask4.s_addr = ($2) ? htonl(~((1 << (32 - $2)) - 1)) : 0; + + /* add the network to our list */ + if (splitnet_list_add(&icc->splitnet_list, &network,&icc->splitnet_count)) + yyerror("Unable to allocate split network"); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + ; + +authgrouplist + : authgroup + | authgroup COMMA authgrouplist + ; +authgroup + : QUOTEDSTRING + { +#ifdef ENABLE_HYBRID + char * groupname = NULL; + char ** grouplist = NULL; + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + + grouplist = racoon_realloc(icc->grouplist, + sizeof(char**)*(icc->groupcount+1)); + if (grouplist == NULL) { + yyerror("unable to allocate auth group list"); + return -1; + } + + groupname = racoon_malloc($1->l+1); + if (groupname == NULL) { + yyerror("unable to allocate auth group name"); + return -1; + } + + memcpy(groupname,$1->v,$1->l); + groupname[$1->l]=0; + grouplist[icc->groupcount]=groupname; + icc->grouplist = grouplist; + icc->groupcount++; + + vfree($1); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + ; + +splitdnslist + : splitdns + | splitdns COMMA splitdnslist + ; +splitdns + : QUOTEDSTRING + { +#ifdef ENABLE_HYBRID + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + + if (!icc->splitdns_len) + { + icc->splitdns_list = racoon_malloc($1->l); + if(icc->splitdns_list == NULL) { + yyerror("error allocating splitdns list buffer"); + return -1; + } + memcpy(icc->splitdns_list,$1->v,$1->l); + icc->splitdns_len = $1->l; + } + else + { + int len = icc->splitdns_len + $1->l + 1; + icc->splitdns_list = racoon_realloc(icc->splitdns_list,len); + if(icc->splitdns_list == NULL) { + yyerror("error allocating splitdns list buffer"); + return -1; + } + icc->splitdns_list[icc->splitdns_len] = ','; + memcpy(icc->splitdns_list + icc->splitdns_len + 1, $1->v, $1->l); + icc->splitdns_len = len; + } + vfree($1); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + ; + + + /* timer */ +timer_statement + : RETRY BOC timer_stmts EOC + ; +timer_stmts + : /* nothing */ + | timer_stmts timer_stmt + ; +timer_stmt + : RETRY_COUNTER NUMBER + { + lcconf->retry_counter = $2; + } + EOS + | RETRY_INTERVAL NUMBER unittype_time + { + lcconf->retry_interval = $2 * $3; + } + EOS + | RETRY_PERSEND NUMBER + { + lcconf->count_persend = $2; + } + EOS + | RETRY_PHASE1 NUMBER unittype_time + { + lcconf->retry_checkph1 = $2 * $3; + } + EOS + | RETRY_PHASE2 NUMBER unittype_time + { + lcconf->wait_ph2complete = $2 * $3; + } + EOS + | NATT_KA NUMBER unittype_time + { +#ifdef ENABLE_NATT + if (libipsec_opt & LIBIPSEC_OPT_NATT) + lcconf->natt_ka_interval = $2 * $3; + else + yyerror("libipsec lacks NAT-T support"); +#else + yyerror("NAT-T support not compiled in."); +#endif + } + EOS + ; + + /* sainfo */ +sainfo_statement + : SAINFO + { + cur_sainfo = newsainfo(); + if (cur_sainfo == NULL) { + yyerror("failed to allocate sainfo"); + return -1; + } + } + sainfo_name sainfo_param BOC sainfo_specs + { + struct sainfo *check; + + /* default */ + if (cur_sainfo->algs[algclass_ipsec_enc] == 0) { + yyerror("no encryption algorithm at %s", + sainfo2str(cur_sainfo)); + return -1; + } + if (cur_sainfo->algs[algclass_ipsec_auth] == 0) { + yyerror("no authentication algorithm at %s", + sainfo2str(cur_sainfo)); + return -1; + } + if (cur_sainfo->algs[algclass_ipsec_comp] == 0) { + yyerror("no compression algorithm at %s", + sainfo2str(cur_sainfo)); + return -1; + } + + /* duplicate check */ + check = getsainfo(cur_sainfo->idsrc, + cur_sainfo->iddst, + cur_sainfo->id_i, + NULL, + cur_sainfo->remoteid); + + if (check && ((check->idsrc != SAINFO_ANONYMOUS) && + (cur_sainfo->idsrc != SAINFO_ANONYMOUS))) { + yyerror("duplicated sainfo: %s", + sainfo2str(cur_sainfo)); + return -1; + } + + inssainfo(cur_sainfo); + } + EOC + ; +sainfo_name + : ANONYMOUS + { + cur_sainfo->idsrc = SAINFO_ANONYMOUS; + cur_sainfo->iddst = SAINFO_ANONYMOUS; + } + | ANONYMOUS CLIENTADDR + { + cur_sainfo->idsrc = SAINFO_ANONYMOUS; + cur_sainfo->iddst = SAINFO_CLIENTADDR; + } + | ANONYMOUS sainfo_id + { + cur_sainfo->idsrc = SAINFO_ANONYMOUS; + cur_sainfo->iddst = $2; + } + | sainfo_id ANONYMOUS + { + cur_sainfo->idsrc = $1; + cur_sainfo->iddst = SAINFO_ANONYMOUS; + } + | sainfo_id CLIENTADDR + { + cur_sainfo->idsrc = $1; + cur_sainfo->iddst = SAINFO_CLIENTADDR; + } + | sainfo_id sainfo_id + { + cur_sainfo->idsrc = $1; + cur_sainfo->iddst = $2; + } + ; +sainfo_id + : IDENTIFIERTYPE ADDRSTRING prefix port ul_proto + { + char portbuf[10]; + struct sockaddr *saddr; + + if (($5 == IPPROTO_ICMP || $5 == IPPROTO_ICMPV6) + && ($4 != IPSEC_PORT_ANY || $4 != IPSEC_PORT_ANY)) { + yyerror("port number must be \"any\"."); + return -1; + } + + snprintf(portbuf, sizeof(portbuf), "%lu", $4); + saddr = str2saddr($2->v, portbuf); + vfree($2); + if (saddr == NULL) + return -1; + + switch (saddr->sa_family) { + case AF_INET: + if ($5 == IPPROTO_ICMPV6) { + yyerror("upper layer protocol mismatched.\n"); + racoon_free(saddr); + return -1; + } + $$ = ipsecdoi_sockaddr2id(saddr, + $3 == ~0 ? (sizeof(struct in_addr) << 3): $3, + $5); + break; +#ifdef INET6 + case AF_INET6: + if ($5 == IPPROTO_ICMP) { + yyerror("upper layer protocol mismatched.\n"); + racoon_free(saddr); + return -1; + } + $$ = ipsecdoi_sockaddr2id(saddr, + $3 == ~0 ? (sizeof(struct in6_addr) << 3): $3, + $5); + break; +#endif + default: + yyerror("invalid family: %d", saddr->sa_family); + $$ = NULL; + break; + } + racoon_free(saddr); + if ($$ == NULL) + return -1; + } + | IDENTIFIERTYPE ADDRSTRING ADDRRANGE prefix port ul_proto + { + char portbuf[10]; + struct sockaddr *laddr = NULL, *haddr = NULL; + char *cur = NULL; + + if (($6 == IPPROTO_ICMP || $6 == IPPROTO_ICMPV6) + && ($5 != IPSEC_PORT_ANY || $5 != IPSEC_PORT_ANY)) { + yyerror("port number must be \"any\"."); + return -1; + } + + snprintf(portbuf, sizeof(portbuf), "%lu", $5); + + laddr = str2saddr($2->v, portbuf); + if (laddr == NULL) { + return -1; + } + vfree($2); + haddr = str2saddr($3->v, portbuf); + if (haddr == NULL) { + racoon_free(laddr); + return -1; + } + vfree($3); + + switch (laddr->sa_family) { + case AF_INET: + if ($6 == IPPROTO_ICMPV6) { + yyerror("upper layer protocol mismatched.\n"); + if (laddr) + racoon_free(laddr); + if (haddr) + racoon_free(haddr); + return -1; + } + $$ = ipsecdoi_sockrange2id(laddr, haddr, + $6); + break; +#ifdef INET6 + case AF_INET6: + if ($6 == IPPROTO_ICMP) { + yyerror("upper layer protocol mismatched.\n"); + if (laddr) + racoon_free(laddr); + if (haddr) + racoon_free(haddr); + return -1; + } + $$ = ipsecdoi_sockrange2id(laddr, haddr, + $6); + break; +#endif + default: + yyerror("invalid family: %d", laddr->sa_family); + $$ = NULL; + break; + } + if (laddr) + racoon_free(laddr); + if (haddr) + racoon_free(haddr); + if ($$ == NULL) + return -1; + } + | IDENTIFIERTYPE QUOTEDSTRING + { + struct ipsecdoi_id_b *id_b; + + if ($1 == IDTYPE_ASN1DN) { + yyerror("id type forbidden: %d", $1); + $$ = NULL; + return -1; + } + + $2->l--; + + $$ = vmalloc(sizeof(*id_b) + $2->l); + if ($$ == NULL) { + yyerror("failed to allocate identifier"); + return -1; + } + + id_b = (struct ipsecdoi_id_b *)$$->v; + id_b->type = idtype2doi($1); + + id_b->proto_id = 0; + id_b->port = 0; + + memcpy($$->v + sizeof(*id_b), $2->v, $2->l); + } + ; +sainfo_param + : /* nothing */ + { + cur_sainfo->id_i = NULL; + } + | FROM IDENTIFIERTYPE identifierstring + { + struct ipsecdoi_id_b *id_b; + vchar_t *idv; + + if (set_identifier(&idv, $2, $3) != 0) { + yyerror("failed to set identifer.\n"); + return -1; + } + cur_sainfo->id_i = vmalloc(sizeof(*id_b) + idv->l); + if (cur_sainfo->id_i == NULL) { + yyerror("failed to allocate identifier"); + return -1; + } + + id_b = (struct ipsecdoi_id_b *)cur_sainfo->id_i->v; + id_b->type = idtype2doi($2); + + id_b->proto_id = 0; + id_b->port = 0; + + memcpy(cur_sainfo->id_i->v + sizeof(*id_b), + idv->v, idv->l); + vfree(idv); + } + | GROUP QUOTEDSTRING + { +#ifdef ENABLE_HYBRID + if ((cur_sainfo->group = vdup($2)) == NULL) { + yyerror("failed to set sainfo xauth group.\n"); + return -1; + } +#else + yyerror("racoon not configured with --enable-hybrid"); + return -1; +#endif + } + ; +sainfo_specs + : /* nothing */ + | sainfo_specs sainfo_spec + ; +sainfo_spec + : PFS_GROUP dh_group_num + { + cur_sainfo->pfs_group = $2; + } + EOS + | REMOTEID NUMBER + { + cur_sainfo->remoteid = $2; + } + EOS + | LIFETIME LIFETYPE_TIME NUMBER unittype_time + { + cur_sainfo->lifetime = $3 * $4; + } + EOS + | LIFETIME LIFETYPE_BYTE NUMBER unittype_byte + { +#if 1 + yyerror("byte lifetime support is deprecated"); + return -1; +#else + cur_sainfo->lifebyte = fix_lifebyte($3 * $4); + if (cur_sainfo->lifebyte == 0) + return -1; +#endif + } + EOS + | ALGORITHM_CLASS { + cur_algclass = $1; + } + algorithms EOS + ; + +algorithms + : algorithm + { + inssainfoalg(&cur_sainfo->algs[cur_algclass], $1); + } + | algorithm + { + inssainfoalg(&cur_sainfo->algs[cur_algclass], $1); + } + COMMA algorithms + ; +algorithm + : ALGORITHMTYPE keylength + { + int defklen; + + $$ = newsainfoalg(); + if ($$ == NULL) { + yyerror("failed to get algorithm allocation"); + return -1; + } + + $$->alg = algtype2doi(cur_algclass, $1); + if ($$->alg == -1) { + yyerror("algorithm mismatched"); + racoon_free($$); + $$ = NULL; + return -1; + } + + defklen = default_keylen(cur_algclass, $1); + if (defklen == 0) { + if ($2) { + yyerror("keylen not allowed"); + racoon_free($$); + $$ = NULL; + return -1; + } + } else { + if ($2 && check_keylen(cur_algclass, $1, $2) < 0) { + yyerror("invalid keylen %d", $2); + racoon_free($$); + $$ = NULL; + return -1; + } + } + + if ($2) + $$->encklen = $2; + else + $$->encklen = defklen; + + /* check if it's supported algorithm by kernel */ + if (!(cur_algclass == algclass_ipsec_auth && $1 == algtype_non_auth) + && pk_checkalg(cur_algclass, $1, $$->encklen)) { + int a = algclass2doi(cur_algclass); + int b = algtype2doi(cur_algclass, $1); + if (a == IPSECDOI_ATTR_AUTH) + a = IPSECDOI_PROTO_IPSEC_AH; + yyerror("algorithm %s not supported by the kernel (missing module?)", + s_ipsecdoi_trns(a, b)); + racoon_free($$); + $$ = NULL; + return -1; + } + } + ; +prefix + : /* nothing */ { $$ = ~0; } + | PREFIX { $$ = $1; } + ; +port + : /* nothing */ { $$ = IPSEC_PORT_ANY; } + | PORT { $$ = $1; } + | PORTANY { $$ = IPSEC_PORT_ANY; } + ; +ul_proto + : NUMBER { $$ = $1; } + | UL_PROTO { $$ = $1; } + | ANY { $$ = IPSEC_ULPROTO_ANY; } + ; +keylength + : /* nothing */ { $$ = 0; } + | NUMBER { $$ = $1; } + ; + + /* remote */ +remote_statement + : REMOTE QUOTEDSTRING INHERIT QUOTEDSTRING + { + struct remoteconf *from, *new; + + if (getrmconf_by_name($2->v) != NULL) { + yyerror("named remoteconf \"%s\" already exists."); + return -1; + } + + from = getrmconf_by_name($4->v); + if (from == NULL) { + yyerror("named parent remoteconf \"%s\" does not exist.", + $4->v); + return -1; + } + + new = duprmconf_shallow(from); + if (new == NULL) { + yyerror("failed to duplicate remoteconf from \"%s\".", + $4->v); + return -1; + } + + new->name = racoon_strdup($2->v); + cur_rmconf = new; + + vfree($2); + vfree($4); + } + remote_specs_inherit_block + | REMOTE QUOTEDSTRING + { + struct remoteconf *new; + + if (getrmconf_by_name($2->v) != NULL) { + yyerror("Named remoteconf \"%s\" already exists."); + return -1; + } + + new = newrmconf(); + if (new == NULL) { + yyerror("failed to get new remoteconf."); + return -1; + } + new->name = racoon_strdup($2->v); + cur_rmconf = new; + + vfree($2); + } + remote_specs_block + | REMOTE remote_index INHERIT remote_index + { + struct remoteconf *from, *new; + + from = getrmconf($4, GETRMCONF_F_NO_ANONYMOUS); + if (from == NULL) { + yyerror("failed to get remoteconf for %s.", + saddr2str($4)); + return -1; + } + + new = duprmconf_shallow(from); + if (new == NULL) { + yyerror("failed to duplicate remoteconf from %s.", + saddr2str($4)); + return -1; + } + + racoon_free($4); + new->remote = $2; + cur_rmconf = new; + } + remote_specs_inherit_block + | REMOTE remote_index + { + struct remoteconf *new; + + new = newrmconf(); + if (new == NULL) { + yyerror("failed to get new remoteconf."); + return -1; + } + + new->remote = $2; + cur_rmconf = new; + } + remote_specs_block + ; + +remote_specs_inherit_block + : remote_specs_block + | EOS /* inheritance without overriding any settings */ + { + if (process_rmconf() != 0) + return -1; + } + ; + +remote_specs_block + : BOC remote_specs EOC + { + if (process_rmconf() != 0) + return -1; + } + ; +remote_index + : ANONYMOUS ike_port + { + $$ = newsaddr(sizeof(struct sockaddr)); + $$->sa_family = AF_UNSPEC; + ((struct sockaddr_in *)$$)->sin_port = htons($2); + } + | ike_addrinfo_port + { + $$ = $1; + if ($$ == NULL) { + yyerror("failed to allocate sockaddr"); + return -1; + } + } + ; +remote_specs + : /* nothing */ + | remote_specs remote_spec + ; +remote_spec + : REMOTE_ADDRESS ike_addrinfo_port + { + if (cur_rmconf->remote != NULL) { + yyerror("remote_address already specified"); + return -1; + } + cur_rmconf->remote = $2; + } + EOS + | EXCHANGE_MODE + { + cur_rmconf->etypes = NULL; + } + exchange_types EOS + | DOI DOITYPE { cur_rmconf->doitype = $2; } EOS + | SITUATION SITUATIONTYPE { cur_rmconf->sittype = $2; } EOS + | CERTIFICATE_TYPE cert_spec + | PEERS_CERTFILE QUOTEDSTRING + { + yywarn("This directive without certtype will be removed!\n"); + yywarn("Please use 'peers_certfile x509 \"%s\";' instead\n", $2->v); + + if (cur_rmconf->peerscert != NULL) { + yyerror("peers_certfile already defined\n"); + return -1; + } + + if (load_x509($2->v, &cur_rmconf->peerscertfile, + &cur_rmconf->peerscert)) { + yyerror("failed to load certificate \"%s\"\n", + $2->v); + return -1; + } + + vfree($2); + } + EOS + | PEERS_CERTFILE CERT_X509 QUOTEDSTRING + { + if (cur_rmconf->peerscert != NULL) { + yyerror("peers_certfile already defined\n"); + return -1; + } + + if (load_x509($3->v, &cur_rmconf->peerscertfile, + &cur_rmconf->peerscert)) { + yyerror("failed to load certificate \"%s\"\n", + $3->v); + return -1; + } + + vfree($3); + } + EOS + | PEERS_CERTFILE CERT_PLAINRSA QUOTEDSTRING + { + char path[MAXPATHLEN]; + int ret = 0; + + if (cur_rmconf->peerscert != NULL) { + yyerror("peers_certfile already defined\n"); + return -1; + } + + cur_rmconf->peerscert = vmalloc(1); + if (cur_rmconf->peerscert == NULL) { + yyerror("failed to allocate peerscert"); + return -1; + } + cur_rmconf->peerscert->v[0] = ISAKMP_CERT_PLAINRSA; + + getpathname(path, sizeof(path), + LC_PATHTYPE_CERT, $3->v); + if (rsa_parse_file(cur_rmconf->rsa_public, path, + RSA_TYPE_PUBLIC)) { + yyerror("Couldn't parse keyfile.\n", path); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, + "Public PlainRSA keyfile parsed: %s\n", path); + + vfree($3); + } + EOS + | PEERS_CERTFILE DNSSEC + { + if (cur_rmconf->peerscert != NULL) { + yyerror("peers_certfile already defined\n"); + return -1; + } + cur_rmconf->peerscert = vmalloc(1); + if (cur_rmconf->peerscert == NULL) { + yyerror("failed to allocate peerscert"); + return -1; + } + cur_rmconf->peerscert->v[0] = ISAKMP_CERT_DNS; + } + EOS + | CA_TYPE CERT_X509 QUOTEDSTRING + { + if (cur_rmconf->cacert != NULL) { + yyerror("ca_type already defined\n"); + return -1; + } + + if (load_x509($3->v, &cur_rmconf->cacertfile, + &cur_rmconf->cacert)) { + yyerror("failed to load certificate \"%s\"\n", + $3->v); + return -1; + } + + vfree($3); + } + EOS + | VERIFY_CERT SWITCH { cur_rmconf->verify_cert = $2; } EOS + | SEND_CERT SWITCH { cur_rmconf->send_cert = $2; } EOS + | SEND_CR SWITCH { cur_rmconf->send_cr = $2; } EOS + | MATCH_EMPTY_CR SWITCH { cur_rmconf->match_empty_cr = $2; } EOS + | MY_IDENTIFIER IDENTIFIERTYPE identifierstring + { + if (set_identifier(&cur_rmconf->idv, $2, $3) != 0) { + yyerror("failed to set identifer.\n"); + return -1; + } + cur_rmconf->idvtype = $2; + } + EOS + | MY_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring + { + if (set_identifier_qual(&cur_rmconf->idv, $2, $4, $3) != 0) { + yyerror("failed to set identifer.\n"); + return -1; + } + cur_rmconf->idvtype = $2; + } + EOS + | XAUTH_LOGIN identifierstring + { +#ifdef ENABLE_HYBRID + /* formerly identifier type login */ + if (xauth_rmconf_used(&cur_rmconf->xauth) == -1) { + yyerror("failed to allocate xauth state\n"); + return -1; + } + if ((cur_rmconf->xauth->login = vdup($2)) == NULL) { + yyerror("failed to set identifer.\n"); + return -1; + } +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | PEERS_IDENTIFIER IDENTIFIERTYPE identifierstring + { + struct idspec *id; + id = newidspec(); + if (id == NULL) { + yyerror("failed to allocate idspec"); + return -1; + } + if (set_identifier(&id->id, $2, $3) != 0) { + yyerror("failed to set identifer.\n"); + racoon_free(id); + return -1; + } + id->idtype = $2; + genlist_append (cur_rmconf->idvl_p, id); + } + EOS + | PEERS_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring + { + struct idspec *id; + id = newidspec(); + if (id == NULL) { + yyerror("failed to allocate idspec"); + return -1; + } + if (set_identifier_qual(&id->id, $2, $4, $3) != 0) { + yyerror("failed to set identifer.\n"); + racoon_free(id); + return -1; + } + id->idtype = $2; + genlist_append (cur_rmconf->idvl_p, id); + } + EOS + | VERIFY_IDENTIFIER SWITCH { cur_rmconf->verify_identifier = $2; } EOS + | NONCE_SIZE NUMBER { cur_rmconf->nonce_size = $2; } EOS + | DH_GROUP + { + yyerror("dh_group cannot be defined here."); + return -1; + } + dh_group_num EOS + | PASSIVE SWITCH { cur_rmconf->passive = $2; } EOS + | IKE_FRAG SWITCH { cur_rmconf->ike_frag = $2; } EOS + | IKE_FRAG REMOTE_FORCE_LEVEL { cur_rmconf->ike_frag = ISAKMP_FRAG_FORCE; } EOS + | ESP_FRAG NUMBER { +#ifdef SADB_X_EXT_NAT_T_FRAG + if (libipsec_opt & LIBIPSEC_OPT_FRAG) + cur_rmconf->esp_frag = $2; + else + yywarn("libipsec lacks IKE frag support"); +#else + yywarn("Your kernel does not support esp_frag"); +#endif + } EOS + | SCRIPT QUOTEDSTRING PHASE1_UP { + if (cur_rmconf->script[SCRIPT_PHASE1_UP] != NULL) + vfree(cur_rmconf->script[SCRIPT_PHASE1_UP]); + + cur_rmconf->script[SCRIPT_PHASE1_UP] = + script_path_add(vdup($2)); + } EOS + | SCRIPT QUOTEDSTRING PHASE1_DOWN { + if (cur_rmconf->script[SCRIPT_PHASE1_DOWN] != NULL) + vfree(cur_rmconf->script[SCRIPT_PHASE1_DOWN]); + + cur_rmconf->script[SCRIPT_PHASE1_DOWN] = + script_path_add(vdup($2)); + } EOS + | SCRIPT QUOTEDSTRING PHASE1_DEAD { + if (cur_rmconf->script[SCRIPT_PHASE1_DEAD] != NULL) + vfree(cur_rmconf->script[SCRIPT_PHASE1_DEAD]); + + cur_rmconf->script[SCRIPT_PHASE1_DEAD] = + script_path_add(vdup($2)); + } EOS + | MODE_CFG SWITCH { cur_rmconf->mode_cfg = $2; } EOS + | WEAK_PHASE1_CHECK SWITCH { + cur_rmconf->weak_phase1_check = $2; + } EOS + | GENERATE_POLICY SWITCH { cur_rmconf->gen_policy = $2; } EOS + | GENERATE_POLICY GENERATE_LEVEL { cur_rmconf->gen_policy = $2; } EOS + | SUPPORT_PROXY SWITCH { cur_rmconf->support_proxy = $2; } EOS + | INITIAL_CONTACT SWITCH { cur_rmconf->ini_contact = $2; } EOS + | NAT_TRAVERSAL SWITCH + { +#ifdef ENABLE_NATT + if (libipsec_opt & LIBIPSEC_OPT_NATT) + cur_rmconf->nat_traversal = $2; + else + yyerror("libipsec lacks NAT-T support"); +#else + yyerror("NAT-T support not compiled in."); +#endif + } EOS + | NAT_TRAVERSAL REMOTE_FORCE_LEVEL + { +#ifdef ENABLE_NATT + if (libipsec_opt & LIBIPSEC_OPT_NATT) + cur_rmconf->nat_traversal = NATT_FORCE; + else + yyerror("libipsec lacks NAT-T support"); +#else + yyerror("NAT-T support not compiled in."); +#endif + } EOS + | DPD SWITCH + { +#ifdef ENABLE_DPD + cur_rmconf->dpd = $2; +#else + yyerror("DPD support not compiled in."); +#endif + } EOS + | DPD_DELAY NUMBER + { +#ifdef ENABLE_DPD + cur_rmconf->dpd_interval = $2; +#else + yyerror("DPD support not compiled in."); +#endif + } + EOS + | DPD_RETRY NUMBER + { +#ifdef ENABLE_DPD + cur_rmconf->dpd_retry = $2; +#else + yyerror("DPD support not compiled in."); +#endif + } + EOS + | DPD_MAXFAIL NUMBER + { +#ifdef ENABLE_DPD + cur_rmconf->dpd_maxfails = $2; +#else + yyerror("DPD support not compiled in."); +#endif + } + EOS + | REKEY SWITCH { cur_rmconf->rekey = $2; } EOS + | REKEY REMOTE_FORCE_LEVEL { cur_rmconf->rekey = REKEY_FORCE; } EOS + | PH1ID NUMBER + { + cur_rmconf->ph1id = $2; + } + EOS + | LIFETIME LIFETYPE_TIME NUMBER unittype_time + { + cur_rmconf->lifetime = $3 * $4; + } + EOS + | PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL { cur_rmconf->pcheck_level = $2; } EOS + | LIFETIME LIFETYPE_BYTE NUMBER unittype_byte + { +#if 1 + yyerror("byte lifetime support is deprecated in Phase1"); + return -1; +#else + yywarn("the lifetime of bytes in phase 1 " + "will be ignored at the moment."); + cur_rmconf->lifebyte = fix_lifebyte($3 * $4); + if (cur_rmconf->lifebyte == 0) + return -1; +#endif + } + EOS + | PROPOSAL + { + struct secprotospec *spspec; + + spspec = newspspec(); + if (spspec == NULL) + return -1; + insspspec(cur_rmconf, spspec); + } + BOC isakmpproposal_specs EOC + ; +exchange_types + : /* nothing */ + | exchange_types EXCHANGETYPE + { + struct etypes *new; + new = racoon_malloc(sizeof(struct etypes)); + if (new == NULL) { + yyerror("failed to allocate etypes"); + return -1; + } + new->type = $2; + new->next = NULL; + if (cur_rmconf->etypes == NULL) + cur_rmconf->etypes = new; + else { + struct etypes *p; + for (p = cur_rmconf->etypes; + p->next != NULL; + p = p->next) + ; + p->next = new; + } + } + ; +cert_spec + : CERT_X509 QUOTEDSTRING QUOTEDSTRING + { + if (cur_rmconf->mycert != NULL) { + yyerror("certificate_type already defined\n"); + return -1; + } + + if (load_x509($2->v, &cur_rmconf->mycertfile, + &cur_rmconf->mycert)) { + yyerror("failed to load certificate \"%s\"\n", + $2->v); + return -1; + } + + cur_rmconf->myprivfile = racoon_strdup($3->v); + STRDUP_FATAL(cur_rmconf->myprivfile); + + vfree($2); + vfree($3); + } + EOS + | CERT_PLAINRSA QUOTEDSTRING + { + char path[MAXPATHLEN]; + int ret = 0; + + if (cur_rmconf->mycert != NULL) { + yyerror("certificate_type already defined\n"); + return -1; + } + + cur_rmconf->mycert = vmalloc(1); + if (cur_rmconf->mycert == NULL) { + yyerror("failed to allocate mycert"); + return -1; + } + cur_rmconf->mycert->v[0] = ISAKMP_CERT_PLAINRSA; + + getpathname(path, sizeof(path), + LC_PATHTYPE_CERT, $2->v); + cur_rmconf->send_cr = FALSE; + cur_rmconf->send_cert = FALSE; + cur_rmconf->verify_cert = FALSE; + if (rsa_parse_file(cur_rmconf->rsa_private, path, + RSA_TYPE_PRIVATE)) { + yyerror("Couldn't parse keyfile.\n", path); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, + "Private PlainRSA keyfile parsed: %s\n", path); + vfree($2); + } + EOS + ; +dh_group_num + : ALGORITHMTYPE + { + $$ = algtype2doi(algclass_isakmp_dh, $1); + if ($$ == -1) { + yyerror("must be DH group"); + return -1; + } + } + | NUMBER + { + if (ARRAYLEN(num2dhgroup) > $1 && num2dhgroup[$1] != 0) { + $$ = num2dhgroup[$1]; + } else { + yyerror("must be DH group"); + $$ = 0; + return -1; + } + } + ; +identifierstring + : /* nothing */ { $$ = NULL; } + | ADDRSTRING { $$ = $1; } + | QUOTEDSTRING { $$ = $1; } + ; +isakmpproposal_specs + : /* nothing */ + | isakmpproposal_specs isakmpproposal_spec + ; +isakmpproposal_spec + : LIFETIME LIFETYPE_TIME NUMBER unittype_time + { + cur_rmconf->spspec->lifetime = $3 * $4; + } + EOS + | LIFETIME LIFETYPE_BYTE NUMBER unittype_byte + { +#if 1 + yyerror("byte lifetime support is deprecated"); + return -1; +#else + cur_rmconf->spspec->lifebyte = fix_lifebyte($3 * $4); + if (cur_rmconf->spspec->lifebyte == 0) + return -1; +#endif + } + EOS + | DH_GROUP dh_group_num + { + cur_rmconf->spspec->algclass[algclass_isakmp_dh] = $2; + } + EOS + | GSS_ID QUOTEDSTRING + { + if (cur_rmconf->spspec->vendorid != VENDORID_GSSAPI) { + yyerror("wrong Vendor ID for gssapi_id"); + return -1; + } + if (cur_rmconf->spspec->gssid != NULL) + racoon_free(cur_rmconf->spspec->gssid); + cur_rmconf->spspec->gssid = + racoon_strdup($2->v); + STRDUP_FATAL(cur_rmconf->spspec->gssid); + } + EOS + | ALGORITHM_CLASS ALGORITHMTYPE keylength + { + int doi; + int defklen; + + doi = algtype2doi($1, $2); + if (doi == -1) { + yyerror("algorithm mismatched 1"); + return -1; + } + + switch ($1) { + case algclass_isakmp_enc: + /* reject suppressed algorithms */ +#ifndef HAVE_OPENSSL_RC5_H + if ($2 == algtype_rc5) { + yyerror("algorithm %s not supported", + s_attr_isakmp_enc(doi)); + return -1; + } +#endif +#ifndef HAVE_OPENSSL_IDEA_H + if ($2 == algtype_idea) { + yyerror("algorithm %s not supported", + s_attr_isakmp_enc(doi)); + return -1; + } +#endif + + cur_rmconf->spspec->algclass[algclass_isakmp_enc] = doi; + defklen = default_keylen($1, $2); + if (defklen == 0) { + if ($3) { + yyerror("keylen not allowed"); + return -1; + } + } else { + if ($3 && check_keylen($1, $2, $3) < 0) { + yyerror("invalid keylen %d", $3); + return -1; + } + } + if ($3) + cur_rmconf->spspec->encklen = $3; + else + cur_rmconf->spspec->encklen = defklen; + break; + case algclass_isakmp_hash: + cur_rmconf->spspec->algclass[algclass_isakmp_hash] = doi; + break; + case algclass_isakmp_ameth: + cur_rmconf->spspec->algclass[algclass_isakmp_ameth] = doi; + /* + * We may have to set the Vendor ID for the + * authentication method we're using. + */ + switch ($2) { + case algtype_gssapikrb: + if (cur_rmconf->spspec->vendorid != + VENDORID_UNKNOWN) { + yyerror("Vendor ID mismatch " + "for auth method"); + return -1; + } + /* + * For interoperability with Win2k, + * we set the Vendor ID to "GSSAPI". + */ + cur_rmconf->spspec->vendorid = + VENDORID_GSSAPI; + break; + case algtype_rsasig: + if (oakley_get_certtype(cur_rmconf->peerscert) == ISAKMP_CERT_PLAINRSA) { + if (rsa_list_count(cur_rmconf->rsa_private) == 0) { + yyerror ("Private PlainRSA key not set. " + "Use directive 'certificate_type plainrsa ...'\n"); + return -1; + } + if (rsa_list_count(cur_rmconf->rsa_public) == 0) { + yyerror ("Public PlainRSA keys not set. " + "Use directive 'peers_certfile plainrsa ...'\n"); + return -1; + } + } + break; + default: + break; + } + break; + default: + yyerror("algorithm mismatched 2"); + return -1; + } + } + EOS + ; + +unittype_time + : UNITTYPE_SEC { $$ = 1; } + | UNITTYPE_MIN { $$ = 60; } + | UNITTYPE_HOUR { $$ = (60 * 60); } + ; +unittype_byte + : UNITTYPE_BYTE { $$ = 1; } + | UNITTYPE_KBYTES { $$ = 1024; } + | UNITTYPE_MBYTES { $$ = (1024 * 1024); } + | UNITTYPE_TBYTES { $$ = (1024 * 1024 * 1024); } + ; +%% + +static struct secprotospec * +newspspec() +{ + struct secprotospec *new; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) { + yyerror("failed to allocate spproto"); + return NULL; + } + + new->encklen = 0; /*XXX*/ + + /* + * Default to "uknown" vendor -- we will override this + * as necessary. When we send a Vendor ID payload, an + * "unknown" will be translated to a KAME/racoon ID. + */ + new->vendorid = VENDORID_UNKNOWN; + + return new; +} + +/* + * insert into head of list. + */ +static void +insspspec(rmconf, spspec) + struct remoteconf *rmconf; + struct secprotospec *spspec; +{ + if (rmconf->spspec != NULL) + rmconf->spspec->prev = spspec; + spspec->next = rmconf->spspec; + rmconf->spspec = spspec; +} + +static struct secprotospec * +dupspspec(spspec) + struct secprotospec *spspec; +{ + struct secprotospec *new; + + new = newspspec(); + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "dupspspec: malloc failed\n"); + return NULL; + } + memcpy(new, spspec, sizeof(*new)); + + if (spspec->gssid) { + new->gssid = racoon_strdup(spspec->gssid); + STRDUP_FATAL(new->gssid); + } + if (spspec->remote) { + new->remote = racoon_malloc(sizeof(*new->remote)); + if (new->remote == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "dupspspec: malloc failed (remote)\n"); + return NULL; + } + memcpy(new->remote, spspec->remote, sizeof(*new->remote)); + } + + return new; +} + +/* + * copy the whole list + */ +void +dupspspec_list(dst, src) + struct remoteconf *dst, *src; +{ + struct secprotospec *p, *new, *last; + + for(p = src->spspec, last = NULL; p; p = p->next, last = new) { + new = dupspspec(p); + if (new == NULL) + exit(1); + + new->prev = last; + new->next = NULL; /* not necessary but clean */ + + if (last) + last->next = new; + else /* first element */ + dst->spspec = new; + + } +} + +/* + * delete the whole list + */ +void +flushspspec(rmconf) + struct remoteconf *rmconf; +{ + struct secprotospec *p; + + while(rmconf->spspec != NULL) { + p = rmconf->spspec; + rmconf->spspec = p->next; + if (p->next != NULL) + p->next->prev = NULL; /* not necessary but clean */ + + if (p->gssid) + racoon_free(p->gssid); + if (p->remote) + racoon_free(p->remote); + racoon_free(p); + } + rmconf->spspec = NULL; +} + +/* set final acceptable proposal */ +static int +set_isakmp_proposal(rmconf) + struct remoteconf *rmconf; +{ + struct secprotospec *s; + int prop_no = 1; + int trns_no = 1; + int32_t types[MAXALGCLASS]; + + /* mandatory check */ + if (rmconf->spspec == NULL) { + yyerror("no remote specification found: %s.\n", + saddr2str(rmconf->remote)); + return -1; + } + for (s = rmconf->spspec; s != NULL; s = s->next) { + /* XXX need more to check */ + if (s->algclass[algclass_isakmp_enc] == 0) { + yyerror("encryption algorithm required."); + return -1; + } + if (s->algclass[algclass_isakmp_hash] == 0) { + yyerror("hash algorithm required."); + return -1; + } + if (s->algclass[algclass_isakmp_dh] == 0) { + yyerror("DH group required."); + return -1; + } + if (s->algclass[algclass_isakmp_ameth] == 0) { + yyerror("authentication method required."); + return -1; + } + } + + /* skip to last part */ + for (s = rmconf->spspec; s->next != NULL; s = s->next) + ; + + while (s != NULL) { + plog(LLV_DEBUG2, LOCATION, NULL, + "lifetime = %ld\n", (long) + (s->lifetime ? s->lifetime : rmconf->lifetime)); + plog(LLV_DEBUG2, LOCATION, NULL, + "lifebyte = %d\n", + s->lifebyte ? s->lifebyte : rmconf->lifebyte); + plog(LLV_DEBUG2, LOCATION, NULL, + "encklen=%d\n", s->encklen); + + memset(types, 0, ARRAYLEN(types)); + types[algclass_isakmp_enc] = s->algclass[algclass_isakmp_enc]; + types[algclass_isakmp_hash] = s->algclass[algclass_isakmp_hash]; + types[algclass_isakmp_dh] = s->algclass[algclass_isakmp_dh]; + types[algclass_isakmp_ameth] = + s->algclass[algclass_isakmp_ameth]; + + /* expanding spspec */ + clean_tmpalgtype(); + trns_no = expand_isakmpspec(prop_no, trns_no, types, + algclass_isakmp_enc, algclass_isakmp_ameth + 1, + s->lifetime ? s->lifetime : rmconf->lifetime, + s->lifebyte ? s->lifebyte : rmconf->lifebyte, + s->encklen, s->vendorid, s->gssid, + rmconf); + if (trns_no == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to expand isakmp proposal.\n"); + return -1; + } + + s = s->prev; + } + + if (rmconf->proposal == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no proposal found.\n"); + return -1; + } + + return 0; +} + +static void +clean_tmpalgtype() +{ + int i; + for (i = 0; i < MAXALGCLASS; i++) + tmpalgtype[i] = 0; /* means algorithm undefined. */ +} + +static int +expand_isakmpspec(prop_no, trns_no, types, + class, last, lifetime, lifebyte, encklen, vendorid, gssid, + rmconf) + int prop_no, trns_no; + int *types, class, last; + time_t lifetime; + int lifebyte; + int encklen; + int vendorid; + char *gssid; + struct remoteconf *rmconf; +{ + struct isakmpsa *new; + + /* debugging */ + { + int j; + char tb[10]; + plog(LLV_DEBUG2, LOCATION, NULL, + "p:%d t:%d\n", prop_no, trns_no); + for (j = class; j < MAXALGCLASS; j++) { + snprintf(tb, sizeof(tb), "%d", types[j]); + plog(LLV_DEBUG2, LOCATION, NULL, + "%s%s%s%s\n", + s_algtype(j, types[j]), + types[j] ? "(" : "", + tb[0] == '0' ? "" : tb, + types[j] ? ")" : ""); + } + plog(LLV_DEBUG2, LOCATION, NULL, "\n"); + } + +#define TMPALGTYPE2STR(n) \ + s_algtype(algclass_isakmp_##n, types[algclass_isakmp_##n]) + /* check mandatory values */ + if (types[algclass_isakmp_enc] == 0 + || types[algclass_isakmp_ameth] == 0 + || types[algclass_isakmp_hash] == 0 + || types[algclass_isakmp_dh] == 0) { + yyerror("few definition of algorithm " + "enc=%s ameth=%s hash=%s dhgroup=%s.\n", + TMPALGTYPE2STR(enc), + TMPALGTYPE2STR(ameth), + TMPALGTYPE2STR(hash), + TMPALGTYPE2STR(dh)); + return -1; + } +#undef TMPALGTYPE2STR + + /* set new sa */ + new = newisakmpsa(); + if (new == NULL) { + yyerror("failed to allocate isakmp sa"); + return -1; + } + new->prop_no = prop_no; + new->trns_no = trns_no++; + new->lifetime = lifetime; + new->lifebyte = lifebyte; + new->enctype = types[algclass_isakmp_enc]; + new->encklen = encklen; + new->authmethod = types[algclass_isakmp_ameth]; + new->hashtype = types[algclass_isakmp_hash]; + new->dh_group = types[algclass_isakmp_dh]; + new->vendorid = vendorid; +#ifdef HAVE_GSSAPI + if (new->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { + if (gssid != NULL) { + if ((new->gssid = vmalloc(strlen(gssid))) == NULL) { + racoon_free(new); + yyerror("failed to allocate gssid"); + return -1; + } + memcpy(new->gssid->v, gssid, new->gssid->l); + racoon_free(gssid); + } else { + /* + * Allocate the default ID so that it gets put + * into a GSS ID attribute during the Phase 1 + * exchange. + */ + new->gssid = gssapi_get_default_gss_id(); + } + } +#endif + insisakmpsa(new, rmconf); + + return trns_no; +} + +#if 0 +/* + * fix lifebyte. + * Must be more than 1024B because its unit is kilobytes. + * That is defined RFC2407. + */ +static int +fix_lifebyte(t) + unsigned long t; +{ + if (t < 1024) { + yyerror("byte size should be more than 1024B."); + return 0; + } + + return(t / 1024); +} +#endif + +int +cfparse() +{ + int error; + + yyerrorcount = 0; + yycf_init_buffer(); + + if (yycf_switch_buffer(lcconf->racoon_conf) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "could not read configuration file \"%s\"\n", + lcconf->racoon_conf); + return -1; + } + + error = yyparse(); + if (error != 0) { + if (yyerrorcount) { + plog(LLV_ERROR, LOCATION, NULL, + "fatal parse failure (%d errors)\n", + yyerrorcount); + } else { + plog(LLV_ERROR, LOCATION, NULL, + "fatal parse failure.\n"); + } + return -1; + } + + if (error == 0 && yyerrorcount) { + plog(LLV_ERROR, LOCATION, NULL, + "parse error is nothing, but yyerrorcount is %d.\n", + yyerrorcount); + exit(1); + } + + yycf_clean_buffer(); + + plog(LLV_DEBUG2, LOCATION, NULL, "parse successed.\n"); + + return 0; +} + +int +cfreparse() +{ + flushph2(); + flushph1(); + flushrmconf(); + flushsainfo(); + clean_tmpalgtype(); + return(cfparse()); +} + +#ifdef ENABLE_ADMINPORT +static void +adminsock_conf(path, owner, group, mode_dec) + vchar_t *path; + vchar_t *owner; + vchar_t *group; + int mode_dec; +{ + struct passwd *pw = NULL; + struct group *gr = NULL; + mode_t mode = 0; + uid_t uid; + gid_t gid; + int isnum; + + adminsock_path = path->v; + + if (owner == NULL) + return; + + errno = 0; + uid = atoi(owner->v); + isnum = !errno; + if (((pw = getpwnam(owner->v)) == NULL) && !isnum) + yyerror("User \"%s\" does not exist", owner->v); + + if (pw) + adminsock_owner = pw->pw_uid; + else + adminsock_owner = uid; + + if (group == NULL) + return; + + errno = 0; + gid = atoi(group->v); + isnum = !errno; + if (((gr = getgrnam(group->v)) == NULL) && !isnum) + yyerror("Group \"%s\" does not exist", group->v); + + if (gr) + adminsock_group = gr->gr_gid; + else + adminsock_group = gid; + + if (mode_dec == -1) + return; + + if (mode_dec > 777) + yyerror("Mode 0%03o is invalid", mode_dec); + if (mode_dec >= 400) { mode += 0400; mode_dec -= 400; } + if (mode_dec >= 200) { mode += 0200; mode_dec -= 200; } + if (mode_dec >= 100) { mode += 0200; mode_dec -= 100; } + + if (mode_dec > 77) + yyerror("Mode 0%03o is invalid", mode_dec); + if (mode_dec >= 40) { mode += 040; mode_dec -= 40; } + if (mode_dec >= 20) { mode += 020; mode_dec -= 20; } + if (mode_dec >= 10) { mode += 020; mode_dec -= 10; } + + if (mode_dec > 7) + yyerror("Mode 0%03o is invalid", mode_dec); + if (mode_dec >= 4) { mode += 04; mode_dec -= 4; } + if (mode_dec >= 2) { mode += 02; mode_dec -= 2; } + if (mode_dec >= 1) { mode += 02; mode_dec -= 1; } + + adminsock_mode = mode; + + return; +} +#endif diff --git a/ipsec-tools/src/racoon/cfparse_proto.h b/ipsec-tools/src/racoon/cfparse_proto.h new file mode 100644 index 00000000..139520c6 --- /dev/null +++ b/ipsec-tools/src/racoon/cfparse_proto.h @@ -0,0 +1,42 @@ +/* $NetBSD: cfparse_proto.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: cfparse_proto.h,v 1.3 2004/06/11 16:00:15 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _CFPARSE_PROTO_H +#define _CFPARSE_PROTO_H + +/* cfparse.y */ +extern int yyparse __P((void)); +extern int cfparse __P((void)); +extern int cfreparse __P((void)); + +#endif /* _CFPARSE_PROTO_H */ diff --git a/ipsec-tools/src/racoon/cftoken.c b/ipsec-tools/src/racoon/cftoken.c new file mode 100644 index 00000000..7b9bb14f --- /dev/null +++ b/ipsec-tools/src/racoon/cftoken.c @@ -0,0 +1,4836 @@ + +#line 3 "cftoken.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 37 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +typedef unsigned char YY_CHAR; + +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + (yytext_ptr) -= (yy_more_len); \ + yyleng = (size_t) (yy_cp - (yytext_ptr)); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 307 +#define YY_END_OF_BUFFER 308 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[1820] = + { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 308, 306, 302, 303, 306, 304, 306, 306, 298, 298, + 298, 301, 305, 289, 306, 306, 306, 306, 301, 301, + 301, 301, 301, 301, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 301, + 306, 306, 306, 306, 306, 306, 306, 306, 301, 306, + 306, 2, 6, 14, 301, 301, 306, 306, 306, 25, + + 301, 301, 306, 306, 306, 301, 306, 306, 306, 27, + 33, 301, 301, 306, 306, 35, 42, 301, 306, 306, + 306, 96, 103, 93, 301, 301, 301, 301, 306, 306, + 306, 306, 306, 306, 306, 306, 66, 94, 301, 301, + 306, 306, 306, 306, 51, 64, 301, 306, 306, 44, + 49, 112, 306, 301, 301, 301, 306, 111, 123, 301, + 301, 301, 301, 306, 306, 306, 306, 306, 113, 127, + 301, 306, 128, 132, 301, 301, 301, 301, 301, 301, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 129, 301, 301, 301, 301, + + 306, 306, 306, 306, 190, 191, 204, 306, 306, 302, + 0, 300, 304, 209, 207, 301, 301, 298, 0, 301, + 0, 290, 291, 292, 0, 301, 301, 211, 0, 0, + 0, 301, 301, 0, 301, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 297, 0, 0, 205, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 301, + 301, 0, 0, 0, 0, 301, 0, 0, 297, 0, + + 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, + 0, 0, 0, 301, 0, 301, 0, 301, 0, 0, + 0, 0, 0, 0, 0, 297, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 301, 0, 0, 0, 0, + 0, 301, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 301, 0, 301, 301, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 297, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 209, 209, 207, 301, 299, 301, + 0, 208, 301, 230, 0, 0, 0, 0, 0, 301, + 219, 0, 301, 210, 0, 0, 217, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 256, 245, 294, 0, + 0, 0, 206, 254, 0, 227, 221, 0, 0, 293, + 0, 0, 287, 215, 0, 0, 216, 0, 0, 296, + 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 301, 0, + 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 301, 0, 0, 0, 301, 0, 0, 0, + 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 301, 0, 0, 0, 0, 0, 108, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, + 175, 210, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 293, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 209, 207, 220, 0, 0, 0, 0, 289, 0, + 0, 0, 0, 0, 0, 288, 282, 0, 0, 295, + 0, 213, 222, 0, 0, 244, 294, 0, 0, 0, + 229, 0, 0, 0, 0, 0, 0, 293, 246, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 301, 69, 0, 0, 83, 0, 0, 0, + 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 53, 54, 0, 0, 46, 45, 0, 0, + 0, 0, 0, 109, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 118, 0, 0, 0, 133, 174, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 134, 0, 0, + 0, 0, 0, 166, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, + + 0, 0, 0, 148, 0, 0, 194, 0, 0, 0, + 0, 0, 0, 193, 0, 0, 225, 0, 0, 0, + 289, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 295, 0, 214, 0, 283, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 95, 0, 4, 0, 0, 0, 0, 0, + 0, 23, 19, 0, 0, 0, 0, 0, 0, 38, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 79, 70, 0, 0, 0, + 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, + 0, 0, 107, 0, 0, 110, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 169, 0, + 0, 0, 0, 0, 0, 168, 0, 164, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 179, 0, 0, 0, 188, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 286, 0, 0, 0, 0, 0, 0, 269, 0, 0, + + 0, 0, 0, 0, 212, 294, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 270, 271, + 268, 293, 249, 0, 0, 0, 251, 253, 285, 0, + 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, + 0, 0, 124, 104, 5, 0, 0, 0, 0, 0, + 11, 24, 21, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 0, 0, 100, 101, 0, 0, + 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 81, 0, 0, 78, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 151, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 182, 0, 0, + 0, 167, 0, 159, 0, 0, 0, 0, 0, 0, + 199, 0, 0, 0, 202, 0, 284, 0, 0, 223, + 255, 0, 0, 243, 260, 261, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 257, 0, 0, 0, + 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, + 0, 15, 50, 0, 26, 0, 1, 0, 0, 0, + + 8, 13, 0, 20, 0, 0, 0, 0, 0, 0, + 0, 0, 97, 0, 0, 99, 0, 0, 0, 0, + 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 57, 58, 56, + 52, 48, 47, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 126, 0, 147, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, + 0, 0, 0, 160, 140, 0, 154, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, + + 233, 226, 218, 0, 235, 0, 0, 0, 258, 259, + 262, 263, 264, 265, 266, 234, 228, 0, 231, 248, + 250, 252, 0, 0, 0, 0, 0, 65, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, 40, 0, + 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 68, 67, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 117, 0, + 0, 115, 0, 0, 0, 156, 0, 0, 0, 181, + 0, 0, 0, 180, 0, 0, 0, 0, 172, 0, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 189, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 0, 0, 0, 192, 203, 0, 236, 0, 0, 0, + 0, 0, 0, 281, 0, 0, 0, 0, 0, 43, + 0, 0, 0, 0, 28, 0, 39, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 88, 91, 84, + 0, 90, 0, 60, 0, 61, 0, 59, 105, 0, + 0, 0, 0, 0, 114, 125, 0, 0, 176, 0, + 177, 0, 0, 0, 0, 141, 137, 170, 0, 0, + 0, 0, 0, 0, 0, 0, 183, 149, 0, 0, + 153, 138, 0, 0, 0, 0, 0, 0, 0, 200, + + 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, + 0, 0, 62, 0, 106, 0, 0, 0, 0, 135, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 238, 0, 0, 0, 240, 242, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 37, 0, 0, 74, 73, + 0, 76, 0, 0, 92, 0, 63, 0, 0, 0, + + 0, 0, 178, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 185, 184, 0, 0, 0, 152, 0, 0, + 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 0, 31, 0, 0, 0, 0, 75, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 239, 241, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 0, 87, 0, 0, 0, 116, 0, 131, 0, + + 139, 0, 0, 142, 163, 0, 0, 0, 0, 161, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 267, + 0, 0, 0, 0, 17, 9, 32, 30, 0, 41, + 102, 72, 0, 0, 0, 0, 0, 0, 155, 150, + 0, 165, 130, 0, 0, 0, 0, 197, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 158, 162, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 278, 277, 280, 279, 29, 0, 0, 0, + 146, 144, 0, 0, 0, 0, 276, 274, 275, 273, + 0, 0, 0, 145, 187, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, + 0, 195, 0, 122, 196, 0, 0, 121, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 4, 5, 1, 6, 1, 1, 1, + 1, 1, 1, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 1, + 1, 1, 1, 1, 23, 24, 23, 23, 23, 23, + 25, 25, 25, 25, 26, 25, 27, 25, 25, 25, + 25, 25, 25, 28, 25, 25, 25, 25, 25, 25, + 29, 1, 30, 1, 31, 1, 32, 33, 34, 35, + + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 1, 59, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[60] = + { 0, + 1, 1, 2, 1, 1, 3, 1, 1, 3, 1, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 1, 6, 6, 7, 7, 7, 7, 1, 1, + 1, 6, 6, 6, 6, 6, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[1832] = + { 0, + 0, 0, 26, 44, 27, 58, 68, 87, 90, 106, + 103, 114, 134, 136, 98, 143, 196, 0, 165, 167, + 48, 189, 0, 0, 0, 0, 227, 238, 290, 343, + 82, 91, 396, 0, 424, 452, 0, 0, 46, 81, + 2198, 2199, 2195, 2199, 2192, 0, 0, 0, 506, 2140, + 130, 2188, 2199, 2187, 2168, 2167, 2166, 0, 172, 153, + 68, 169, 229, 204, 13, 135, 120, 36, 2132, 222, + 59, 221, 2139, 237, 242, 248, 192, 2155, 2150, 263, + 183, 256, 258, 265, 276, 278, 299, 252, 313, 267, + 239, 2199, 2199, 2199, 314, 323, 309, 140, 326, 2199, + + 330, 324, 337, 275, 2153, 355, 353, 364, 361, 2199, + 2199, 2149, 375, 372, 422, 2199, 2199, 363, 419, 440, + 388, 2199, 2199, 2199, 349, 438, 470, 463, 298, 462, + 307, 498, 500, 513, 519, 2143, 2199, 2199, 2131, 522, + 433, 167, 462, 2145, 2199, 2199, 374, 533, 536, 2199, + 2199, 2199, 2148, 2134, 542, 546, 318, 2199, 2199, 2126, + 550, 566, 554, 79, 557, 386, 571, 547, 2199, 2199, + 2132, 575, 2199, 2199, 2138, 568, 583, 596, 610, 585, + 578, 603, 457, 577, 617, 607, 625, 632, 638, 646, + 655, 616, 2139, 2138, 221, 2199, 2121, 648, 663, 673, + + 367, 664, 583, 660, 2199, 2199, 2199, 275, 655, 2170, + 2167, 2199, 0, 2164, 0, 0, 2163, 2113, 0, 385, + 2132, 2199, 2199, 2199, 2136, 465, 527, 2199, 2120, 2118, + 2112, 677, 678, 2112, 551, 2114, 2117, 2124, 2122, 2107, + 2124, 2103, 2121, 2109, 2116, 2117, 2094, 2114, 2098, 2131, + 2101, 2110, 2099, 2100, 2105, 2199, 2101, 2104, 490, 2098, + 2106, 2103, 2104, 2102, 2096, 2086, 2094, 2085, 2083, 2093, + 2076, 2077, 2082, 2075, 2090, 2091, 2072, 2083, 2085, 248, + 2077, 31, 2083, 2073, 2076, 592, 2066, 432, 2078, 446, + 670, 2079, 2077, 2075, 2061, 697, 2060, 2071, 666, 2058, + + 2072, 2050, 2059, 2054, 612, 2052, 2069, 2051, 2047, 2047, + 2046, 2047, 2063, 695, 2043, 142, 2048, 687, 2042, 676, + 2057, 2058, 2055, 2043, 2036, 2041, 2041, 2034, 2037, 2047, + 2028, 2037, 2029, 2033, 2026, 530, 2031, 368, 2026, 2041, + 2024, 710, 2021, 2020, 687, 2025, 680, 2029, 2022, 696, + 2016, 2015, 2021, 2030, 2026, 2031, 2011, 2016, 695, 2013, + 2019, 2019, 729, 2005, 732, 734, 2023, 2023, 2003, 2012, + 2016, 2003, 550, 2000, 2003, 2011, 2010, 701, 709, 709, + 2008, 706, 2009, 2012, 1991, 1996, 2004, 1989, 2002, 736, + 2005, 714, 707, 1987, 719, 1984, 1985, 723, 723, 1993, + + 1983, 1999, 2019, 1977, 1977, 1976, 1995, 1991, 1974, 1973, + 1985, 728, 1970, 1983, 0, 2013, 0, 0, 0, 748, + 1982, 2199, 752, 2199, 2005, 1962, 1979, 1978, 1962, 553, + 1981, 1961, 763, 2199, 1974, 1964, 2199, 1976, 1973, 1957, + 1956, 1957, 1971, 1956, 1961, 1958, 2199, 2199, 721, 1952, + 1967, 1954, 2199, 2199, 1965, 2199, 2199, 1950, 738, 731, + 777, 1949, 2199, 2199, 1957, 1955, 2199, 1942, 1939, 2199, + 1942, 753, 1945, 1940, 1935, 2199, 739, 1950, 1945, 1947, + 1929, 1941, 1934, 1934, 1942, 1931, 1924, 1926, 772, 1923, + 1930, 1935, 1940, 1930, 774, 1923, 1922, 1927, 1921, 1922, + + 1924, 1928, 1922, 1921, 1928, 1917, 1918, 1912, 1920, 1904, + 1904, 1903, 756, 1913, 1906, 1913, 786, 1934, 1896, 1904, + 1899, 1913, 1894, 750, 764, 2199, 1912, 1899, 1901, 1904, + 1899, 1887, 1887, 1887, 1899, 1899, 1882, 1881, 752, 1881, + 790, 1891, 1880, 1892, 1871, 1881, 2199, 1889, 1880, 1871, + 1883, 1885, 1873, 1870, 1882, 1877, 1885, 1869, 1878, 1868, + 1876, 1862, 1874, 1873, 1857, 1856, 1866, 1867, 1854, 2199, + 1872, 1871, 1867, 1861, 1865, 1862, 767, 1866, 1845, 1859, + 1858, 1846, 1856, 1846, 1856, 769, 1849, 1857, 775, 1831, + 1836, 1836, 1844, 1833, 1842, 1834, 1844, 1833, 1826, 1837, + + 761, 1841, 1823, 1834, 1826, 1836, 1823, 1830, 1827, 1848, + 1816, 1827, 1829, 1826, 1814, 788, 1823, 1825, 1824, 1819, + 1850, 0, 2199, 2199, 1825, 1820, 1820, 1817, 1803, 1809, + 1839, 1818, 773, 1809, 1836, 2199, 2199, 1800, 1815, 1795, + 1804, 1826, 2199, 1798, 1806, 2199, 2199, 1789, 818, 1807, + 1807, 1787, 1801, 1790, 1798, 1793, 1787, 2199, 2199, 807, + 1812, 1818, 1793, 1779, 1787, 1795, 1786, 1781, 1783, 1770, + 1787, 1784, 1788, 1778, 2199, 1761, 1766, 1763, 1763, 1776, + 1763, 1765, 1763, 1778, 1756, 1767, 1754, 1765, 1754, 1756, + 1764, 1752, 2199, 1763, 1759, 1746, 1753, 1750, 1761, 1749, + + 1760, 1748, 1757, 1739, 1740, 1757, 1751, 1750, 1733, 1753, + 1747, 1751, 809, 2199, 1734, 1728, 2199, 1736, 1763, 1745, + 1730, 2199, 1737, 1743, 1721, 1741, 1720, 1734, 1754, 1737, + 2199, 1736, 2199, 2199, 1717, 1725, 2199, 2199, 1724, 1717, + 1732, 1705, 1715, 2199, 1712, 1722, 1707, 1707, 1699, 1703, + 1718, 1714, 1700, 2199, 1694, 1700, 1712, 2199, 1697, 1690, + 1705, 1700, 1694, 1706, 790, 1704, 1689, 1707, 1702, 1688, + 1685, 1698, 1694, 1695, 1698, 1699, 1679, 2199, 1690, 1697, + 1692, 1675, 1689, 2199, 1684, 1673, 1687, 1685, 1675, 1673, + 1662, 1666, 1676, 1668, 1678, 1682, 1680, 1677, 1664, 2199, + + 1657, 1671, 1676, 2199, 1667, 1669, 1654, 1654, 1646, 1659, + 1649, 50, 78, 2199, 137, 239, 2199, 290, 318, 425, + 2199, 492, 616, 604, 614, 789, 784, 808, 788, 796, + 2199, 807, 2199, 796, 2199, 808, 834, 836, 837, 838, + 839, 835, 841, 802, 819, 817, 825, 824, 806, 822, + 827, 846, 851, 851, 855, 818, 2199, 820, 834, 841, + 837, 839, 840, 839, 832, 844, 834, 849, 845, 832, + 847, 838, 2199, 834, 2199, 839, 850, 853, 846, 851, + 840, 879, 2199, 837, 849, 845, 844, 853, 847, 849, + 857, 854, 851, 867, 851, 863, 861, 895, 864, 872, + + 862, 862, 870, 883, 880, 885, 2199, 867, 869, 870, + 870, 871, 877, 894, 882, 2199, 895, 893, 893, 884, + 895, 880, 2199, 890, 884, 2199, 891, 901, 891, 901, + 906, 894, 908, 901, 906, 898, 902, 913, 2199, 905, + 918, 917, 922, 919, 907, 2199, 912, 2199, 926, 919, + 911, 929, 913, 932, 921, 925, 935, 933, 932, 920, + 939, 918, 941, 2199, 961, 943, 925, 2199, 940, 928, + 927, 945, 946, 930, 931, 934, 948, 929, 939, 956, + 943, 943, 943, 956, 952, 961, 954, 983, 979, 947, + 2199, 948, 959, 981, 965, 988, 969, 2199, 988, 990, + + 976, 973, 970, 979, 2199, 961, 999, 999, 999, 997, + 996, 1002, 999, 999, 969, 976, 990, 987, 2199, 2199, + 2199, 974, 2199, 1009, 1007, 1015, 2199, 2199, 2199, 989, + 981, 983, 976, 1002, 998, 997, 2199, 999, 999, 1005, + 992, 1006, 2199, 2199, 2199, 991, 1002, 1007, 1008, 1013, + 2199, 2199, 2199, 1008, 1007, 1004, 1009, 1019, 1005, 1016, + 1022, 1023, 1006, 1024, 1021, 1023, 2199, 2199, 1008, 1011, + 1015, 1023, 2199, 1017, 1013, 1015, 1030, 1024, 1026, 1027, + 1024, 1031, 2199, 1040, 1038, 2199, 1039, 1026, 1044, 1027, + 1033, 1025, 1045, 1037, 1034, 1034, 1040, 1055, 1037, 1039, + + 1039, 1047, 1047, 1047, 1054, 1049, 1045, 1047, 1062, 1059, + 1048, 2199, 1058, 1047, 1052, 1072, 1067, 1055, 1056, 1076, + 1066, 1070, 1076, 1072, 1069, 1078, 1078, 1071, 1085, 1068, + 1083, 1086, 1090, 1073, 1091, 1093, 1089, 2199, 1071, 1092, + 1089, 2199, 1079, 2199, 1100, 1093, 1090, 1083, 1083, 1085, + 2199, 1107, 1097, 1098, 2199, 1100, 2199, 1105, 1113, 2199, + 2199, 1133, 1132, 2199, 2199, 2199, 1106, 1133, 1118, 1116, + 1137, 1136, 1135, 1142, 1139, 1142, 2199, 1145, 1120, 1126, + 1112, 1119, 1146, 1149, 1153, 2199, 1132, 1118, 1119, 1139, + 1135, 2199, 2199, 1134, 2199, 1121, 2199, 1137, 1143, 1142, + + 2199, 2199, 1128, 2199, 1125, 1148, 1123, 1147, 1148, 1148, + 1139, 1153, 2199, 1143, 1151, 2199, 1148, 1143, 1138, 1142, + 1140, 1162, 1148, 2199, 1163, 1181, 1182, 1146, 1142, 1150, + 1156, 1166, 1168, 1158, 1155, 1162, 1171, 2199, 2199, 2199, + 2199, 2199, 2199, 1156, 1174, 1170, 1161, 1172, 1177, 1163, + 1163, 1181, 1165, 2199, 1178, 2199, 1185, 1173, 1189, 1185, + 1174, 1186, 1189, 1190, 1171, 1190, 1198, 1179, 1185, 1179, + 1197, 1190, 1197, 1185, 1184, 1198, 2199, 1203, 1205, 1206, + 1192, 1200, 1212, 2199, 2199, 1196, 2199, 1200, 1216, 1214, + 1217, 1204, 1211, 1205, 1213, 1215, 1218, 1223, 1224, 2199, + + 2199, 2199, 2199, 1212, 2199, 1250, 1215, 1217, 2199, 2199, + 2199, 2199, 2199, 2199, 2199, 2199, 2199, 1232, 2199, 2199, + 2199, 2199, 1224, 1228, 1239, 1239, 1228, 2199, 1237, 1237, + 2199, 1244, 1241, 1242, 1236, 1244, 1242, 1240, 2199, 1251, + 1249, 2199, 1238, 1241, 1235, 1239, 1243, 1241, 1256, 1240, + 1248, 2199, 2199, 1247, 1259, 1246, 1247, 1247, 1250, 1248, + 1259, 1269, 1254, 1254, 1270, 1272, 1267, 1262, 2199, 1269, + 1263, 2199, 1261, 1259, 1281, 2199, 1258, 1283, 1260, 2199, + 1286, 1287, 1288, 2199, 1286, 1265, 1282, 1287, 2199, 1277, + 2199, 1285, 1290, 1270, 1279, 1293, 1294, 1284, 1300, 1302, + + 1299, 1284, 1291, 1290, 1302, 1304, 1291, 1304, 1309, 2199, + 1298, 1310, 1300, 2199, 2199, 1314, 2199, 1332, 1330, 1338, + 1301, 1320, 1318, 2199, 1323, 1324, 1304, 1323, 1321, 2199, + 1308, 1325, 1330, 1326, 1333, 1329, 2199, 1315, 1332, 1336, + 1331, 1323, 1337, 1321, 1339, 1328, 1326, 2199, 2199, 2199, + 1322, 2199, 1323, 2199, 1331, 2199, 1343, 2199, 2199, 1331, + 1349, 1336, 1338, 1347, 2199, 2199, 1349, 1335, 2199, 1347, + 2199, 1344, 1342, 1344, 1345, 2199, 2199, 2199, 1341, 1356, + 1345, 1359, 1345, 1352, 1366, 1345, 2199, 2199, 1366, 1366, + 2199, 2199, 1353, 1354, 1368, 1369, 1366, 1375, 1363, 2199, + + 1360, 2199, 1393, 1398, 1398, 1402, 1385, 1386, 1387, 1385, + 1386, 1376, 2199, 1386, 1387, 1393, 1374, 1381, 1384, 1394, + 1378, 1381, 1388, 2199, 1382, 1397, 1383, 1401, 1394, 1405, + 1405, 1395, 2199, 1393, 2199, 1392, 1399, 1414, 1406, 2199, + 1411, 1405, 1403, 1404, 1406, 1407, 1397, 1414, 1405, 2199, + 1419, 1406, 1423, 1414, 1421, 1412, 1416, 1412, 1419, 1453, + 1421, 1416, 1437, 1429, 2199, 1454, 1452, 1460, 2199, 2199, + 1439, 1440, 1433, 1433, 1441, 1435, 1443, 1445, 1432, 2199, + 1440, 1451, 1446, 1449, 1444, 2199, 1451, 1448, 2199, 2199, + 1448, 2199, 1460, 1457, 2199, 1445, 2199, 1455, 1465, 1465, + + 1462, 1468, 2199, 1465, 1458, 1459, 1452, 1473, 1469, 1474, + 1467, 1468, 2199, 2199, 1473, 1474, 1456, 2199, 1461, 1482, + 2199, 1474, 1483, 1465, 1500, 1503, 1506, 1477, 1485, 1479, + 1487, 1488, 1485, 1477, 1487, 1479, 1486, 2199, 1494, 1491, + 1481, 1488, 2199, 1484, 1482, 1500, 1497, 2199, 1496, 1493, + 1508, 1498, 1493, 1492, 1508, 1505, 1490, 1515, 1514, 1500, + 1507, 1508, 1515, 1519, 1504, 1499, 1516, 1523, 1512, 1516, + 1521, 2199, 2199, 2199, 1521, 1513, 1523, 1515, 1509, 1530, + 1514, 1532, 1516, 1534, 1515, 1529, 1534, 1536, 1525, 1540, + 2199, 1532, 2199, 1533, 1536, 1542, 2199, 1525, 2199, 1548, + + 2199, 1549, 1535, 2199, 2199, 1549, 1546, 1545, 1538, 2199, + 1552, 1551, 1546, 1554, 1549, 1558, 1542, 1560, 1544, 2199, + 1553, 1563, 1555, 1565, 2199, 2199, 2199, 2199, 1551, 2199, + 2199, 2199, 1572, 1566, 1559, 1559, 1551, 1557, 2199, 2199, + 1573, 2199, 2199, 1570, 1575, 1581, 1567, 2199, 1569, 1579, + 1571, 1581, 1567, 1570, 1569, 1572, 1583, 1591, 1578, 1576, + 1590, 2199, 2199, 1578, 1592, 1595, 1586, 1582, 1581, 1584, + 1583, 1586, 2199, 2199, 2199, 2199, 2199, 1593, 1588, 1598, + 2199, 2199, 1590, 1598, 1605, 1602, 2199, 2199, 2199, 2199, + 1605, 1604, 1594, 2199, 2199, 1595, 1596, 1602, 1598, 1611, + + 1612, 1613, 1604, 1615, 1611, 1610, 1613, 1618, 1615, 2199, + 1625, 2199, 1610, 2199, 2199, 1623, 1619, 2199, 2199, 1663, + 1670, 1674, 1668, 1678, 1681, 1683, 1686, 1687, 1691, 1694, + 1688 + } ; + +static yyconst flex_int16_t yy_def[1832] = + { 0, + 1819, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 33, 1, 1, 1, 1, 1, 1, + 1819, 1819, 1819, 1819, 1820, 1821, 1822, 1823, 1819, 49, + 49, 1824, 1819, 1824, 1819, 1819, 1819, 1825, 1824, 1824, + 1824, 1824, 1824, 1824, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1824, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1824, 1819, + 1819, 1819, 1819, 1819, 1824, 1824, 1819, 1819, 1819, 1819, + + 1824, 1824, 1819, 1819, 1819, 1824, 1819, 1819, 1819, 1819, + 1819, 59, 1824, 1819, 1819, 1819, 1819, 1824, 1819, 1819, + 1819, 1819, 1819, 1819, 59, 1824, 1824, 1824, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 59, 1824, + 1819, 1819, 1819, 1819, 1819, 1819, 59, 1819, 1819, 1819, + 1819, 1819, 1825, 59, 1824, 1824, 1819, 1819, 1819, 59, + 1824, 1824, 1824, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 59, 1819, 1819, 1819, 59, 140, 1824, 1824, 1824, 1824, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 59, 1824, 1824, 1824, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1820, 1819, 1821, 1826, 1827, 1828, 1824, 49, 1829, 1824, + 1819, 1819, 1819, 1819, 1825, 1824, 1824, 1819, 1819, 1819, + 1819, 1824, 1824, 1819, 1824, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1824, + 1824, 1819, 1819, 1819, 1819, 1824, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1824, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1824, 1819, 1824, 1819, 1824, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1824, 1819, 1819, 1819, 1819, + 1819, 1824, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1824, 1819, 1824, 1824, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1830, 1826, 1831, 1828, 1829, 1824, + 1819, 1819, 1824, 1819, 1819, 1819, 1819, 1819, 1819, 1824, + 1819, 1819, 1824, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1824, 1819, + 1819, 1819, 1819, 1819, 1824, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1824, 1819, 1819, 1819, 1824, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1824, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1830, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1824, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 0, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819 + } ; + +static yyconst flex_int16_t yy_nxt[2259] = + { 0, + 42, 43, 44, 45, 46, 42, 42, 47, 42, 48, + 49, 50, 50, 51, 50, 50, 50, 50, 50, 50, + 52, 53, 52, 54, 42, 55, 56, 57, 58, 42, + 42, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 42, 68, 69, 70, 71, 72, 73, 42, 74, 75, + 76, 77, 42, 42, 78, 79, 42, 42, 42, 80, + 89, 239, 240, 81, 90, 82, 455, 207, 83, 84, + 481, 247, 85, 216, 86, 87, 88, 80, 91, 147, + 986, 81, 248, 82, 92, 93, 83, 84, 208, 94, + 85, 89, 86, 87, 88, 90, 148, 209, 149, 232, + + 95, 96, 207, 170, 253, 150, 151, 97, 94, 91, + 254, 100, 170, 171, 98, 92, 93, 99, 355, 95, + 96, 172, 171, 208, 101, 102, 97, 100, 987, 103, + 172, 118, 209, 98, 104, 249, 99, 119, 106, 173, + 101, 102, 120, 105, 121, 103, 107, 216, 173, 106, + 104, 108, 109, 244, 245, 122, 123, 107, 216, 105, + 110, 111, 108, 109, 220, 112, 246, 112, 113, 221, + 113, 110, 111, 114, 216, 114, 118, 216, 241, 293, + 242, 988, 119, 115, 1819, 115, 515, 120, 294, 121, + 243, 116, 117, 116, 117, 230, 139, 140, 139, 140, + + 122, 123, 124, 141, 233, 141, 226, 227, 231, 216, + 228, 142, 339, 142, 143, 258, 143, 144, 234, 144, + 147, 229, 145, 146, 145, 146, 269, 125, 126, 127, + 128, 239, 274, 129, 216, 130, 403, 148, 131, 149, + 132, 270, 133, 237, 134, 135, 150, 151, 152, 136, + 989, 238, 404, 137, 138, 153, 250, 255, 154, 152, + 155, 251, 235, 156, 157, 256, 153, 252, 216, 154, + 259, 155, 257, 269, 156, 157, 260, 262, 236, 265, + 263, 266, 478, 265, 158, 266, 261, 267, 289, 244, + 245, 286, 276, 264, 232, 158, 159, 277, 479, 250, + + 275, 268, 246, 278, 251, 268, 413, 280, 273, 283, + 279, 259, 281, 284, 249, 288, 240, 260, 216, 216, + 299, 160, 161, 162, 282, 163, 254, 261, 216, 216, + 285, 249, 164, 165, 262, 216, 166, 263, 167, 990, + 168, 322, 244, 245, 232, 290, 320, 240, 169, 159, + 264, 287, 323, 292, 232, 246, 230, 235, 291, 295, + 216, 262, 991, 249, 263, 296, 350, 240, 216, 231, + 244, 245, 297, 236, 160, 161, 162, 264, 163, 234, + 216, 298, 314, 246, 302, 164, 165, 250, 235, 166, + 216, 167, 251, 168, 232, 303, 262, 259, 252, 263, + + 315, 169, 174, 260, 236, 244, 245, 342, 309, 301, + 233, 304, 264, 261, 306, 239, 409, 537, 246, 440, + 420, 307, 357, 312, 234, 343, 313, 175, 176, 177, + 178, 179, 180, 181, 258, 182, 258, 183, 184, 185, + 186, 187, 188, 216, 189, 190, 191, 192, 193, 194, + 195, 216, 244, 245, 196, 197, 198, 262, 199, 200, + 263, 201, 202, 310, 992, 246, 203, 437, 216, 316, + 216, 311, 308, 264, 204, 216, 241, 487, 338, 489, + 230, 205, 206, 197, 198, 253, 199, 200, 243, 201, + 202, 254, 380, 231, 203, 244, 245, 262, 318, 423, + + 263, 232, 204, 248, 456, 457, 321, 319, 246, 205, + 206, 216, 234, 340, 217, 317, 218, 218, 218, 218, + 218, 218, 218, 218, 218, 218, 217, 216, 217, 217, + 324, 327, 216, 325, 993, 216, 328, 217, 217, 217, + 217, 217, 217, 326, 330, 329, 259, 216, 258, 254, + 331, 216, 260, 336, 262, 216, 216, 263, 216, 216, + 219, 337, 261, 433, 230, 332, 259, 265, 344, 266, + 264, 216, 260, 232, 333, 345, 424, 231, 265, 535, + 266, 573, 261, 574, 348, 237, 359, 235, 216, 268, + 216, 250, 230, 238, 349, 632, 251, 232, 354, 363, + + 268, 216, 252, 236, 259, 352, 358, 1819, 244, 245, + 260, 353, 356, 375, 365, 216, 381, 216, 366, 361, + 261, 246, 411, 364, 237, 367, 239, 240, 994, 465, + 374, 233, 238, 249, 368, 485, 244, 376, 385, 249, + 369, 370, 371, 235, 377, 234, 423, 378, 382, 379, + 269, 250, 386, 216, 995, 504, 251, 387, 254, 372, + 400, 255, 383, 388, 373, 270, 996, 389, 216, 256, + 390, 259, 384, 393, 391, 216, 257, 260, 216, 394, + 392, 395, 216, 216, 263, 396, 265, 261, 266, 269, + 230, 265, 216, 266, 399, 410, 397, 398, 233, 412, + + 216, 407, 216, 406, 270, 414, 235, 241, 268, 242, + 451, 437, 234, 268, 430, 216, 498, 408, 490, 243, + 428, 519, 236, 517, 465, 546, 429, 431, 513, 495, + 544, 437, 465, 430, 216, 547, 431, 216, 559, 216, + 579, 550, 444, 541, 582, 584, 431, 593, 597, 455, + 598, 580, 601, 216, 599, 462, 585, 216, 581, 596, + 465, 216, 565, 602, 445, 465, 606, 594, 216, 605, + 647, 619, 648, 654, 673, 428, 657, 216, 563, 216, + 658, 429, 566, 669, 638, 649, 655, 656, 659, 660, + 661, 216, 662, 720, 650, 216, 663, 624, 643, 722, + + 626, 709, 735, 721, 780, 650, 657, 635, 783, 795, + 658, 771, 825, 685, 216, 649, 826, 713, 810, 811, + 997, 998, 852, 999, 942, 691, 1000, 1001, 632, 837, + 838, 839, 840, 943, 841, 842, 843, 853, 944, 1002, + 737, 1004, 1005, 1006, 1007, 1003, 1009, 1010, 1011, 1008, + 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, + 903, 1022, 1023, 1024, 1025, 1027, 1026, 1028, 1029, 1030, + 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, + 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, + 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, + + 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, + 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, + 1083, 1071, 1072, 1084, 1085, 1086, 1087, 1091, 1093, 1094, + 1095, 1096, 1088, 1097, 1098, 1099, 1100, 1101, 1089, 1092, + 1102, 1103, 1104, 1105, 1106, 1107, 1090, 1108, 1109, 1110, + 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, + 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, + 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, + 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, + + 1161, 1162, 1164, 1165, 1163, 1166, 1167, 1168, 1169, 1170, + 647, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, + 1180, 1181, 1182, 658, 1183, 1184, 1185, 1186, 1187, 1188, + 1190, 1189, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, + 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, + 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, + 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, + 1229, 1230, 1231, 1233, 1234, 1235, 1237, 1238, 1239, 1236, + 1240, 1241, 1232, 1242, 1243, 1244, 1245, 1246, 1247, 1248, + 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, + + 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, + 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278, + 1280, 1281, 1282, 1283, 1284, 1279, 1285, 1286, 1288, 1289, + 1290, 1291, 1292, 1293, 1294, 1295, 1188, 1296, 1189, 1297, + 1287, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, + 1307, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, + 1318, 1319, 1320, 1321, 1308, 1322, 1323, 1324, 1325, 1326, + 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, + 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, + 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, + + 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, + 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, + 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, + 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, + 1397, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1407, 1408, + 1409, 1410, 1411, 1406, 1412, 1413, 1304, 1398, 1414, 1415, + 1416, 1417, 1418, 1419, 1421, 1420, 1422, 1423, 1424, 1425, + 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, + 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443, 1444, 1445, + 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, + + 1456, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, + 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, + 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, + 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1486, + 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1505, 1506, + 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, + 1517, 1518, 1504, 1519, 1520, 1521, 1522, 1523, 1524, 1525, + 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, + 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, + 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, + + 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, + 1566, 1567, 1569, 1568, 1570, 1571, 1572, 1573, 1574, 1576, + 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, + 1588, 1589, 1590, 1591, 1575, 1577, 1592, 1593, 1594, 1595, + 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, + 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, + 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, + 1626, 1627, 1628, 1630, 1632, 1633, 1634, 1635, 1636, 1637, + 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1629, 1631, + 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, + + 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, + 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, + 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, + 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1694, 1695, + 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, + 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715, + 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, + 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, + 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, + 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, + + 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, + 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, + 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, + 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, + 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804, 1805, + 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, + 1816, 1817, 1818, 211, 211, 211, 211, 211, 211, 211, + 213, 215, 213, 213, 213, 213, 213, 214, 214, 214, + 217, 217, 217, 217, 225, 416, 416, 416, 416, 417, + 418, 623, 418, 418, 419, 985, 419, 622, 984, 622, + + 622, 983, 982, 821, 981, 980, 979, 978, 977, 976, + 975, 974, 973, 972, 971, 970, 969, 968, 967, 966, + 965, 964, 963, 962, 961, 960, 959, 958, 957, 956, + 955, 954, 953, 952, 951, 950, 949, 948, 947, 946, + 945, 941, 940, 939, 938, 937, 821, 936, 935, 934, + 933, 932, 931, 930, 929, 928, 821, 927, 926, 925, + 924, 923, 922, 921, 920, 919, 918, 917, 916, 915, + 914, 913, 912, 911, 910, 909, 908, 907, 906, 905, + 904, 902, 901, 900, 899, 898, 897, 896, 895, 894, + 893, 892, 891, 890, 889, 888, 887, 886, 885, 884, + + 883, 882, 881, 880, 879, 878, 877, 876, 859, 875, + 874, 873, 872, 871, 870, 869, 868, 867, 866, 865, + 864, 863, 862, 861, 860, 859, 858, 857, 856, 855, + 854, 851, 850, 849, 848, 847, 846, 845, 844, 836, + 835, 834, 833, 832, 831, 830, 829, 828, 827, 824, + 823, 822, 821, 820, 819, 818, 817, 816, 815, 814, + 813, 812, 809, 808, 807, 806, 805, 804, 803, 802, + 801, 800, 799, 798, 797, 796, 794, 793, 792, 791, + 790, 789, 788, 787, 786, 785, 784, 782, 781, 779, + 778, 777, 776, 775, 774, 773, 772, 770, 769, 768, + + 767, 766, 765, 764, 763, 762, 761, 760, 759, 758, + 757, 756, 755, 754, 753, 752, 751, 750, 749, 748, + 747, 746, 745, 744, 743, 742, 741, 740, 739, 738, + 736, 734, 733, 732, 731, 730, 729, 728, 727, 726, + 725, 724, 723, 719, 718, 717, 716, 715, 714, 712, + 711, 710, 708, 707, 706, 705, 704, 703, 702, 701, + 700, 699, 698, 697, 696, 695, 694, 693, 692, 690, + 689, 688, 687, 686, 684, 683, 682, 681, 680, 679, + 678, 677, 676, 675, 674, 672, 671, 670, 668, 667, + 666, 665, 664, 663, 653, 652, 651, 650, 649, 646, + + 645, 644, 643, 642, 641, 640, 639, 638, 637, 636, + 634, 633, 631, 630, 629, 628, 627, 625, 415, 621, + 620, 618, 617, 616, 615, 614, 613, 612, 611, 610, + 609, 608, 607, 604, 603, 600, 595, 592, 591, 590, + 589, 588, 587, 586, 583, 578, 577, 576, 575, 572, + 571, 570, 569, 568, 567, 564, 562, 561, 560, 558, + 557, 556, 555, 554, 553, 552, 551, 549, 548, 545, + 543, 542, 540, 539, 538, 536, 534, 533, 532, 531, + 530, 529, 528, 527, 526, 525, 524, 523, 522, 521, + 520, 518, 516, 514, 512, 511, 510, 509, 508, 507, + + 506, 505, 503, 502, 501, 500, 499, 497, 496, 494, + 493, 492, 491, 488, 486, 484, 483, 482, 480, 477, + 476, 475, 474, 473, 472, 471, 470, 469, 468, 467, + 466, 465, 464, 463, 462, 461, 460, 459, 458, 455, + 454, 453, 452, 451, 450, 449, 448, 447, 446, 445, + 444, 443, 442, 441, 440, 439, 438, 437, 436, 435, + 434, 432, 427, 426, 425, 422, 421, 1819, 216, 415, + 212, 210, 405, 402, 401, 362, 360, 351, 347, 346, + 341, 335, 334, 305, 300, 272, 271, 258, 249, 224, + 223, 222, 216, 216, 1819, 212, 210, 1819, 41, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819 + } ; + +static yyconst flex_int16_t yy_chk[2259] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 5, 65, 65, 3, 5, 3, 282, 39, 3, 3, + 282, 68, 3, 61, 3, 3, 3, 4, 5, 21, + 812, 4, 68, 4, 5, 5, 4, 4, 39, 7, + 4, 6, 4, 4, 4, 6, 21, 39, 21, 61, + + 7, 7, 40, 31, 71, 21, 21, 7, 8, 6, + 71, 9, 32, 31, 7, 6, 6, 7, 164, 8, + 8, 31, 32, 40, 9, 9, 8, 10, 813, 9, + 32, 15, 40, 8, 9, 164, 8, 15, 11, 31, + 10, 10, 15, 9, 15, 10, 11, 316, 32, 12, + 10, 11, 11, 67, 67, 15, 15, 12, 60, 10, + 11, 11, 12, 12, 51, 13, 67, 14, 13, 51, + 14, 12, 12, 13, 62, 14, 16, 59, 66, 98, + 66, 815, 16, 13, 51, 14, 316, 16, 98, 16, + 66, 13, 13, 14, 14, 60, 19, 19, 20, 20, + + 16, 16, 17, 19, 62, 20, 59, 59, 60, 64, + 59, 19, 142, 20, 19, 142, 20, 19, 62, 20, + 22, 59, 19, 19, 20, 20, 77, 17, 17, 17, + 17, 81, 81, 17, 63, 17, 195, 22, 17, 22, + 17, 77, 17, 64, 17, 17, 22, 22, 27, 17, + 816, 64, 195, 17, 17, 27, 70, 72, 27, 28, + 27, 70, 63, 27, 27, 72, 28, 70, 80, 28, + 74, 28, 72, 91, 28, 28, 74, 75, 63, 76, + 75, 76, 280, 88, 27, 88, 74, 76, 91, 82, + 82, 88, 83, 75, 80, 28, 29, 83, 280, 84, + + 82, 76, 82, 83, 84, 88, 208, 85, 80, 86, + 84, 86, 85, 86, 83, 90, 90, 86, 89, 95, + 104, 29, 29, 29, 85, 29, 104, 86, 96, 102, + 87, 208, 29, 29, 87, 101, 29, 87, 29, 818, + 29, 131, 97, 97, 89, 95, 129, 129, 29, 30, + 87, 89, 131, 97, 96, 97, 95, 102, 96, 99, + 106, 99, 819, 131, 99, 101, 157, 157, 118, 95, + 103, 103, 102, 102, 30, 30, 30, 99, 30, 101, + 113, 103, 125, 103, 107, 30, 30, 107, 106, 30, + 220, 30, 107, 30, 118, 108, 109, 108, 107, 109, + + 125, 30, 33, 108, 106, 114, 114, 147, 118, 106, + 113, 109, 109, 108, 113, 201, 201, 338, 114, 338, + 220, 114, 166, 121, 113, 147, 121, 33, 33, 33, + 33, 33, 33, 33, 166, 33, 121, 33, 33, 33, + 33, 33, 33, 126, 33, 33, 33, 33, 33, 33, + 33, 290, 119, 119, 33, 35, 35, 115, 35, 35, + 115, 35, 35, 119, 820, 119, 35, 288, 128, 126, + 226, 120, 115, 115, 35, 127, 141, 288, 141, 290, + 126, 35, 35, 36, 36, 120, 36, 36, 141, 36, + 36, 120, 183, 126, 36, 130, 130, 143, 128, 226, + + 143, 127, 36, 183, 259, 259, 130, 128, 130, 36, + 36, 49, 128, 143, 49, 127, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 140, 49, 49, + 132, 133, 227, 132, 822, 336, 133, 49, 49, 49, + 49, 49, 49, 132, 134, 133, 134, 155, 133, 132, + 135, 156, 134, 140, 135, 161, 235, 135, 430, 163, + 49, 140, 134, 235, 140, 135, 148, 149, 148, 149, + 135, 162, 148, 155, 135, 149, 227, 140, 168, 336, + 168, 373, 148, 373, 155, 156, 168, 163, 177, 149, + 180, 165, 161, 156, 156, 430, 165, 162, 163, 176, + + 168, 178, 165, 163, 167, 161, 167, 176, 172, 172, + 167, 162, 165, 181, 177, 179, 184, 305, 177, 172, + 167, 172, 203, 176, 180, 177, 181, 181, 823, 286, + 180, 178, 180, 184, 178, 286, 182, 182, 186, 203, + 178, 178, 178, 179, 182, 178, 305, 182, 185, 182, + 192, 185, 186, 198, 824, 305, 185, 187, 186, 179, + 192, 187, 185, 188, 179, 192, 825, 188, 199, 187, + 188, 189, 185, 189, 188, 291, 187, 189, 200, 190, + 188, 190, 232, 233, 190, 190, 191, 189, 191, 209, + 198, 204, 318, 204, 191, 202, 190, 190, 199, 204, + + 314, 199, 296, 198, 209, 209, 200, 202, 191, 202, + 299, 320, 199, 204, 233, 342, 299, 200, 291, 202, + 232, 320, 200, 318, 345, 347, 232, 233, 314, 296, + 345, 350, 359, 296, 363, 347, 318, 365, 359, 366, + 378, 350, 379, 342, 380, 382, 296, 390, 393, 392, + 393, 378, 395, 420, 393, 398, 382, 423, 379, 392, + 399, 513, 365, 395, 380, 412, 399, 390, 433, 398, + 449, 412, 449, 459, 477, 365, 460, 489, 363, 495, + 460, 365, 366, 472, 472, 477, 459, 459, 461, 461, + 461, 517, 461, 524, 525, 541, 539, 420, 577, 525, + + 423, 513, 539, 524, 586, 589, 601, 433, 589, 601, + 601, 577, 633, 489, 713, 586, 633, 517, 616, 616, + 826, 827, 660, 828, 765, 495, 828, 829, 517, 649, + 649, 649, 649, 765, 649, 649, 649, 660, 765, 830, + 541, 832, 834, 836, 837, 830, 838, 839, 840, 837, + 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, + 713, 851, 852, 853, 853, 854, 853, 855, 856, 858, + 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, + 869, 870, 871, 872, 874, 876, 877, 878, 879, 880, + 881, 882, 884, 885, 886, 887, 888, 889, 890, 891, + + 892, 893, 894, 895, 896, 897, 898, 898, 899, 900, + 901, 902, 903, 904, 905, 906, 908, 909, 910, 911, + 912, 900, 900, 913, 914, 915, 917, 918, 919, 920, + 921, 922, 917, 924, 925, 927, 928, 929, 917, 918, + 930, 931, 932, 933, 934, 935, 917, 936, 937, 938, + 940, 941, 942, 943, 944, 945, 947, 949, 950, 951, + 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, + 962, 963, 965, 966, 967, 969, 970, 971, 972, 973, + 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, + 984, 985, 986, 987, 988, 989, 990, 992, 993, 994, + + 995, 996, 997, 999, 996, 1000, 1001, 1002, 1003, 1004, + 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, + 1016, 1017, 1018, 1022, 1024, 1025, 1026, 1030, 1031, 1032, + 1033, 1032, 1034, 1035, 1036, 1038, 1039, 1040, 1041, 1042, + 1046, 1047, 1048, 1049, 1050, 1054, 1055, 1056, 1057, 1058, + 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1069, 1070, + 1071, 1072, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, + 1082, 1084, 1085, 1087, 1088, 1089, 1090, 1091, 1092, 1089, + 1093, 1094, 1085, 1095, 1096, 1097, 1098, 1099, 1100, 1101, + 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, + + 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, + 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, + 1133, 1134, 1135, 1136, 1137, 1132, 1139, 1140, 1141, 1143, + 1145, 1146, 1147, 1148, 1149, 1150, 1147, 1152, 1147, 1153, + 1140, 1154, 1156, 1158, 1159, 1162, 1163, 1167, 1168, 1169, + 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1178, 1179, 1180, + 1181, 1182, 1183, 1184, 1170, 1185, 1187, 1188, 1189, 1190, + 1191, 1194, 1196, 1198, 1199, 1200, 1203, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1214, 1215, 1217, 1218, 1219, + 1220, 1221, 1222, 1223, 1225, 1226, 1227, 1228, 1229, 1230, + + 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1244, 1245, 1246, + 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1255, 1257, 1258, + 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, + 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1278, 1279, + 1280, 1281, 1282, 1283, 1286, 1288, 1289, 1290, 1291, 1292, + 1293, 1294, 1295, 1290, 1296, 1297, 1296, 1280, 1298, 1299, + 1304, 1306, 1306, 1306, 1307, 1306, 1308, 1318, 1323, 1324, + 1325, 1326, 1327, 1329, 1330, 1332, 1333, 1334, 1335, 1336, + 1337, 1338, 1340, 1341, 1343, 1344, 1345, 1346, 1347, 1348, + 1349, 1350, 1351, 1354, 1355, 1356, 1357, 1358, 1359, 1360, + + 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1370, 1371, + 1373, 1374, 1375, 1377, 1378, 1379, 1381, 1382, 1383, 1385, + 1386, 1387, 1388, 1390, 1392, 1393, 1394, 1395, 1396, 1397, + 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1397, + 1407, 1408, 1409, 1411, 1412, 1413, 1416, 1418, 1419, 1420, + 1421, 1422, 1423, 1425, 1426, 1427, 1428, 1429, 1431, 1432, + 1433, 1434, 1418, 1435, 1436, 1438, 1439, 1440, 1441, 1442, + 1443, 1444, 1445, 1446, 1447, 1451, 1453, 1455, 1457, 1460, + 1461, 1462, 1463, 1464, 1467, 1468, 1470, 1472, 1473, 1474, + 1475, 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1489, + + 1490, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1501, 1503, + 1504, 1504, 1505, 1504, 1506, 1507, 1508, 1509, 1510, 1511, + 1512, 1514, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, + 1523, 1525, 1526, 1527, 1510, 1511, 1528, 1529, 1530, 1531, + 1532, 1534, 1536, 1537, 1538, 1539, 1541, 1542, 1543, 1544, + 1545, 1546, 1547, 1548, 1549, 1551, 1552, 1553, 1554, 1555, + 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1566, + 1567, 1568, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, + 1579, 1581, 1582, 1583, 1584, 1585, 1587, 1588, 1571, 1572, + 1591, 1593, 1594, 1596, 1598, 1599, 1600, 1601, 1602, 1604, + + 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1615, 1616, + 1617, 1619, 1620, 1622, 1623, 1624, 1625, 1626, 1627, 1628, + 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1639, + 1640, 1641, 1642, 1644, 1645, 1646, 1647, 1649, 1650, 1651, + 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, + 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, + 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, + 1685, 1686, 1687, 1688, 1689, 1690, 1692, 1694, 1695, 1696, + 1698, 1700, 1702, 1703, 1706, 1707, 1708, 1709, 1711, 1712, + 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1721, 1722, 1723, + + 1724, 1729, 1733, 1734, 1735, 1736, 1737, 1738, 1741, 1744, + 1745, 1746, 1747, 1749, 1750, 1751, 1752, 1753, 1754, 1755, + 1756, 1757, 1758, 1759, 1760, 1761, 1764, 1765, 1766, 1767, + 1768, 1769, 1770, 1771, 1772, 1778, 1779, 1780, 1783, 1784, + 1785, 1786, 1791, 1792, 1793, 1796, 1797, 1798, 1799, 1800, + 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1811, + 1813, 1816, 1817, 1820, 1820, 1820, 1820, 1820, 1820, 1820, + 1821, 1823, 1821, 1821, 1821, 1821, 1821, 1822, 1822, 1822, + 1824, 1824, 1824, 1824, 1825, 1826, 1826, 1826, 1826, 1827, + 1828, 1831, 1828, 1828, 1829, 811, 1829, 1830, 810, 1830, + + 1830, 809, 808, 807, 806, 805, 803, 802, 801, 799, + 798, 797, 796, 795, 794, 793, 792, 791, 790, 789, + 788, 787, 786, 785, 783, 782, 781, 780, 779, 777, + 776, 775, 774, 773, 772, 771, 770, 769, 768, 767, + 766, 764, 763, 762, 761, 760, 759, 757, 756, 755, + 753, 752, 751, 750, 749, 748, 747, 746, 745, 743, + 742, 741, 740, 739, 736, 735, 732, 730, 729, 728, + 727, 726, 725, 724, 723, 721, 720, 719, 718, 716, + 715, 712, 711, 710, 709, 708, 707, 706, 705, 704, + 703, 702, 701, 700, 699, 698, 697, 696, 695, 694, + + 692, 691, 690, 689, 688, 687, 686, 685, 684, 683, + 682, 681, 680, 679, 678, 677, 676, 674, 673, 672, + 671, 670, 669, 668, 667, 666, 665, 664, 663, 662, + 661, 657, 656, 655, 654, 653, 652, 651, 650, 648, + 645, 644, 642, 641, 640, 639, 638, 635, 634, 632, + 631, 630, 629, 628, 627, 626, 625, 621, 620, 619, + 618, 617, 615, 614, 613, 612, 611, 610, 609, 608, + 607, 606, 605, 604, 603, 602, 600, 599, 598, 597, + 596, 595, 594, 593, 592, 591, 590, 588, 587, 585, + 584, 583, 582, 581, 580, 579, 578, 576, 575, 574, + + 573, 572, 571, 569, 568, 567, 566, 565, 564, 563, + 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, + 552, 551, 550, 549, 548, 546, 545, 544, 543, 542, + 540, 538, 537, 536, 535, 534, 533, 532, 531, 530, + 529, 528, 527, 523, 522, 521, 520, 519, 518, 516, + 515, 514, 512, 511, 510, 509, 508, 507, 506, 505, + 504, 503, 502, 501, 500, 499, 498, 497, 496, 494, + 493, 492, 491, 490, 488, 487, 486, 485, 484, 483, + 482, 481, 480, 479, 478, 475, 474, 473, 471, 469, + 468, 466, 465, 462, 458, 455, 452, 451, 450, 446, + + 445, 444, 443, 442, 441, 440, 439, 438, 436, 435, + 432, 431, 429, 428, 427, 426, 425, 421, 416, 414, + 413, 411, 410, 409, 408, 407, 406, 405, 404, 403, + 402, 401, 400, 397, 396, 394, 391, 389, 388, 387, + 386, 385, 384, 383, 381, 377, 376, 375, 374, 372, + 371, 370, 369, 368, 367, 364, 362, 361, 360, 358, + 357, 356, 355, 354, 353, 352, 351, 349, 348, 346, + 344, 343, 341, 340, 339, 337, 335, 334, 333, 332, + 331, 330, 329, 328, 327, 326, 325, 324, 323, 322, + 321, 319, 317, 315, 313, 312, 311, 310, 309, 308, + + 307, 306, 304, 303, 302, 301, 300, 298, 297, 295, + 294, 293, 292, 289, 287, 285, 284, 283, 281, 279, + 278, 277, 276, 275, 274, 273, 272, 271, 270, 269, + 268, 267, 266, 265, 264, 263, 262, 261, 260, 258, + 257, 255, 254, 253, 252, 251, 250, 249, 248, 247, + 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, + 236, 234, 231, 230, 229, 225, 221, 218, 217, 214, + 211, 210, 197, 194, 193, 175, 171, 160, 154, 153, + 144, 139, 136, 112, 105, 79, 78, 73, 69, 57, + 56, 55, 54, 52, 50, 45, 43, 41, 1819, 1819, + + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +static int yy_more_flag = 0; +static int yy_more_len = 0; +#define yymore() ((yy_more_flag) = 1) +#define YY_MORE_ADJ (yy_more_len) +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "cftoken.l" +/* $NetBSD: cftoken.l,v 1.23.2.1 2012/08/29 08:42:24 tteras Exp $ */ +/* Id: cftoken.l,v 1.53 2006/08/22 18:17:17 manubsd Exp */ +#line 6 "cftoken.l" +/* + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 and 2003 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_STDARG_H +#include +#else +#include +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "debug.h" + +#include "algorithm.h" +#include "cfparse_proto.h" +#include "cftoken_proto.h" +#include "localconf.h" +#include "oakley.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "ipsec_doi.h" +#include "policy.h" +#include "proposal.h" +#include "remoteconf.h" +#ifdef GC +#include "gcmalloc.h" +#endif + +#include "cfparse.h" + +int yyerrorcount = 0; + +#if defined(YIPS_DEBUG) +# define YYDB plog(LLV_DEBUG2, LOCATION, NULL, \ + "begin <%d>%s\n", yy_start, yytext); +# define YYD { \ + plog(LLV_DEBUG2, LOCATION, NULL, "<%d>%s", \ + yy_start, loglevel >= LLV_DEBUG2 ? "\n" : ""); \ +} +#else +# define YYDB +# define YYD +#endif /* defined(YIPS_DEBUG) */ + +#define MAX_INCLUDE_DEPTH 10 + +static struct include_stack { + char *path; + FILE *fp; + YY_BUFFER_STATE prevstate; + int lineno; + glob_t matches; + int matchon; +} incstack[MAX_INCLUDE_DEPTH]; +static int incstackp = 0; + +static int yy_first_time = 1; +/* common seciton */ +/*octet (([01]?{digit}?{digit})|((2([0-4]{digit}))|(25[0-5]))) */ + + + + + + +#line 1665 "cftoken.c" + +#define INITIAL 0 +#define S_INI 1 +#define S_PRIV 2 +#define S_PTH 3 +#define S_LOG 4 +#define S_PAD 5 +#define S_LST 6 +#define S_RTRY 7 +#define S_CFG 8 +#define S_LDAP 9 +#define S_RAD 10 +#define S_ALGST 11 +#define S_ALGCL 12 +#define S_SAINF 13 +#define S_SAINFS 14 +#define S_RMT 15 +#define S_RMTS 16 +#define S_RMTP 17 +#define S_SA 18 +#define S_GSSENC 19 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (void ); + +int yyget_debug (void ); + +void yyset_debug (int debug_flag ); + +YY_EXTRA_TYPE yyget_extra (void ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in (void ); + +void yyset_in (FILE * in_str ); + +FILE *yyget_out (void ); + +void yyset_out (FILE * out_str ); + +yy_size_t yyget_leng (void ); + +char *yyget_text (void ); + +int yyget_lineno (void ); + +void yyset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 142 "cftoken.l" + + + if (yy_first_time) { + BEGIN S_INI; + yy_first_time = 0; + } + + + /* privsep */ +#line 1876 "cftoken.c" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + (yy_more_len) = 0; + if ( (yy_more_flag) ) + { + (yy_more_len) = (yy_c_buf_p) - (yytext_ptr); + (yy_more_flag) = 0; + } + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1820 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 2199 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 151 "cftoken.l" +{ BEGIN S_PRIV; YYDB; return(PRIVSEP); } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 152 "cftoken.l" +{ return(BOC); } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 153 "cftoken.l" +{ YYD; return(USER); } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 154 "cftoken.l" +{ YYD; return(GROUP); } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 155 "cftoken.l" +{ YYD; return(CHROOT); } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 156 "cftoken.l" +{ BEGIN S_INI; return(EOC); } + YY_BREAK +/* path */ +case 7: +YY_RULE_SETUP +#line 159 "cftoken.l" +{ BEGIN S_PTH; YYDB; return(PATH); } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 160 "cftoken.l" +{ YYD; yylval.num = LC_PATHTYPE_INCLUDE; + return(PATHTYPE); } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 162 "cftoken.l" +{ YYD; yylval.num = LC_PATHTYPE_PSK; + return(PATHTYPE); } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 164 "cftoken.l" +{ YYD; yylval.num = LC_PATHTYPE_CERT; + return(PATHTYPE); } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 166 "cftoken.l" +{ YYD; yylval.num = LC_PATHTYPE_SCRIPT; + return(PATHTYPE); } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 168 "cftoken.l" +{ YYD; yylval.num = LC_PATHTYPE_BACKUPSA; + return(PATHTYPE); } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 170 "cftoken.l" +{ YYD; yylval.num = LC_PATHTYPE_PIDFILE; + return(PATHTYPE); } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 172 "cftoken.l" +{ BEGIN S_INI; YYDB; return(EOS); } + YY_BREAK +/* include */ +case 15: +YY_RULE_SETUP +#line 175 "cftoken.l" +{ YYDB; return(INCLUDE); } + YY_BREAK +/* pfkey_buffer */ +case 16: +YY_RULE_SETUP +#line 178 "cftoken.l" +{ YYDB; return(PFKEY_BUFFER); } + YY_BREAK +/* special */ +case 17: +YY_RULE_SETUP +#line 181 "cftoken.l" +{ YYDB; return(COMPLEX_BUNDLE); } + YY_BREAK +/* logging */ +case 18: +YY_RULE_SETUP +#line 184 "cftoken.l" +{ BEGIN S_LOG; YYDB; return(LOGGING); } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 185 "cftoken.l" +{ YYD; yylval.num = LLV_ERROR; return(LOGLEV); } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 186 "cftoken.l" +{ YYD; yylval.num = LLV_WARNING; return(LOGLEV); } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 187 "cftoken.l" +{ YYD; yylval.num = LLV_NOTIFY; return(LOGLEV); } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 188 "cftoken.l" +{ YYD; yylval.num = LLV_INFO; return(LOGLEV); } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 189 "cftoken.l" +{ YYD; yylval.num = LLV_DEBUG; return(LOGLEV); } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 190 "cftoken.l" +{ YYD; yylval.num = LLV_DEBUG2; return(LOGLEV); } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 191 "cftoken.l" +{ BEGIN S_INI; return(EOS); } + YY_BREAK +/* padding */ +case 26: +YY_RULE_SETUP +#line 194 "cftoken.l" +{ BEGIN S_PAD; YYDB; return(PADDING); } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 195 "cftoken.l" +{ return(BOC); } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 196 "cftoken.l" +{ YYD; return(PAD_RANDOMIZE); } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 197 "cftoken.l" +{ YYD; return(PAD_RANDOMIZELEN); } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 198 "cftoken.l" +{ YYD; return(PAD_MAXLEN); } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 199 "cftoken.l" +{ YYD; return(PAD_STRICT); } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 200 "cftoken.l" +{ YYD; return(PAD_EXCLTAIL); } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 201 "cftoken.l" +{ BEGIN S_INI; return(EOC); } + YY_BREAK +/* listen */ +case 34: +YY_RULE_SETUP +#line 204 "cftoken.l" +{ BEGIN S_LST; YYDB; return(LISTEN); } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 205 "cftoken.l" +{ return(BOC); } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 206 "cftoken.l" +{ YYD; return(X_ISAKMP); } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 207 "cftoken.l" +{ YYD; return(X_ISAKMP_NATT); } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 208 "cftoken.l" +{ YYD; return(X_ADMIN); } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 209 "cftoken.l" +{ YYD; return(ADMINSOCK); } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 210 "cftoken.l" +{ YYD; return(DISABLED); } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 211 "cftoken.l" +{ YYD; return(STRICT_ADDRESS); } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 212 "cftoken.l" +{ BEGIN S_INI; return(EOC); } + YY_BREAK +/* radius config */ +case 43: +YY_RULE_SETUP +#line 215 "cftoken.l" +{ BEGIN S_RAD; YYDB; return(RADCFG); } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 216 "cftoken.l" +{ return(BOC); } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 217 "cftoken.l" +{ YYD; return(RAD_AUTH); } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 218 "cftoken.l" +{ YYD; return(RAD_ACCT); } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 219 "cftoken.l" +{ YYD; return(RAD_TIMEOUT); } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 220 "cftoken.l" +{ YYD; return(RAD_RETRIES); } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 221 "cftoken.l" +{ BEGIN S_INI; return(EOC); } + YY_BREAK +/* ldap config */ +case 50: +YY_RULE_SETUP +#line 224 "cftoken.l" +{ BEGIN S_LDAP; YYDB; return(LDAPCFG); } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 225 "cftoken.l" +{ return(BOC); } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 226 "cftoken.l" +{ YYD; return(LDAP_PVER); } + YY_BREAK +case 53: +YY_RULE_SETUP +#line 227 "cftoken.l" +{ YYD; return(LDAP_HOST); } + YY_BREAK +case 54: +YY_RULE_SETUP +#line 228 "cftoken.l" +{ YYD; return(LDAP_PORT); } + YY_BREAK +case 55: +YY_RULE_SETUP +#line 229 "cftoken.l" +{ YYD; return(LDAP_BASE); } + YY_BREAK +case 56: +YY_RULE_SETUP +#line 230 "cftoken.l" +{ YYD; return(LDAP_SUBTREE); } + YY_BREAK +case 57: +YY_RULE_SETUP +#line 231 "cftoken.l" +{ YYD; return(LDAP_BIND_DN); } + YY_BREAK +case 58: +YY_RULE_SETUP +#line 232 "cftoken.l" +{ YYD; return(LDAP_BIND_PW); } + YY_BREAK +case 59: +YY_RULE_SETUP +#line 233 "cftoken.l" +{ YYD; return(LDAP_ATTR_USER); } + YY_BREAK +case 60: +YY_RULE_SETUP +#line 234 "cftoken.l" +{ YYD; return(LDAP_ATTR_ADDR); } + YY_BREAK +case 61: +YY_RULE_SETUP +#line 235 "cftoken.l" +{ YYD; return(LDAP_ATTR_MASK); } + YY_BREAK +case 62: +YY_RULE_SETUP +#line 236 "cftoken.l" +{ YYD; return(LDAP_ATTR_GROUP); } + YY_BREAK +case 63: +YY_RULE_SETUP +#line 237 "cftoken.l" +{ YYD; return(LDAP_ATTR_MEMBER); } + YY_BREAK +case 64: +YY_RULE_SETUP +#line 238 "cftoken.l" +{ BEGIN S_INI; return(EOC); } + YY_BREAK +/* mode_cfg */ +case 65: +YY_RULE_SETUP +#line 241 "cftoken.l" +{ BEGIN S_CFG; YYDB; return(MODECFG); } + YY_BREAK +case 66: +YY_RULE_SETUP +#line 242 "cftoken.l" +{ return(BOC); } + YY_BREAK +case 67: +YY_RULE_SETUP +#line 243 "cftoken.l" +{ YYD; return(CFG_NET4); } + YY_BREAK +case 68: +YY_RULE_SETUP +#line 244 "cftoken.l" +{ YYD; return(CFG_MASK4); } + YY_BREAK +case 69: +YY_RULE_SETUP +#line 245 "cftoken.l" +{ YYD; return(CFG_DNS4); } + YY_BREAK +case 70: +YY_RULE_SETUP +#line 246 "cftoken.l" +{ YYD; return(CFG_NBNS4); } + YY_BREAK +case 71: +YY_RULE_SETUP +#line 247 "cftoken.l" +{ YYD; return(CFG_NBNS4); } + YY_BREAK +case 72: +YY_RULE_SETUP +#line 248 "cftoken.l" +{ YYD; return(CFG_DEFAULT_DOMAIN); } + YY_BREAK +case 73: +YY_RULE_SETUP +#line 249 "cftoken.l" +{ YYD; return(CFG_AUTH_SOURCE); } + YY_BREAK +case 74: +YY_RULE_SETUP +#line 250 "cftoken.l" +{ YYD; return(CFG_AUTH_GROUPS); } + YY_BREAK +case 75: +YY_RULE_SETUP +#line 251 "cftoken.l" +{ YYD; return(CFG_GROUP_SOURCE); } + YY_BREAK +case 76: +YY_RULE_SETUP +#line 252 "cftoken.l" +{ YYD; return(CFG_CONF_SOURCE); } + YY_BREAK +case 77: +YY_RULE_SETUP +#line 253 "cftoken.l" +{ YYD; return(CFG_ACCOUNTING); } + YY_BREAK +case 78: +YY_RULE_SETUP +#line 254 "cftoken.l" +{ YYD; return(CFG_SYSTEM); } + YY_BREAK +case 79: +YY_RULE_SETUP +#line 255 "cftoken.l" +{ YYD; return(CFG_LOCAL); } + YY_BREAK +case 80: +YY_RULE_SETUP +#line 256 "cftoken.l" +{ YYD; return(CFG_NONE); } + YY_BREAK +case 81: +YY_RULE_SETUP +#line 257 "cftoken.l" +{ YYD; return(CFG_RADIUS); } + YY_BREAK +case 82: +YY_RULE_SETUP +#line 258 "cftoken.l" +{ YYD; return(CFG_PAM); } + YY_BREAK +case 83: +YY_RULE_SETUP +#line 259 "cftoken.l" +{ YYD; return(CFG_LDAP); } + YY_BREAK +case 84: +YY_RULE_SETUP +#line 260 "cftoken.l" +{ YYD; return(CFG_POOL_SIZE); } + YY_BREAK +case 85: +YY_RULE_SETUP +#line 261 "cftoken.l" +{ YYD; return(CFG_MOTD); } + YY_BREAK +case 86: +YY_RULE_SETUP +#line 262 "cftoken.l" +{ YYD; return(CFG_AUTH_THROTTLE); } + YY_BREAK +case 87: +YY_RULE_SETUP +#line 263 "cftoken.l" +{ YYD; return(CFG_SPLIT_NETWORK); } + YY_BREAK +case 88: +YY_RULE_SETUP +#line 264 "cftoken.l" +{ YYD; return(CFG_SPLIT_LOCAL); } + YY_BREAK +case 89: +YY_RULE_SETUP +#line 265 "cftoken.l" +{ YYD; return(CFG_SPLIT_INCLUDE); } + YY_BREAK +case 90: +YY_RULE_SETUP +#line 266 "cftoken.l" +{ YYD; return(CFG_SPLIT_DNS); } + YY_BREAK +case 91: +YY_RULE_SETUP +#line 267 "cftoken.l" +{ YYD; return(CFG_PFS_GROUP); } + YY_BREAK +case 92: +YY_RULE_SETUP +#line 268 "cftoken.l" +{ YYD; return(CFG_SAVE_PASSWD); } + YY_BREAK +case 93: +YY_RULE_SETUP +#line 269 "cftoken.l" +{ YYD; return(COMMA); } + YY_BREAK +case 94: +YY_RULE_SETUP +#line 270 "cftoken.l" +{ BEGIN S_INI; return(EOC); } + YY_BREAK +/* timer */ +case 95: +YY_RULE_SETUP +#line 273 "cftoken.l" +{ BEGIN S_RTRY; YYDB; return(RETRY); } + YY_BREAK +case 96: +YY_RULE_SETUP +#line 274 "cftoken.l" +{ return(BOC); } + YY_BREAK +case 97: +YY_RULE_SETUP +#line 275 "cftoken.l" +{ YYD; return(RETRY_COUNTER); } + YY_BREAK +case 98: +YY_RULE_SETUP +#line 276 "cftoken.l" +{ YYD; return(RETRY_INTERVAL); } + YY_BREAK +case 99: +YY_RULE_SETUP +#line 277 "cftoken.l" +{ YYD; return(RETRY_PERSEND); } + YY_BREAK +case 100: +YY_RULE_SETUP +#line 278 "cftoken.l" +{ YYD; return(RETRY_PHASE1); } + YY_BREAK +case 101: +YY_RULE_SETUP +#line 279 "cftoken.l" +{ YYD; return(RETRY_PHASE2); } + YY_BREAK +case 102: +YY_RULE_SETUP +#line 280 "cftoken.l" +{ YYD; return(NATT_KA); } + YY_BREAK +case 103: +YY_RULE_SETUP +#line 281 "cftoken.l" +{ BEGIN S_INI; return(EOC); } + YY_BREAK +/* sainfo */ +case 104: +YY_RULE_SETUP +#line 284 "cftoken.l" +{ BEGIN S_SAINF; YYDB; return(SAINFO); } + YY_BREAK +case 105: +YY_RULE_SETUP +#line 285 "cftoken.l" +{ YYD; return(ANONYMOUS); } + YY_BREAK +case 106: +YY_RULE_SETUP +#line 286 "cftoken.l" +{ YYD; return(CLIENTADDR); } + YY_BREAK +case 107: +YY_RULE_SETUP +#line 287 "cftoken.l" +{ YYD; return(PORTANY); } + YY_BREAK +case 108: +YY_RULE_SETUP +#line 288 "cftoken.l" +{ YYD; return(ANY); } + YY_BREAK +case 109: +YY_RULE_SETUP +#line 289 "cftoken.l" +{ YYD; return(FROM); } + YY_BREAK +case 110: +YY_RULE_SETUP +#line 290 "cftoken.l" +{ YYD; return(GROUP); } + YY_BREAK +/* sainfo spec */ +case 111: +YY_RULE_SETUP +#line 292 "cftoken.l" +{ BEGIN S_SAINFS; return(BOC); } + YY_BREAK +case 112: +YY_RULE_SETUP +#line 293 "cftoken.l" +{ BEGIN S_INI; return(EOS); } + YY_BREAK +case 113: +YY_RULE_SETUP +#line 294 "cftoken.l" +{ BEGIN S_INI; return(EOC); } + YY_BREAK +case 114: +YY_RULE_SETUP +#line 295 "cftoken.l" +{ YYD; return(PFS_GROUP); } + YY_BREAK +case 115: +YY_RULE_SETUP +#line 296 "cftoken.l" +{ YYD; return(REMOTEID); } + YY_BREAK +case 116: +YY_RULE_SETUP +#line 297 "cftoken.l" +{ YYD; return(MY_IDENTIFIER); } + YY_BREAK +case 117: +YY_RULE_SETUP +#line 298 "cftoken.l" +{ YYD; return(LIFETIME); } + YY_BREAK +case 118: +YY_RULE_SETUP +#line 299 "cftoken.l" +{ YYD; return(LIFETYPE_TIME); } + YY_BREAK +case 119: +YY_RULE_SETUP +#line 300 "cftoken.l" +{ YYD; return(LIFETYPE_BYTE); } + YY_BREAK +case 120: +YY_RULE_SETUP +#line 301 "cftoken.l" +{ YYD; yylval.num = algclass_ipsec_enc; return(ALGORITHM_CLASS); } + YY_BREAK +case 121: +YY_RULE_SETUP +#line 302 "cftoken.l" +{ YYD; yylval.num = algclass_ipsec_auth; return(ALGORITHM_CLASS); } + YY_BREAK +case 122: +YY_RULE_SETUP +#line 303 "cftoken.l" +{ YYD; yylval.num = algclass_ipsec_comp; return(ALGORITHM_CLASS); } + YY_BREAK +case 123: +YY_RULE_SETUP +#line 304 "cftoken.l" +{ YYD; return(COMMA); } + YY_BREAK +/* remote */ +case 124: +YY_RULE_SETUP +#line 307 "cftoken.l" +{ BEGIN S_RMT; YYDB; return(REMOTE); } + YY_BREAK +case 125: +YY_RULE_SETUP +#line 308 "cftoken.l" +{ YYD; return(ANONYMOUS); } + YY_BREAK +case 126: +YY_RULE_SETUP +#line 309 "cftoken.l" +{ YYD; return(INHERIT); } + YY_BREAK +case 127: +YY_RULE_SETUP +#line 310 "cftoken.l" +{ BEGIN S_INI; YYDB; return(EOS); } + YY_BREAK +/* remote spec */ +case 128: +YY_RULE_SETUP +#line 312 "cftoken.l" +{ BEGIN S_RMTS; return(BOC); } + YY_BREAK +case 129: +YY_RULE_SETUP +#line 313 "cftoken.l" +{ BEGIN S_INI; return(EOC); } + YY_BREAK +case 130: +YY_RULE_SETUP +#line 314 "cftoken.l" +{ YYD; return(REMOTE_ADDRESS); } + YY_BREAK +case 131: +YY_RULE_SETUP +#line 315 "cftoken.l" +{ YYD; return(EXCHANGE_MODE); } + YY_BREAK +case 132: +YY_RULE_SETUP +#line 316 "cftoken.l" +{ YYD; /* XXX ignored, but to be handled. */ ; } + YY_BREAK +case 133: +YY_RULE_SETUP +#line 317 "cftoken.l" +{ YYD; yylval.num = ISAKMP_ETYPE_BASE; return(EXCHANGETYPE); } + YY_BREAK +case 134: +YY_RULE_SETUP +#line 318 "cftoken.l" +{ YYD; yylval.num = ISAKMP_ETYPE_IDENT; return(EXCHANGETYPE); } + YY_BREAK +case 135: +YY_RULE_SETUP +#line 319 "cftoken.l" +{ YYD; yylval.num = ISAKMP_ETYPE_AGG; return(EXCHANGETYPE); } + YY_BREAK +case 136: +YY_RULE_SETUP +#line 320 "cftoken.l" +{ YYD; return(DOI); } + YY_BREAK +case 137: +YY_RULE_SETUP +#line 321 "cftoken.l" +{ YYD; yylval.num = IPSEC_DOI; return(DOITYPE); } + YY_BREAK +case 138: +YY_RULE_SETUP +#line 322 "cftoken.l" +{ YYD; return(SITUATION); } + YY_BREAK +case 139: +YY_RULE_SETUP +#line 323 "cftoken.l" +{ YYD; yylval.num = IPSECDOI_SIT_IDENTITY_ONLY; return(SITUATIONTYPE); } + YY_BREAK +case 140: +YY_RULE_SETUP +#line 324 "cftoken.l" +{ YYD; yylval.num = IPSECDOI_SIT_SECRECY; return(SITUATIONTYPE); } + YY_BREAK +case 141: +YY_RULE_SETUP +#line 325 "cftoken.l" +{ YYD; yylval.num = IPSECDOI_SIT_INTEGRITY; return(SITUATIONTYPE); } + YY_BREAK +case 142: +YY_RULE_SETUP +#line 326 "cftoken.l" +{ YYD; return(MY_IDENTIFIER); } + YY_BREAK +case 143: +YY_RULE_SETUP +#line 327 "cftoken.l" +{ YYD; return(XAUTH_LOGIN); /* formerly identifier type login */ } + YY_BREAK +case 144: +YY_RULE_SETUP +#line 328 "cftoken.l" +{ YYD; return(PEERS_IDENTIFIER); } + YY_BREAK +case 145: +YY_RULE_SETUP +#line 329 "cftoken.l" +{ YYD; return(VERIFY_IDENTIFIER); } + YY_BREAK +case 146: +YY_RULE_SETUP +#line 330 "cftoken.l" +{ YYD; return(CERTIFICATE_TYPE); } + YY_BREAK +case 147: +YY_RULE_SETUP +#line 331 "cftoken.l" +{ YYD; return(CA_TYPE); } + YY_BREAK +case 148: +YY_RULE_SETUP +#line 332 "cftoken.l" +{ YYD; yylval.num = ISAKMP_CERT_X509SIGN; return(CERT_X509); } + YY_BREAK +case 149: +YY_RULE_SETUP +#line 333 "cftoken.l" +{ YYD; yylval.num = ISAKMP_CERT_PLAINRSA; return(CERT_PLAINRSA); } + YY_BREAK +case 150: +YY_RULE_SETUP +#line 334 "cftoken.l" +{ YYD; return(PEERS_CERTFILE); } + YY_BREAK +case 151: +YY_RULE_SETUP +#line 335 "cftoken.l" +{ YYD; return(DNSSEC); } + YY_BREAK +case 152: +YY_RULE_SETUP +#line 336 "cftoken.l" +{ YYD; return(VERIFY_CERT); } + YY_BREAK +case 153: +YY_RULE_SETUP +#line 337 "cftoken.l" +{ YYD; return(SEND_CERT); } + YY_BREAK +case 154: +YY_RULE_SETUP +#line 338 "cftoken.l" +{ YYD; return(SEND_CR); } + YY_BREAK +case 155: +YY_RULE_SETUP +#line 339 "cftoken.l" +{ YYD; return(MATCH_EMPTY_CR); } + YY_BREAK +case 156: +YY_RULE_SETUP +#line 340 "cftoken.l" +{ YYD; return(DH_GROUP); } + YY_BREAK +case 157: +YY_RULE_SETUP +#line 341 "cftoken.l" +{ YYD; return(NONCE_SIZE); } + YY_BREAK +case 158: +YY_RULE_SETUP +#line 342 "cftoken.l" +{ YYD; return(GENERATE_POLICY); } + YY_BREAK +case 159: +YY_RULE_SETUP +#line 343 "cftoken.l" +{ YYD; yylval.num = GENERATE_POLICY_UNIQUE; return(GENERATE_LEVEL); } + YY_BREAK +case 160: +YY_RULE_SETUP +#line 344 "cftoken.l" +{ YYD; yylval.num = GENERATE_POLICY_REQUIRE; return(GENERATE_LEVEL); } + YY_BREAK +case 161: +YY_RULE_SETUP +#line 345 "cftoken.l" +{ YYD; return(SUPPORT_PROXY); } + YY_BREAK +case 162: +YY_RULE_SETUP +#line 346 "cftoken.l" +{ YYD; return(INITIAL_CONTACT); } + YY_BREAK +case 163: +YY_RULE_SETUP +#line 347 "cftoken.l" +{ YYD; return(NAT_TRAVERSAL); } + YY_BREAK +case 164: +YY_RULE_SETUP +#line 348 "cftoken.l" +{ YYD; return(REMOTE_FORCE_LEVEL); } + YY_BREAK +case 165: +YY_RULE_SETUP +#line 349 "cftoken.l" +{ YYD; return(PROPOSAL_CHECK); } + YY_BREAK +case 166: +YY_RULE_SETUP +#line 350 "cftoken.l" +{ YYD; yylval.num = PROP_CHECK_OBEY; return(PROPOSAL_CHECK_LEVEL); } + YY_BREAK +case 167: +YY_RULE_SETUP +#line 351 "cftoken.l" +{ YYD; yylval.num = PROP_CHECK_STRICT; return(PROPOSAL_CHECK_LEVEL); } + YY_BREAK +case 168: +YY_RULE_SETUP +#line 352 "cftoken.l" +{ YYD; yylval.num = PROP_CHECK_EXACT; return(PROPOSAL_CHECK_LEVEL); } + YY_BREAK +case 169: +YY_RULE_SETUP +#line 353 "cftoken.l" +{ YYD; yylval.num = PROP_CHECK_CLAIM; return(PROPOSAL_CHECK_LEVEL); } + YY_BREAK +case 170: +YY_RULE_SETUP +#line 354 "cftoken.l" +{ YYD; return(KEEPALIVE); } + YY_BREAK +case 171: +YY_RULE_SETUP +#line 355 "cftoken.l" +{ YYD; return(PASSIVE); } + YY_BREAK +case 172: +YY_RULE_SETUP +#line 356 "cftoken.l" +{ YYD; return(LIFETIME); } + YY_BREAK +case 173: +YY_RULE_SETUP +#line 357 "cftoken.l" +{ YYD; return(LIFETYPE_TIME); } + YY_BREAK +case 174: +YY_RULE_SETUP +#line 358 "cftoken.l" +{ YYD; return(LIFETYPE_BYTE); } + YY_BREAK +case 175: +YY_RULE_SETUP +#line 359 "cftoken.l" +{ YYD; return(DPD); } + YY_BREAK +case 176: +YY_RULE_SETUP +#line 360 "cftoken.l" +{ YYD; return(DPD_DELAY); } + YY_BREAK +case 177: +YY_RULE_SETUP +#line 361 "cftoken.l" +{ YYD; return(DPD_RETRY); } + YY_BREAK +case 178: +YY_RULE_SETUP +#line 362 "cftoken.l" +{ YYD; return(DPD_MAXFAIL); } + YY_BREAK +case 179: +YY_RULE_SETUP +#line 363 "cftoken.l" +{ YYD; return(PH1ID); } + YY_BREAK +case 180: +YY_RULE_SETUP +#line 364 "cftoken.l" +{ YYD; return(IKE_FRAG); } + YY_BREAK +case 181: +YY_RULE_SETUP +#line 365 "cftoken.l" +{ YYD; return(ESP_FRAG); } + YY_BREAK +case 182: +YY_RULE_SETUP +#line 366 "cftoken.l" +{ YYD; return(SCRIPT); } + YY_BREAK +case 183: +YY_RULE_SETUP +#line 367 "cftoken.l" +{ YYD; return(PHASE1_UP); } + YY_BREAK +case 184: +YY_RULE_SETUP +#line 368 "cftoken.l" +{ YYD; return(PHASE1_DOWN); } + YY_BREAK +case 185: +YY_RULE_SETUP +#line 369 "cftoken.l" +{ YYD; return(PHASE1_DEAD); } + YY_BREAK +case 186: +YY_RULE_SETUP +#line 370 "cftoken.l" +{ YYD; return(MODE_CFG); } + YY_BREAK +case 187: +YY_RULE_SETUP +#line 371 "cftoken.l" +{ YYD; return(WEAK_PHASE1_CHECK); } + YY_BREAK +case 188: +YY_RULE_SETUP +#line 372 "cftoken.l" +{ YYD; return(REKEY); } + YY_BREAK +/* remote proposal */ +case 189: +YY_RULE_SETUP +#line 374 "cftoken.l" +{ BEGIN S_RMTP; YYDB; return(PROPOSAL); } + YY_BREAK +case 190: +YY_RULE_SETUP +#line 375 "cftoken.l" +{ return(BOC); } + YY_BREAK +case 191: +YY_RULE_SETUP +#line 376 "cftoken.l" +{ BEGIN S_RMTS; return(EOC); } + YY_BREAK +case 192: +YY_RULE_SETUP +#line 377 "cftoken.l" +{ YYD; return(LIFETIME); } + YY_BREAK +case 193: +YY_RULE_SETUP +#line 378 "cftoken.l" +{ YYD; return(LIFETYPE_TIME); } + YY_BREAK +case 194: +YY_RULE_SETUP +#line 379 "cftoken.l" +{ YYD; return(LIFETYPE_BYTE); } + YY_BREAK +case 195: +YY_RULE_SETUP +#line 380 "cftoken.l" +{ YYD; yylval.num = algclass_isakmp_enc; return(ALGORITHM_CLASS); } + YY_BREAK +case 196: +YY_RULE_SETUP +#line 381 "cftoken.l" +{ YYD; yylval.num = algclass_isakmp_ameth; return(ALGORITHM_CLASS); } + YY_BREAK +case 197: +YY_RULE_SETUP +#line 382 "cftoken.l" +{ YYD; yylval.num = algclass_isakmp_hash; return(ALGORITHM_CLASS); } + YY_BREAK +case 198: +YY_RULE_SETUP +#line 383 "cftoken.l" +{ YYD; return(DH_GROUP); } + YY_BREAK +case 199: +YY_RULE_SETUP +#line 384 "cftoken.l" +{ YYD; return(GSS_ID); } + YY_BREAK +case 200: +YY_RULE_SETUP +#line 385 "cftoken.l" +{ YYD; return(GSS_ID); } /* for back compatibility */ + YY_BREAK +/* GSS ID encoding type (global) */ +case 201: +YY_RULE_SETUP +#line 388 "cftoken.l" +{ BEGIN S_GSSENC; YYDB; return(GSS_ID_ENC); } + YY_BREAK +case 202: +YY_RULE_SETUP +#line 389 "cftoken.l" +{ YYD; yylval.num = LC_GSSENC_LATIN1; + return(GSS_ID_ENCTYPE); } + YY_BREAK +case 203: +YY_RULE_SETUP +#line 391 "cftoken.l" +{ YYD; yylval.num = LC_GSSENC_UTF16LE; + return(GSS_ID_ENCTYPE); } + YY_BREAK +case 204: +YY_RULE_SETUP +#line 393 "cftoken.l" +{ BEGIN S_INI; YYDB; return(EOS); } + YY_BREAK +/* parameter */ +case 205: +YY_RULE_SETUP +#line 396 "cftoken.l" +{ YYD; yylval.num = TRUE; return(SWITCH); } + YY_BREAK +case 206: +YY_RULE_SETUP +#line 397 "cftoken.l" +{ YYD; yylval.num = FALSE; return(SWITCH); } + YY_BREAK +/* prefix */ +case 207: +YY_RULE_SETUP +#line 400 "cftoken.l" +{ + YYD; + yytext++; + yylval.num = atoi(yytext); + return(PREFIX); + } + YY_BREAK +/* port number */ +case 208: +YY_RULE_SETUP +#line 408 "cftoken.l" +{ + char *p = yytext; + YYD; + while (*++p != ']') ; + *p = 0; + yytext++; + yylval.num = atoi(yytext); + return(PORT); + } + YY_BREAK +/* address range */ +case 209: +YY_RULE_SETUP +#line 419 "cftoken.l" +{ + YYD; + yytext++; + yylval.val = vmalloc(yyleng + 1); + if (yylval.val == NULL) { + yyerror("vmalloc failed"); + return -1; + } + memcpy(yylval.val->v, yytext, yylval.val->l); + return(ADDRRANGE); + } + YY_BREAK +/* upper protocol */ +case 210: +YY_RULE_SETUP +#line 432 "cftoken.l" +{ YYD; yylval.num = IPPROTO_ESP; return(UL_PROTO); } + YY_BREAK +case 211: +YY_RULE_SETUP +#line 433 "cftoken.l" +{ YYD; yylval.num = IPPROTO_AH; return(UL_PROTO); } + YY_BREAK +case 212: +YY_RULE_SETUP +#line 434 "cftoken.l" +{ YYD; yylval.num = IPPROTO_IPCOMP; return(UL_PROTO); } + YY_BREAK +case 213: +YY_RULE_SETUP +#line 435 "cftoken.l" +{ YYD; yylval.num = IPPROTO_ICMP; return(UL_PROTO); } + YY_BREAK +case 214: +YY_RULE_SETUP +#line 436 "cftoken.l" +{ YYD; yylval.num = IPPROTO_ICMPV6; return(UL_PROTO); } + YY_BREAK +case 215: +YY_RULE_SETUP +#line 437 "cftoken.l" +{ YYD; yylval.num = IPPROTO_TCP; return(UL_PROTO); } + YY_BREAK +case 216: +YY_RULE_SETUP +#line 438 "cftoken.l" +{ YYD; yylval.num = IPPROTO_UDP; return(UL_PROTO); } + YY_BREAK +case 217: +YY_RULE_SETUP +#line 439 "cftoken.l" +{ YYD; yylval.num = IPPROTO_GRE; return(UL_PROTO); } + YY_BREAK +/* algorithm type */ +case 218: +YY_RULE_SETUP +#line 442 "cftoken.l" +{ YYD; yylval.num = algtype_des_iv64; return(ALGORITHMTYPE); } + YY_BREAK +case 219: +YY_RULE_SETUP +#line 443 "cftoken.l" +{ YYD; yylval.num = algtype_des; return(ALGORITHMTYPE); } + YY_BREAK +case 220: +YY_RULE_SETUP +#line 444 "cftoken.l" +{ YYD; yylval.num = algtype_3des; return(ALGORITHMTYPE); } + YY_BREAK +case 221: +YY_RULE_SETUP +#line 445 "cftoken.l" +{ YYD; yylval.num = algtype_rc5; return(ALGORITHMTYPE); } + YY_BREAK +case 222: +YY_RULE_SETUP +#line 446 "cftoken.l" +{ YYD; yylval.num = algtype_idea; return(ALGORITHMTYPE); } + YY_BREAK +case 223: +YY_RULE_SETUP +#line 447 "cftoken.l" +{ YYD; yylval.num = algtype_cast128; return(ALGORITHMTYPE); } + YY_BREAK +case 224: +YY_RULE_SETUP +#line 448 "cftoken.l" +{ YYD; yylval.num = algtype_blowfish; return(ALGORITHMTYPE); } + YY_BREAK +case 225: +YY_RULE_SETUP +#line 449 "cftoken.l" +{ YYD; yylval.num = algtype_3idea; return(ALGORITHMTYPE); } + YY_BREAK +case 226: +YY_RULE_SETUP +#line 450 "cftoken.l" +{ YYD; yylval.num = algtype_des_iv32; return(ALGORITHMTYPE); } + YY_BREAK +case 227: +YY_RULE_SETUP +#line 451 "cftoken.l" +{ YYD; yylval.num = algtype_rc4; return(ALGORITHMTYPE); } + YY_BREAK +case 228: +YY_RULE_SETUP +#line 452 "cftoken.l" +{ YYD; yylval.num = algtype_null_enc; return(ALGORITHMTYPE); } + YY_BREAK +case 229: +YY_RULE_SETUP +#line 453 "cftoken.l" +{ YYD; yylval.num = algtype_null_enc; return(ALGORITHMTYPE); } + YY_BREAK +case 230: +YY_RULE_SETUP +#line 454 "cftoken.l" +{ YYD; yylval.num = algtype_aes; return(ALGORITHMTYPE); } + YY_BREAK +case 231: +YY_RULE_SETUP +#line 455 "cftoken.l" +{ YYD; yylval.num = algtype_aes; return(ALGORITHMTYPE); } + YY_BREAK +case 232: +YY_RULE_SETUP +#line 456 "cftoken.l" +{ YYD; yylval.num = algtype_twofish; return(ALGORITHMTYPE); } + YY_BREAK +case 233: +YY_RULE_SETUP +#line 457 "cftoken.l" +{ YYD; yylval.num = algtype_camellia; return(ALGORITHMTYPE); } + YY_BREAK +case 234: +YY_RULE_SETUP +#line 458 "cftoken.l" +{ YYD; yylval.num = algtype_non_auth; return(ALGORITHMTYPE); } + YY_BREAK +case 235: +YY_RULE_SETUP +#line 459 "cftoken.l" +{ YYD; yylval.num = algtype_hmac_md5; return(ALGORITHMTYPE); } + YY_BREAK +case 236: +YY_RULE_SETUP +#line 460 "cftoken.l" +{ YYD; yylval.num = algtype_hmac_sha1; return(ALGORITHMTYPE); } + YY_BREAK +case 237: +YY_RULE_SETUP +#line 461 "cftoken.l" +{ YYD; yylval.num = algtype_hmac_sha2_256; return(ALGORITHMTYPE); } + YY_BREAK +case 238: +YY_RULE_SETUP +#line 462 "cftoken.l" +{ YYD; yylval.num = algtype_hmac_sha2_256; return(ALGORITHMTYPE); } + YY_BREAK +case 239: +YY_RULE_SETUP +#line 463 "cftoken.l" +{ YYD; yylval.num = algtype_hmac_sha2_384; return(ALGORITHMTYPE); } + YY_BREAK +case 240: +YY_RULE_SETUP +#line 464 "cftoken.l" +{ YYD; yylval.num = algtype_hmac_sha2_384; return(ALGORITHMTYPE); } + YY_BREAK +case 241: +YY_RULE_SETUP +#line 465 "cftoken.l" +{ YYD; yylval.num = algtype_hmac_sha2_512; return(ALGORITHMTYPE); } + YY_BREAK +case 242: +YY_RULE_SETUP +#line 466 "cftoken.l" +{ YYD; yylval.num = algtype_hmac_sha2_512; return(ALGORITHMTYPE); } + YY_BREAK +case 243: +YY_RULE_SETUP +#line 467 "cftoken.l" +{ YYD; yylval.num = algtype_des_mac; return(ALGORITHMTYPE); } + YY_BREAK +case 244: +YY_RULE_SETUP +#line 468 "cftoken.l" +{ YYD; yylval.num = algtype_kpdk; return(ALGORITHMTYPE); } + YY_BREAK +case 245: +YY_RULE_SETUP +#line 469 "cftoken.l" +{ YYD; yylval.num = algtype_md5; return(ALGORITHMTYPE); } + YY_BREAK +case 246: +YY_RULE_SETUP +#line 470 "cftoken.l" +{ YYD; yylval.num = algtype_sha1; return(ALGORITHMTYPE); } + YY_BREAK +case 247: +YY_RULE_SETUP +#line 471 "cftoken.l" +{ YYD; yylval.num = algtype_tiger; return(ALGORITHMTYPE); } + YY_BREAK +case 248: +YY_RULE_SETUP +#line 472 "cftoken.l" +{ YYD; yylval.num = algtype_sha2_256; return(ALGORITHMTYPE); } + YY_BREAK +case 249: +YY_RULE_SETUP +#line 473 "cftoken.l" +{ YYD; yylval.num = algtype_sha2_256; return(ALGORITHMTYPE); } + YY_BREAK +case 250: +YY_RULE_SETUP +#line 474 "cftoken.l" +{ YYD; yylval.num = algtype_sha2_384; return(ALGORITHMTYPE); } + YY_BREAK +case 251: +YY_RULE_SETUP +#line 475 "cftoken.l" +{ YYD; yylval.num = algtype_sha2_384; return(ALGORITHMTYPE); } + YY_BREAK +case 252: +YY_RULE_SETUP +#line 476 "cftoken.l" +{ YYD; yylval.num = algtype_sha2_512; return(ALGORITHMTYPE); } + YY_BREAK +case 253: +YY_RULE_SETUP +#line 477 "cftoken.l" +{ YYD; yylval.num = algtype_sha2_512; return(ALGORITHMTYPE); } + YY_BREAK +case 254: +YY_RULE_SETUP +#line 478 "cftoken.l" +{ YYD; yylval.num = algtype_oui; return(ALGORITHMTYPE); } + YY_BREAK +case 255: +YY_RULE_SETUP +#line 479 "cftoken.l" +{ YYD; yylval.num = algtype_deflate; return(ALGORITHMTYPE); } + YY_BREAK +case 256: +YY_RULE_SETUP +#line 480 "cftoken.l" +{ YYD; yylval.num = algtype_lzs; return(ALGORITHMTYPE); } + YY_BREAK +case 257: +YY_RULE_SETUP +#line 481 "cftoken.l" +{ YYD; yylval.num = algtype_modp768; return(ALGORITHMTYPE); } + YY_BREAK +case 258: +YY_RULE_SETUP +#line 482 "cftoken.l" +{ YYD; yylval.num = algtype_modp1024; return(ALGORITHMTYPE); } + YY_BREAK +case 259: +YY_RULE_SETUP +#line 483 "cftoken.l" +{ YYD; yylval.num = algtype_modp1536; return(ALGORITHMTYPE); } + YY_BREAK +case 260: +YY_RULE_SETUP +#line 484 "cftoken.l" +{ YYD; yylval.num = algtype_ec2n155; return(ALGORITHMTYPE); } + YY_BREAK +case 261: +YY_RULE_SETUP +#line 485 "cftoken.l" +{ YYD; yylval.num = algtype_ec2n185; return(ALGORITHMTYPE); } + YY_BREAK +case 262: +YY_RULE_SETUP +#line 486 "cftoken.l" +{ YYD; yylval.num = algtype_modp2048; return(ALGORITHMTYPE); } + YY_BREAK +case 263: +YY_RULE_SETUP +#line 487 "cftoken.l" +{ YYD; yylval.num = algtype_modp3072; return(ALGORITHMTYPE); } + YY_BREAK +case 264: +YY_RULE_SETUP +#line 488 "cftoken.l" +{ YYD; yylval.num = algtype_modp4096; return(ALGORITHMTYPE); } + YY_BREAK +case 265: +YY_RULE_SETUP +#line 489 "cftoken.l" +{ YYD; yylval.num = algtype_modp6144; return(ALGORITHMTYPE); } + YY_BREAK +case 266: +YY_RULE_SETUP +#line 490 "cftoken.l" +{ YYD; yylval.num = algtype_modp8192; return(ALGORITHMTYPE); } + YY_BREAK +case 267: +YY_RULE_SETUP +#line 491 "cftoken.l" +{ YYD; yylval.num = algtype_psk; return(ALGORITHMTYPE); } + YY_BREAK +case 268: +YY_RULE_SETUP +#line 492 "cftoken.l" +{ YYD; yylval.num = algtype_rsasig; return(ALGORITHMTYPE); } + YY_BREAK +case 269: +YY_RULE_SETUP +#line 493 "cftoken.l" +{ YYD; yylval.num = algtype_dsssig; return(ALGORITHMTYPE); } + YY_BREAK +case 270: +YY_RULE_SETUP +#line 494 "cftoken.l" +{ YYD; yylval.num = algtype_rsaenc; return(ALGORITHMTYPE); } + YY_BREAK +case 271: +YY_RULE_SETUP +#line 495 "cftoken.l" +{ YYD; yylval.num = algtype_rsarev; return(ALGORITHMTYPE); } + YY_BREAK +case 272: +YY_RULE_SETUP +#line 496 "cftoken.l" +{ YYD; yylval.num = algtype_gssapikrb; return(ALGORITHMTYPE); } + YY_BREAK +case 273: +YY_RULE_SETUP +#line 497 "cftoken.l" +{ +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_hybrid_rsa_s; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} + YY_BREAK +case 274: +YY_RULE_SETUP +#line 504 "cftoken.l" +{ +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_hybrid_dss_s; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} + YY_BREAK +case 275: +YY_RULE_SETUP +#line 511 "cftoken.l" +{ +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_hybrid_rsa_c; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} + YY_BREAK +case 276: +YY_RULE_SETUP +#line 518 "cftoken.l" +{ +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_hybrid_dss_c; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} + YY_BREAK +case 277: +YY_RULE_SETUP +#line 525 "cftoken.l" +{ +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_xauth_psk_s; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} + YY_BREAK +case 278: +YY_RULE_SETUP +#line 532 "cftoken.l" +{ +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_xauth_psk_c; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} + YY_BREAK +case 279: +YY_RULE_SETUP +#line 539 "cftoken.l" +{ +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_xauth_rsa_s; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} + YY_BREAK +case 280: +YY_RULE_SETUP +#line 546 "cftoken.l" +{ +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_xauth_rsa_c; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} + YY_BREAK +/* identifier type */ +case 281: +YY_RULE_SETUP +#line 556 "cftoken.l" +{ YYD; yylval.num = IDTYPE_USERFQDN; return(IDENTIFIERTYPE); } + YY_BREAK +case 282: +YY_RULE_SETUP +#line 557 "cftoken.l" +{ YYD; yylval.num = IDTYPE_FQDN; return(IDENTIFIERTYPE); } + YY_BREAK +case 283: +YY_RULE_SETUP +#line 558 "cftoken.l" +{ YYD; yylval.num = IDTYPE_KEYID; return(IDENTIFIERTYPE); } + YY_BREAK +case 284: +YY_RULE_SETUP +#line 559 "cftoken.l" +{ YYD; yylval.num = IDTYPE_ADDRESS; return(IDENTIFIERTYPE); } + YY_BREAK +case 285: +YY_RULE_SETUP +#line 560 "cftoken.l" +{ YYD; yylval.num = IDTYPE_SUBNET; return(IDENTIFIERTYPE); } + YY_BREAK +case 286: +YY_RULE_SETUP +#line 561 "cftoken.l" +{ YYD; yylval.num = IDTYPE_ASN1DN; return(IDENTIFIERTYPE); } + YY_BREAK +/* identifier qualifier */ +case 287: +YY_RULE_SETUP +#line 564 "cftoken.l" +{ YYD; yylval.num = IDQUAL_TAG; return(IDENTIFIERQUAL); } + YY_BREAK +case 288: +YY_RULE_SETUP +#line 565 "cftoken.l" +{ YYD; yylval.num = IDQUAL_FILE; return(IDENTIFIERQUAL); } + YY_BREAK +/* units */ +case 289: +YY_RULE_SETUP +#line 568 "cftoken.l" +{ YYD; return(UNITTYPE_BYTE); } + YY_BREAK +case 290: +YY_RULE_SETUP +#line 569 "cftoken.l" +{ YYD; return(UNITTYPE_KBYTES); } + YY_BREAK +case 291: +YY_RULE_SETUP +#line 570 "cftoken.l" +{ YYD; return(UNITTYPE_MBYTES); } + YY_BREAK +case 292: +YY_RULE_SETUP +#line 571 "cftoken.l" +{ YYD; return(UNITTYPE_TBYTES); } + YY_BREAK +case 293: +YY_RULE_SETUP +#line 572 "cftoken.l" +{ YYD; return(UNITTYPE_SEC); } + YY_BREAK +case 294: +YY_RULE_SETUP +#line 573 "cftoken.l" +{ YYD; return(UNITTYPE_MIN); } + YY_BREAK +case 295: +YY_RULE_SETUP +#line 574 "cftoken.l" +{ YYD; return(UNITTYPE_HOUR); } + YY_BREAK +/* boolean */ +case 296: +YY_RULE_SETUP +#line 577 "cftoken.l" +{ YYD; yylval.num = TRUE; return(BOOLEAN); } + YY_BREAK +case 297: +YY_RULE_SETUP +#line 578 "cftoken.l" +{ YYD; yylval.num = FALSE; return(BOOLEAN); } + YY_BREAK +case 298: +YY_RULE_SETUP +#line 580 "cftoken.l" +{ + char *bp; + + YYD; + yylval.num = strtoul(yytext, &bp, 10); + return(NUMBER); + } + YY_BREAK +case 299: +YY_RULE_SETUP +#line 588 "cftoken.l" +{ + char *p; + + YYD; + yylval.val = vmalloc(yyleng + (yyleng & 1) + 1); + if (yylval.val == NULL) { + yyerror("vmalloc failed"); + return -1; + } + + p = yylval.val->v; + *p++ = '0'; + *p++ = 'x'; + + /* fixed string if length is odd. */ + if (yyleng & 1) + *p++ = '0'; + memcpy(p, &yytext[2], yyleng - 1); + + return(HEXSTRING); + } + YY_BREAK +case 300: +/* rule 300 can match eol */ +YY_RULE_SETUP +#line 610 "cftoken.l" +{ + char *p = yytext; + + YYD; + while (*++p != '"') ; + *p = '\0'; + + yylval.val = vmalloc(yyleng - 1); + if (yylval.val == NULL) { + yyerror("vmalloc failed"); + return -1; + } + memcpy(yylval.val->v, &yytext[1], yylval.val->l); + + return(QUOTEDSTRING); + } + YY_BREAK +case 301: +YY_RULE_SETUP +#line 627 "cftoken.l" +{ + YYD; + + yylval.val = vmalloc(yyleng + 1); + if (yylval.val == NULL) { + yyerror("vmalloc failed"); + return -1; + } + memcpy(yylval.val->v, yytext, yylval.val->l); + + return(ADDRSTRING); + } + YY_BREAK +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(S_INI): +case YY_STATE_EOF(S_PRIV): +case YY_STATE_EOF(S_PTH): +case YY_STATE_EOF(S_LOG): +case YY_STATE_EOF(S_PAD): +case YY_STATE_EOF(S_LST): +case YY_STATE_EOF(S_RTRY): +case YY_STATE_EOF(S_CFG): +case YY_STATE_EOF(S_LDAP): +case YY_STATE_EOF(S_RAD): +case YY_STATE_EOF(S_ALGST): +case YY_STATE_EOF(S_ALGCL): +case YY_STATE_EOF(S_SAINF): +case YY_STATE_EOF(S_SAINFS): +case YY_STATE_EOF(S_RMT): +case YY_STATE_EOF(S_RMTS): +case YY_STATE_EOF(S_RMTP): +case YY_STATE_EOF(S_SA): +case YY_STATE_EOF(S_GSSENC): +#line 640 "cftoken.l" +{ + yy_delete_buffer(YY_CURRENT_BUFFER); + fclose (incstack[incstackp].fp); + incstack[incstackp].fp = NULL; + racoon_free(incstack[incstackp].path); + incstack[incstackp].path = NULL; + incstackp--; + nextfile: + if (incstack[incstackp].matchon < + incstack[incstackp].matches.gl_pathc) { + char* filepath = incstack[incstackp].matches.gl_pathv[incstack[incstackp].matchon]; + incstack[incstackp].matchon++; + incstackp++; + if (yycf_set_buffer(filepath) != 0) { + incstackp--; + goto nextfile; + } + yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE)); + BEGIN(S_INI); + } else { + globfree(&incstack[incstackp].matches); + if (incstackp == 0) + yyterminate(); + else + yy_switch_to_buffer(incstack[incstackp].prevstate); + } + } + YY_BREAK +/* ... */ +case 302: +YY_RULE_SETUP +#line 669 "cftoken.l" +{ ; } + YY_BREAK +case 303: +/* rule 303 can match eol */ +YY_RULE_SETUP +#line 670 "cftoken.l" +{ incstack[incstackp].lineno++; } + YY_BREAK +case 304: +YY_RULE_SETUP +#line 671 "cftoken.l" +{ YYD; } + YY_BREAK +case 305: +YY_RULE_SETUP +#line 672 "cftoken.l" +{ return(EOS); } + YY_BREAK +case 306: +YY_RULE_SETUP +#line 673 "cftoken.l" +{ yymore(); } + YY_BREAK +case 307: +YY_RULE_SETUP +#line 675 "cftoken.l" +ECHO; + YY_BREAK +#line 3710 "cftoken.c" + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1820 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1820 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 1819); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register yy_size_t number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +yy_size_t yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} + +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 675 "cftoken.l" + + + +void +yyerror(char *s, ...) +{ + char fmt[512]; + + va_list ap; +#ifdef HAVE_STDARG_H + va_start(ap, s); +#else + va_start(ap); +#endif + snprintf(fmt, sizeof(fmt), "%s:%d: \"%s\" %s\n", + incstack[incstackp].path, incstack[incstackp].lineno, + yytext, s); + plogv(LLV_ERROR, LOCATION, NULL, fmt, ap); + va_end(ap); + + yyerrorcount++; +} + +void +yywarn(char *s, ...) +{ + char fmt[512]; + + va_list ap; +#ifdef HAVE_STDARG_H + va_start(ap, s); +#else + va_start(ap); +#endif + snprintf(fmt, sizeof(fmt), "%s:%d: \"%s\" %s\n", + incstack[incstackp].path, incstack[incstackp].lineno, + yytext, s); + plogv(LLV_WARNING, LOCATION, NULL, fmt, ap); + va_end(ap); +} + +int +yycf_switch_buffer(path) + char *path; +{ + char *filepath = NULL; + + /* got the include file name */ + if (incstackp >= MAX_INCLUDE_DEPTH) { + plog(LLV_ERROR, LOCATION, NULL, + "Includes nested too deeply"); + return -1; + } + + if (glob(path, GLOB_TILDE, NULL, &incstack[incstackp].matches) != 0 || + incstack[incstackp].matches.gl_pathc == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "glob found no matches for path \"%s\"\n", path); + return -1; + } + incstack[incstackp].matchon = 0; + incstack[incstackp].prevstate = YY_CURRENT_BUFFER; + + nextmatch: + if (incstack[incstackp].matchon >= incstack[incstackp].matches.gl_pathc) + return -1; + filepath = + incstack[incstackp].matches.gl_pathv[incstack[incstackp].matchon]; + incstack[incstackp].matchon++; + incstackp++; + + if (yycf_set_buffer(filepath) != 0) { + incstackp--; + goto nextmatch; + } + + yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE)); + + BEGIN(S_INI); + + return 0; +} + +int +yycf_set_buffer(path) + char *path; +{ + yyin = fopen(path, "r"); + if (yyin == NULL) { + fprintf(stderr, "failed to open file %s (%s)\n", + path, strerror(errno)); + plog(LLV_ERROR, LOCATION, NULL, + "failed to open file %s (%s)\n", + path, strerror(errno)); + return -1; + } + + /* initialize */ + incstack[incstackp].fp = yyin; + if (incstack[incstackp].path != NULL) + racoon_free(incstack[incstackp].path); + incstack[incstackp].path = racoon_strdup(path); + STRDUP_FATAL(incstack[incstackp].path); + incstack[incstackp].lineno = 1; + plog(LLV_DEBUG, LOCATION, NULL, + "reading config file %s\n", path); + + return 0; +} + +void +yycf_init_buffer() +{ + int i; + + for (i = 0; i < MAX_INCLUDE_DEPTH; i++) + memset(&incstack[i], 0, sizeof(incstack[i])); + incstackp = 0; +} + +void +yycf_clean_buffer() +{ + int i; + + for (i = 0; i < MAX_INCLUDE_DEPTH; i++) { + if (incstack[i].path != NULL) { + fclose(incstack[i].fp); + racoon_free(incstack[i].path); + incstack[i].path = NULL; + } + } +} + + diff --git a/ipsec-tools/src/racoon/cftoken.l b/ipsec-tools/src/racoon/cftoken.l new file mode 100644 index 00000000..490242c4 --- /dev/null +++ b/ipsec-tools/src/racoon/cftoken.l @@ -0,0 +1,807 @@ +/* $NetBSD: cftoken.l,v 1.23.2.1 2012/08/29 08:42:24 tteras Exp $ */ + +/* Id: cftoken.l,v 1.53 2006/08/22 18:17:17 manubsd Exp */ + +%{ +/* + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 and 2003 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_STDARG_H +#include +#else +#include +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "debug.h" + +#include "algorithm.h" +#include "cfparse_proto.h" +#include "cftoken_proto.h" +#include "localconf.h" +#include "oakley.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "ipsec_doi.h" +#include "policy.h" +#include "proposal.h" +#include "remoteconf.h" +#ifdef GC +#include "gcmalloc.h" +#endif + +#include "cfparse.h" + +int yyerrorcount = 0; + +#if defined(YIPS_DEBUG) +# define YYDB plog(LLV_DEBUG2, LOCATION, NULL, \ + "begin <%d>%s\n", yy_start, yytext); +# define YYD { \ + plog(LLV_DEBUG2, LOCATION, NULL, "<%d>%s", \ + yy_start, loglevel >= LLV_DEBUG2 ? "\n" : ""); \ +} +#else +# define YYDB +# define YYD +#endif /* defined(YIPS_DEBUG) */ + +#define MAX_INCLUDE_DEPTH 10 + +static struct include_stack { + char *path; + FILE *fp; + YY_BUFFER_STATE prevstate; + int lineno; + glob_t matches; + int matchon; +} incstack[MAX_INCLUDE_DEPTH]; +static int incstackp = 0; + +static int yy_first_time = 1; +%} + +/* common seciton */ +nl \n +ws [ \t]+ +digit [0-9] +letter [A-Za-z] +hexdigit [0-9A-Fa-f] +/*octet (([01]?{digit}?{digit})|((2([0-4]{digit}))|(25[0-5]))) */ +special [()+\|\?\*] +comma \, +dot \. +slash \/ +bcl \{ +ecl \} +blcl \[ +elcl \] +hyphen \- +percent \% +semi \; +comment \#.* +ccomment "/*" +bracketstring \<[^>]*\> +quotedstring \"[^"]*\" +addrstring [a-fA-F0-9:]([a-fA-F0-9:\.]*|[a-fA-F0-9:\.]*%[a-zA-Z0-9]*) +decstring {digit}+ +hexstring 0x{hexdigit}+ + +%s S_INI S_PRIV S_PTH S_LOG S_PAD S_LST S_RTRY S_CFG S_LDAP S_RAD +%s S_ALGST S_ALGCL +%s S_SAINF S_SAINFS +%s S_RMT S_RMTS S_RMTP +%s S_SA +%s S_GSSENC + +%% +%{ + if (yy_first_time) { + BEGIN S_INI; + yy_first_time = 0; + } +%} + + /* privsep */ +privsep { BEGIN S_PRIV; YYDB; return(PRIVSEP); } +{bcl} { return(BOC); } +user { YYD; return(USER); } +group { YYD; return(GROUP); } +chroot { YYD; return(CHROOT); } +{ecl} { BEGIN S_INI; return(EOC); } + + /* path */ +path { BEGIN S_PTH; YYDB; return(PATH); } +include { YYD; yylval.num = LC_PATHTYPE_INCLUDE; + return(PATHTYPE); } +pre_shared_key { YYD; yylval.num = LC_PATHTYPE_PSK; + return(PATHTYPE); } +certificate { YYD; yylval.num = LC_PATHTYPE_CERT; + return(PATHTYPE); } +script { YYD; yylval.num = LC_PATHTYPE_SCRIPT; + return(PATHTYPE); } +backupsa { YYD; yylval.num = LC_PATHTYPE_BACKUPSA; + return(PATHTYPE); } +pidfile { YYD; yylval.num = LC_PATHTYPE_PIDFILE; + return(PATHTYPE); } +{semi} { BEGIN S_INI; YYDB; return(EOS); } + + /* include */ +include { YYDB; return(INCLUDE); } + + /* pfkey_buffer */ +pfkey_buffer { YYDB; return(PFKEY_BUFFER); } + + /* special */ +complex_bundle { YYDB; return(COMPLEX_BUNDLE); } + + /* logging */ +log { BEGIN S_LOG; YYDB; return(LOGGING); } +error { YYD; yylval.num = LLV_ERROR; return(LOGLEV); } +warning { YYD; yylval.num = LLV_WARNING; return(LOGLEV); } +notify { YYD; yylval.num = LLV_NOTIFY; return(LOGLEV); } +info { YYD; yylval.num = LLV_INFO; return(LOGLEV); } +debug { YYD; yylval.num = LLV_DEBUG; return(LOGLEV); } +debug2 { YYD; yylval.num = LLV_DEBUG2; return(LOGLEV); } +{semi} { BEGIN S_INI; return(EOS); } + + /* padding */ +padding { BEGIN S_PAD; YYDB; return(PADDING); } +{bcl} { return(BOC); } +randomize { YYD; return(PAD_RANDOMIZE); } +randomize_length { YYD; return(PAD_RANDOMIZELEN); } +maximum_length { YYD; return(PAD_MAXLEN); } +strict_check { YYD; return(PAD_STRICT); } +exclusive_tail { YYD; return(PAD_EXCLTAIL); } +{ecl} { BEGIN S_INI; return(EOC); } + + /* listen */ +listen { BEGIN S_LST; YYDB; return(LISTEN); } +{bcl} { return(BOC); } +isakmp { YYD; return(X_ISAKMP); } +isakmp_natt { YYD; return(X_ISAKMP_NATT); } +admin { YYD; return(X_ADMIN); } +adminsock { YYD; return(ADMINSOCK); } +disabled { YYD; return(DISABLED); } +strict_address { YYD; return(STRICT_ADDRESS); } +{ecl} { BEGIN S_INI; return(EOC); } + + /* radius config */ +radiuscfg { BEGIN S_RAD; YYDB; return(RADCFG); } +{bcl} { return(BOC); } +auth { YYD; return(RAD_AUTH); } +acct { YYD; return(RAD_ACCT); } +timeout { YYD; return(RAD_TIMEOUT); } +retries { YYD; return(RAD_RETRIES); } +{ecl} { BEGIN S_INI; return(EOC); } + + /* ldap config */ +ldapcfg { BEGIN S_LDAP; YYDB; return(LDAPCFG); } +{bcl} { return(BOC); } +version { YYD; return(LDAP_PVER); } +host { YYD; return(LDAP_HOST); } +port { YYD; return(LDAP_PORT); } +base { YYD; return(LDAP_BASE); } +subtree { YYD; return(LDAP_SUBTREE); } +bind_dn { YYD; return(LDAP_BIND_DN); } +bind_pw { YYD; return(LDAP_BIND_PW); } +attr_user { YYD; return(LDAP_ATTR_USER); } +attr_addr { YYD; return(LDAP_ATTR_ADDR); } +attr_mask { YYD; return(LDAP_ATTR_MASK); } +attr_group { YYD; return(LDAP_ATTR_GROUP); } +attr_member { YYD; return(LDAP_ATTR_MEMBER); } +{ecl} { BEGIN S_INI; return(EOC); } + + /* mode_cfg */ +mode_cfg { BEGIN S_CFG; YYDB; return(MODECFG); } +{bcl} { return(BOC); } +network4 { YYD; return(CFG_NET4); } +netmask4 { YYD; return(CFG_MASK4); } +dns4 { YYD; return(CFG_DNS4); } +nbns4 { YYD; return(CFG_NBNS4); } +wins4 { YYD; return(CFG_NBNS4); } +default_domain { YYD; return(CFG_DEFAULT_DOMAIN); } +auth_source { YYD; return(CFG_AUTH_SOURCE); } +auth_groups { YYD; return(CFG_AUTH_GROUPS); } +group_source { YYD; return(CFG_GROUP_SOURCE); } +conf_source { YYD; return(CFG_CONF_SOURCE); } +accounting { YYD; return(CFG_ACCOUNTING); } +system { YYD; return(CFG_SYSTEM); } +local { YYD; return(CFG_LOCAL); } +none { YYD; return(CFG_NONE); } +radius { YYD; return(CFG_RADIUS); } +pam { YYD; return(CFG_PAM); } +ldap { YYD; return(CFG_LDAP); } +pool_size { YYD; return(CFG_POOL_SIZE); } +banner { YYD; return(CFG_MOTD); } +auth_throttle { YYD; return(CFG_AUTH_THROTTLE); } +split_network { YYD; return(CFG_SPLIT_NETWORK); } +local_lan { YYD; return(CFG_SPLIT_LOCAL); } +include { YYD; return(CFG_SPLIT_INCLUDE); } +split_dns { YYD; return(CFG_SPLIT_DNS); } +pfs_group { YYD; return(CFG_PFS_GROUP); } +save_passwd { YYD; return(CFG_SAVE_PASSWD); } +{comma} { YYD; return(COMMA); } +{ecl} { BEGIN S_INI; return(EOC); } + + /* timer */ +timer { BEGIN S_RTRY; YYDB; return(RETRY); } +{bcl} { return(BOC); } +counter { YYD; return(RETRY_COUNTER); } +interval { YYD; return(RETRY_INTERVAL); } +persend { YYD; return(RETRY_PERSEND); } +phase1 { YYD; return(RETRY_PHASE1); } +phase2 { YYD; return(RETRY_PHASE2); } +natt_keepalive { YYD; return(NATT_KA); } +{ecl} { BEGIN S_INI; return(EOC); } + + /* sainfo */ +sainfo { BEGIN S_SAINF; YYDB; return(SAINFO); } +anonymous { YYD; return(ANONYMOUS); } +clientaddr { YYD; return(CLIENTADDR); } +{blcl}any{elcl} { YYD; return(PORTANY); } +any { YYD; return(ANY); } +from { YYD; return(FROM); } +group { YYD; return(GROUP); } + /* sainfo spec */ +{bcl} { BEGIN S_SAINFS; return(BOC); } +{semi} { BEGIN S_INI; return(EOS); } +{ecl} { BEGIN S_INI; return(EOC); } +pfs_group { YYD; return(PFS_GROUP); } +remoteid { YYD; return(REMOTEID); } +my_identifier { YYD; return(MY_IDENTIFIER); } +lifetime { YYD; return(LIFETIME); } +time { YYD; return(LIFETYPE_TIME); } +byte { YYD; return(LIFETYPE_BYTE); } +encryption_algorithm { YYD; yylval.num = algclass_ipsec_enc; return(ALGORITHM_CLASS); } +authentication_algorithm { YYD; yylval.num = algclass_ipsec_auth; return(ALGORITHM_CLASS); } +compression_algorithm { YYD; yylval.num = algclass_ipsec_comp; return(ALGORITHM_CLASS); } +{comma} { YYD; return(COMMA); } + + /* remote */ +remote { BEGIN S_RMT; YYDB; return(REMOTE); } +anonymous { YYD; return(ANONYMOUS); } +inherit { YYD; return(INHERIT); } +{semi} { BEGIN S_INI; YYDB; return(EOS); } + /* remote spec */ +{bcl} { BEGIN S_RMTS; return(BOC); } +{ecl} { BEGIN S_INI; return(EOC); } +remote_address { YYD; return(REMOTE_ADDRESS); } +exchange_mode { YYD; return(EXCHANGE_MODE); } +{comma} { YYD; /* XXX ignored, but to be handled. */ ; } +base { YYD; yylval.num = ISAKMP_ETYPE_BASE; return(EXCHANGETYPE); } +main { YYD; yylval.num = ISAKMP_ETYPE_IDENT; return(EXCHANGETYPE); } +aggressive { YYD; yylval.num = ISAKMP_ETYPE_AGG; return(EXCHANGETYPE); } +doi { YYD; return(DOI); } +ipsec_doi { YYD; yylval.num = IPSEC_DOI; return(DOITYPE); } +situation { YYD; return(SITUATION); } +identity_only { YYD; yylval.num = IPSECDOI_SIT_IDENTITY_ONLY; return(SITUATIONTYPE); } +secrecy { YYD; yylval.num = IPSECDOI_SIT_SECRECY; return(SITUATIONTYPE); } +integrity { YYD; yylval.num = IPSECDOI_SIT_INTEGRITY; return(SITUATIONTYPE); } +my_identifier { YYD; return(MY_IDENTIFIER); } +xauth_login { YYD; return(XAUTH_LOGIN); /* formerly identifier type login */ } +peers_identifier { YYD; return(PEERS_IDENTIFIER); } +verify_identifier { YYD; return(VERIFY_IDENTIFIER); } +certificate_type { YYD; return(CERTIFICATE_TYPE); } +ca_type { YYD; return(CA_TYPE); } +x509 { YYD; yylval.num = ISAKMP_CERT_X509SIGN; return(CERT_X509); } +plain_rsa { YYD; yylval.num = ISAKMP_CERT_PLAINRSA; return(CERT_PLAINRSA); } +peers_certfile { YYD; return(PEERS_CERTFILE); } +dnssec { YYD; return(DNSSEC); } +verify_cert { YYD; return(VERIFY_CERT); } +send_cert { YYD; return(SEND_CERT); } +send_cr { YYD; return(SEND_CR); } +match_empty_cr { YYD; return(MATCH_EMPTY_CR); } +dh_group { YYD; return(DH_GROUP); } +nonce_size { YYD; return(NONCE_SIZE); } +generate_policy { YYD; return(GENERATE_POLICY); } +unique { YYD; yylval.num = GENERATE_POLICY_UNIQUE; return(GENERATE_LEVEL); } +require { YYD; yylval.num = GENERATE_POLICY_REQUIRE; return(GENERATE_LEVEL); } +support_proxy { YYD; return(SUPPORT_PROXY); } +initial_contact { YYD; return(INITIAL_CONTACT); } +nat_traversal { YYD; return(NAT_TRAVERSAL); } +force { YYD; return(REMOTE_FORCE_LEVEL); } +proposal_check { YYD; return(PROPOSAL_CHECK); } +obey { YYD; yylval.num = PROP_CHECK_OBEY; return(PROPOSAL_CHECK_LEVEL); } +strict { YYD; yylval.num = PROP_CHECK_STRICT; return(PROPOSAL_CHECK_LEVEL); } +exact { YYD; yylval.num = PROP_CHECK_EXACT; return(PROPOSAL_CHECK_LEVEL); } +claim { YYD; yylval.num = PROP_CHECK_CLAIM; return(PROPOSAL_CHECK_LEVEL); } +keepalive { YYD; return(KEEPALIVE); } +passive { YYD; return(PASSIVE); } +lifetime { YYD; return(LIFETIME); } +time { YYD; return(LIFETYPE_TIME); } +byte { YYD; return(LIFETYPE_BYTE); } +dpd { YYD; return(DPD); } +dpd_delay { YYD; return(DPD_DELAY); } +dpd_retry { YYD; return(DPD_RETRY); } +dpd_maxfail { YYD; return(DPD_MAXFAIL); } +ph1id { YYD; return(PH1ID); } +ike_frag { YYD; return(IKE_FRAG); } +esp_frag { YYD; return(ESP_FRAG); } +script { YYD; return(SCRIPT); } +phase1_up { YYD; return(PHASE1_UP); } +phase1_down { YYD; return(PHASE1_DOWN); } +phase1_dead { YYD; return(PHASE1_DEAD); } +mode_cfg { YYD; return(MODE_CFG); } +weak_phase1_check { YYD; return(WEAK_PHASE1_CHECK); } +rekey { YYD; return(REKEY); } + /* remote proposal */ +proposal { BEGIN S_RMTP; YYDB; return(PROPOSAL); } +{bcl} { return(BOC); } +{ecl} { BEGIN S_RMTS; return(EOC); } +lifetime { YYD; return(LIFETIME); } +time { YYD; return(LIFETYPE_TIME); } +byte { YYD; return(LIFETYPE_BYTE); } +encryption_algorithm { YYD; yylval.num = algclass_isakmp_enc; return(ALGORITHM_CLASS); } +authentication_method { YYD; yylval.num = algclass_isakmp_ameth; return(ALGORITHM_CLASS); } +hash_algorithm { YYD; yylval.num = algclass_isakmp_hash; return(ALGORITHM_CLASS); } +dh_group { YYD; return(DH_GROUP); } +gss_id { YYD; return(GSS_ID); } +gssapi_id { YYD; return(GSS_ID); } /* for back compatibility */ + + /* GSS ID encoding type (global) */ +gss_id_enc { BEGIN S_GSSENC; YYDB; return(GSS_ID_ENC); } +latin1 { YYD; yylval.num = LC_GSSENC_LATIN1; + return(GSS_ID_ENCTYPE); } +utf-16le { YYD; yylval.num = LC_GSSENC_UTF16LE; + return(GSS_ID_ENCTYPE); } +{semi} { BEGIN S_INI; YYDB; return(EOS); } + + /* parameter */ +on { YYD; yylval.num = TRUE; return(SWITCH); } +off { YYD; yylval.num = FALSE; return(SWITCH); } + + /* prefix */ +{slash}{digit}{1,3} { + YYD; + yytext++; + yylval.num = atoi(yytext); + return(PREFIX); + } + + /* port number */ +{blcl}{decstring}{elcl} { + char *p = yytext; + YYD; + while (*++p != ']') ; + *p = 0; + yytext++; + yylval.num = atoi(yytext); + return(PORT); + } + + /* address range */ +{hyphen}{addrstring} { + YYD; + yytext++; + yylval.val = vmalloc(yyleng + 1); + if (yylval.val == NULL) { + yyerror("vmalloc failed"); + return -1; + } + memcpy(yylval.val->v, yytext, yylval.val->l); + return(ADDRRANGE); + } + + /* upper protocol */ +esp { YYD; yylval.num = IPPROTO_ESP; return(UL_PROTO); } +ah { YYD; yylval.num = IPPROTO_AH; return(UL_PROTO); } +ipcomp { YYD; yylval.num = IPPROTO_IPCOMP; return(UL_PROTO); } +icmp { YYD; yylval.num = IPPROTO_ICMP; return(UL_PROTO); } +icmp6 { YYD; yylval.num = IPPROTO_ICMPV6; return(UL_PROTO); } +tcp { YYD; yylval.num = IPPROTO_TCP; return(UL_PROTO); } +udp { YYD; yylval.num = IPPROTO_UDP; return(UL_PROTO); } +gre { YYD; yylval.num = IPPROTO_GRE; return(UL_PROTO); } + + /* algorithm type */ +des_iv64 { YYD; yylval.num = algtype_des_iv64; return(ALGORITHMTYPE); } +des { YYD; yylval.num = algtype_des; return(ALGORITHMTYPE); } +3des { YYD; yylval.num = algtype_3des; return(ALGORITHMTYPE); } +rc5 { YYD; yylval.num = algtype_rc5; return(ALGORITHMTYPE); } +idea { YYD; yylval.num = algtype_idea; return(ALGORITHMTYPE); } +cast128 { YYD; yylval.num = algtype_cast128; return(ALGORITHMTYPE); } +blowfish { YYD; yylval.num = algtype_blowfish; return(ALGORITHMTYPE); } +3idea { YYD; yylval.num = algtype_3idea; return(ALGORITHMTYPE); } +des_iv32 { YYD; yylval.num = algtype_des_iv32; return(ALGORITHMTYPE); } +rc4 { YYD; yylval.num = algtype_rc4; return(ALGORITHMTYPE); } +null_enc { YYD; yylval.num = algtype_null_enc; return(ALGORITHMTYPE); } +null { YYD; yylval.num = algtype_null_enc; return(ALGORITHMTYPE); } +aes { YYD; yylval.num = algtype_aes; return(ALGORITHMTYPE); } +rijndael { YYD; yylval.num = algtype_aes; return(ALGORITHMTYPE); } +twofish { YYD; yylval.num = algtype_twofish; return(ALGORITHMTYPE); } +camellia { YYD; yylval.num = algtype_camellia; return(ALGORITHMTYPE); } +non_auth { YYD; yylval.num = algtype_non_auth; return(ALGORITHMTYPE); } +hmac_md5 { YYD; yylval.num = algtype_hmac_md5; return(ALGORITHMTYPE); } +hmac_sha1 { YYD; yylval.num = algtype_hmac_sha1; return(ALGORITHMTYPE); } +hmac_sha2_256 { YYD; yylval.num = algtype_hmac_sha2_256; return(ALGORITHMTYPE); } +hmac_sha256 { YYD; yylval.num = algtype_hmac_sha2_256; return(ALGORITHMTYPE); } +hmac_sha2_384 { YYD; yylval.num = algtype_hmac_sha2_384; return(ALGORITHMTYPE); } +hmac_sha384 { YYD; yylval.num = algtype_hmac_sha2_384; return(ALGORITHMTYPE); } +hmac_sha2_512 { YYD; yylval.num = algtype_hmac_sha2_512; return(ALGORITHMTYPE); } +hmac_sha512 { YYD; yylval.num = algtype_hmac_sha2_512; return(ALGORITHMTYPE); } +des_mac { YYD; yylval.num = algtype_des_mac; return(ALGORITHMTYPE); } +kpdk { YYD; yylval.num = algtype_kpdk; return(ALGORITHMTYPE); } +md5 { YYD; yylval.num = algtype_md5; return(ALGORITHMTYPE); } +sha1 { YYD; yylval.num = algtype_sha1; return(ALGORITHMTYPE); } +tiger { YYD; yylval.num = algtype_tiger; return(ALGORITHMTYPE); } +sha2_256 { YYD; yylval.num = algtype_sha2_256; return(ALGORITHMTYPE); } +sha256 { YYD; yylval.num = algtype_sha2_256; return(ALGORITHMTYPE); } +sha2_384 { YYD; yylval.num = algtype_sha2_384; return(ALGORITHMTYPE); } +sha384 { YYD; yylval.num = algtype_sha2_384; return(ALGORITHMTYPE); } +sha2_512 { YYD; yylval.num = algtype_sha2_512; return(ALGORITHMTYPE); } +sha512 { YYD; yylval.num = algtype_sha2_512; return(ALGORITHMTYPE); } +oui { YYD; yylval.num = algtype_oui; return(ALGORITHMTYPE); } +deflate { YYD; yylval.num = algtype_deflate; return(ALGORITHMTYPE); } +lzs { YYD; yylval.num = algtype_lzs; return(ALGORITHMTYPE); } +modp768 { YYD; yylval.num = algtype_modp768; return(ALGORITHMTYPE); } +modp1024 { YYD; yylval.num = algtype_modp1024; return(ALGORITHMTYPE); } +modp1536 { YYD; yylval.num = algtype_modp1536; return(ALGORITHMTYPE); } +ec2n155 { YYD; yylval.num = algtype_ec2n155; return(ALGORITHMTYPE); } +ec2n185 { YYD; yylval.num = algtype_ec2n185; return(ALGORITHMTYPE); } +modp2048 { YYD; yylval.num = algtype_modp2048; return(ALGORITHMTYPE); } +modp3072 { YYD; yylval.num = algtype_modp3072; return(ALGORITHMTYPE); } +modp4096 { YYD; yylval.num = algtype_modp4096; return(ALGORITHMTYPE); } +modp6144 { YYD; yylval.num = algtype_modp6144; return(ALGORITHMTYPE); } +modp8192 { YYD; yylval.num = algtype_modp8192; return(ALGORITHMTYPE); } +pre_shared_key { YYD; yylval.num = algtype_psk; return(ALGORITHMTYPE); } +rsasig { YYD; yylval.num = algtype_rsasig; return(ALGORITHMTYPE); } +dsssig { YYD; yylval.num = algtype_dsssig; return(ALGORITHMTYPE); } +rsaenc { YYD; yylval.num = algtype_rsaenc; return(ALGORITHMTYPE); } +rsarev { YYD; yylval.num = algtype_rsarev; return(ALGORITHMTYPE); } +gssapi_krb { YYD; yylval.num = algtype_gssapikrb; return(ALGORITHMTYPE); } +hybrid_rsa_server { +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_hybrid_rsa_s; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} +hybrid_dss_server { +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_hybrid_dss_s; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} +hybrid_rsa_client { +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_hybrid_rsa_c; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} +hybrid_dss_client { +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_hybrid_dss_c; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} +xauth_psk_server { +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_xauth_psk_s; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} +xauth_psk_client { +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_xauth_psk_c; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} +xauth_rsa_server { +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_xauth_rsa_s; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} +xauth_rsa_client { +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_xauth_rsa_c; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} + + + /* identifier type */ +user_fqdn { YYD; yylval.num = IDTYPE_USERFQDN; return(IDENTIFIERTYPE); } +fqdn { YYD; yylval.num = IDTYPE_FQDN; return(IDENTIFIERTYPE); } +keyid { YYD; yylval.num = IDTYPE_KEYID; return(IDENTIFIERTYPE); } +address { YYD; yylval.num = IDTYPE_ADDRESS; return(IDENTIFIERTYPE); } +subnet { YYD; yylval.num = IDTYPE_SUBNET; return(IDENTIFIERTYPE); } +asn1dn { YYD; yylval.num = IDTYPE_ASN1DN; return(IDENTIFIERTYPE); } + + /* identifier qualifier */ +tag { YYD; yylval.num = IDQUAL_TAG; return(IDENTIFIERQUAL); } +file { YYD; yylval.num = IDQUAL_FILE; return(IDENTIFIERQUAL); } + + /* units */ +B|byte|bytes { YYD; return(UNITTYPE_BYTE); } +KB { YYD; return(UNITTYPE_KBYTES); } +MB { YYD; return(UNITTYPE_MBYTES); } +TB { YYD; return(UNITTYPE_TBYTES); } +sec|secs|second|seconds { YYD; return(UNITTYPE_SEC); } +min|mins|minute|minutes { YYD; return(UNITTYPE_MIN); } +hour|hours { YYD; return(UNITTYPE_HOUR); } + + /* boolean */ +yes { YYD; yylval.num = TRUE; return(BOOLEAN); } +no { YYD; yylval.num = FALSE; return(BOOLEAN); } + +{decstring} { + char *bp; + + YYD; + yylval.num = strtoul(yytext, &bp, 10); + return(NUMBER); + } + +{hexstring} { + char *p; + + YYD; + yylval.val = vmalloc(yyleng + (yyleng & 1) + 1); + if (yylval.val == NULL) { + yyerror("vmalloc failed"); + return -1; + } + + p = yylval.val->v; + *p++ = '0'; + *p++ = 'x'; + + /* fixed string if length is odd. */ + if (yyleng & 1) + *p++ = '0'; + memcpy(p, &yytext[2], yyleng - 1); + + return(HEXSTRING); + } + +{quotedstring} { + char *p = yytext; + + YYD; + while (*++p != '"') ; + *p = '\0'; + + yylval.val = vmalloc(yyleng - 1); + if (yylval.val == NULL) { + yyerror("vmalloc failed"); + return -1; + } + memcpy(yylval.val->v, &yytext[1], yylval.val->l); + + return(QUOTEDSTRING); + } + +{addrstring} { + YYD; + + yylval.val = vmalloc(yyleng + 1); + if (yylval.val == NULL) { + yyerror("vmalloc failed"); + return -1; + } + memcpy(yylval.val->v, yytext, yylval.val->l); + + return(ADDRSTRING); + } + +<> { + yy_delete_buffer(YY_CURRENT_BUFFER); + fclose (incstack[incstackp].fp); + incstack[incstackp].fp = NULL; + racoon_free(incstack[incstackp].path); + incstack[incstackp].path = NULL; + incstackp--; + nextfile: + if (incstack[incstackp].matchon < + incstack[incstackp].matches.gl_pathc) { + char* filepath = incstack[incstackp].matches.gl_pathv[incstack[incstackp].matchon]; + incstack[incstackp].matchon++; + incstackp++; + if (yycf_set_buffer(filepath) != 0) { + incstackp--; + goto nextfile; + } + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + BEGIN(S_INI); + } else { + globfree(&incstack[incstackp].matches); + if (incstackp == 0) + yyterminate(); + else + yy_switch_to_buffer(incstack[incstackp].prevstate); + } + } + + /* ... */ +{ws} { ; } +{nl} { incstack[incstackp].lineno++; } +{comment} { YYD; } +{semi} { return(EOS); } +. { yymore(); } + +%% + +void +yyerror(char *s, ...) +{ + char fmt[512]; + + va_list ap; +#ifdef HAVE_STDARG_H + va_start(ap, s); +#else + va_start(ap); +#endif + snprintf(fmt, sizeof(fmt), "%s:%d: \"%s\" %s\n", + incstack[incstackp].path, incstack[incstackp].lineno, + yytext, s); + plogv(LLV_ERROR, LOCATION, NULL, fmt, ap); + va_end(ap); + + yyerrorcount++; +} + +void +yywarn(char *s, ...) +{ + char fmt[512]; + + va_list ap; +#ifdef HAVE_STDARG_H + va_start(ap, s); +#else + va_start(ap); +#endif + snprintf(fmt, sizeof(fmt), "%s:%d: \"%s\" %s\n", + incstack[incstackp].path, incstack[incstackp].lineno, + yytext, s); + plogv(LLV_WARNING, LOCATION, NULL, fmt, ap); + va_end(ap); +} + +int +yycf_switch_buffer(path) + char *path; +{ + char *filepath = NULL; + + /* got the include file name */ + if (incstackp >= MAX_INCLUDE_DEPTH) { + plog(LLV_ERROR, LOCATION, NULL, + "Includes nested too deeply"); + return -1; + } + + if (glob(path, GLOB_TILDE, NULL, &incstack[incstackp].matches) != 0 || + incstack[incstackp].matches.gl_pathc == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "glob found no matches for path \"%s\"\n", path); + return -1; + } + incstack[incstackp].matchon = 0; + incstack[incstackp].prevstate = YY_CURRENT_BUFFER; + + nextmatch: + if (incstack[incstackp].matchon >= incstack[incstackp].matches.gl_pathc) + return -1; + filepath = + incstack[incstackp].matches.gl_pathv[incstack[incstackp].matchon]; + incstack[incstackp].matchon++; + incstackp++; + + if (yycf_set_buffer(filepath) != 0) { + incstackp--; + goto nextmatch; + } + + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + + BEGIN(S_INI); + + return 0; +} + +int +yycf_set_buffer(path) + char *path; +{ + yyin = fopen(path, "r"); + if (yyin == NULL) { + fprintf(stderr, "failed to open file %s (%s)\n", + path, strerror(errno)); + plog(LLV_ERROR, LOCATION, NULL, + "failed to open file %s (%s)\n", + path, strerror(errno)); + return -1; + } + + /* initialize */ + incstack[incstackp].fp = yyin; + if (incstack[incstackp].path != NULL) + racoon_free(incstack[incstackp].path); + incstack[incstackp].path = racoon_strdup(path); + STRDUP_FATAL(incstack[incstackp].path); + incstack[incstackp].lineno = 1; + plog(LLV_DEBUG, LOCATION, NULL, + "reading config file %s\n", path); + + return 0; +} + +void +yycf_init_buffer() +{ + int i; + + for (i = 0; i < MAX_INCLUDE_DEPTH; i++) + memset(&incstack[i], 0, sizeof(incstack[i])); + incstackp = 0; +} + +void +yycf_clean_buffer() +{ + int i; + + for (i = 0; i < MAX_INCLUDE_DEPTH; i++) { + if (incstack[i].path != NULL) { + fclose(incstack[i].fp); + racoon_free(incstack[i].path); + incstack[i].path = NULL; + } + } +} + diff --git a/ipsec-tools/src/racoon/cftoken_proto.h b/ipsec-tools/src/racoon/cftoken_proto.h new file mode 100644 index 00000000..41cb939d --- /dev/null +++ b/ipsec-tools/src/racoon/cftoken_proto.h @@ -0,0 +1,48 @@ +/* $NetBSD: cftoken_proto.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: cftoken_proto.h,v 1.3 2004/06/11 16:00:15 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _CFTOKEN_PROTO_H +#define _CFTOKEN_PROTO_H + +extern int yyerrorcount; + +extern int yylex __P((void)); +extern void yyerror __P((char *, ...)); +extern void yywarn __P((char *, ...)); + +extern int yycf_switch_buffer __P((char *)); +extern int yycf_set_buffer __P((char *)); +extern void yycf_init_buffer __P((void)); +extern void yycf_clean_buffer __P((void)); + +#endif /* _CFTOKEN_PROTO_H */ diff --git a/ipsec-tools/src/racoon/contrib/sp.pl b/ipsec-tools/src/racoon/contrib/sp.pl new file mode 100644 index 00000000..d1f9cafe --- /dev/null +++ b/ipsec-tools/src/racoon/contrib/sp.pl @@ -0,0 +1,21 @@ +#! /usr/pkg/bin/perl + +die "insufficient arguments" if (scalar(@ARGV) < 2); +$src = $ARGV[0]; +$dst = $ARGV[1]; +$mode = 'transport'; +if (scalar(@ARGV) > 2) { + $mode = $ARGV[2]; +} + +open(OUT, "|setkey -c"); +if ($mode eq 'transport') { + print STDERR "install esp transport mode: $src -> $dst\n"; + print OUT "spdadd $src $dst any -P out ipsec esp/transport//require;\n"; + print OUT "spdadd $dst $src any -P in ipsec esp/transport//require;\n"; +} elsif ($mode eq 'delete') { + print STDERR "delete policy: $src -> $dst\n"; + print OUT "spddelete $src $dst any -P out;\n"; + print OUT "spddelete $dst $src any -P in;\n"; +} +close(OUT); diff --git a/ipsec-tools/src/racoon/crypto_openssl.c b/ipsec-tools/src/racoon/crypto_openssl.c new file mode 100644 index 00000000..55b076a3 --- /dev/null +++ b/ipsec-tools/src/racoon/crypto_openssl.c @@ -0,0 +1,2586 @@ +/* $NetBSD: crypto_openssl.c,v 1.20.4.3 2012/12/24 14:50:39 tteras Exp $ */ + +/* Id: crypto_openssl.c,v 1.47 2006/05/06 20:42:09 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include + +/* get openssl/ssleay version number */ +#include + +#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090813fL) +#error OpenSSL version 0.9.8s or later required. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_OPENSSL_ENGINE_H +#include +#endif +#include +#include +#include +#ifdef HAVE_OPENSSL_RC5_H +#include +#endif +#ifdef HAVE_OPENSSL_IDEA_H +#include +#endif +#if defined(HAVE_OPENSSL_AES_H) +#include +#elif defined(HAVE_OPENSSL_RIJNDAEL_H) +#include +#else +#include "crypto/rijndael/rijndael-api-fst.h" +#endif +#if defined(HAVE_OPENSSL_CAMELLIA_H) +#include +#endif +#ifdef WITH_SHA2 +#ifdef HAVE_OPENSSL_SHA2_H +#include +#else +#include "crypto/sha2/sha2.h" +#endif +#endif +#include "plog.h" + +#define USE_NEW_DES_API + +#define OpenSSL_BUG() do { plog(LLV_ERROR, LOCATION, NULL, "OpenSSL function failed\n"); } while(0) + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "crypto_openssl.h" +#include "debug.h" +#include "gcmalloc.h" +#include "isakmp.h" + +/* + * I hate to cast every parameter to des_xx into void *, but it is + * necessary for SSLeay/OpenSSL portability. It sucks. + */ + +static int cb_check_cert_local __P((int, X509_STORE_CTX *)); +static int cb_check_cert_remote __P((int, X509_STORE_CTX *)); +static X509 *mem2x509 __P((vchar_t *)); + +static caddr_t eay_hmac_init __P((vchar_t *, const EVP_MD *)); + +/* X509 Certificate */ +/* + * convert the string of the subject name into DER + * e.g. str = "C=JP, ST=Kanagawa"; + */ +vchar_t * +eay_str2asn1dn(str, len) + const char *str; + int len; +{ + X509_NAME *name; + char *buf, *dst; + char *field, *value; + int i; + vchar_t *ret = NULL; + caddr_t p; + + if (len == -1) + len = strlen(str); + + buf = racoon_malloc(len + 1); + if (!buf) { + plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n"); + return NULL; + } + memcpy(buf, str, len); + + name = X509_NAME_new(); + + dst = field = &buf[0]; + value = NULL; + for (i = 0; i < len; i++) { + if (buf[i] == '\\') { + /* Escape characters specified in RFC 2253 */ + if (i < len - 1 && + strchr("\\,=+<>#;", buf[i+1]) != NULL) { + *dst++ = buf[++i]; + continue; + } else if (i < len - 2) { + /* RFC 2253 hexpair character escape */ + long u; + char esc_str[3]; + char *endptr; + + esc_str[0] = buf[++i]; + esc_str[1] = buf[++i]; + esc_str[2] = '\0'; + u = strtol(esc_str, &endptr, 16); + if (*endptr != '\0' || u < 0 || u > 255) + goto err; + *dst++ = u; + continue; + } else + goto err; + } + if (!value && buf[i] == '=') { + *dst = '\0'; + dst = value = &buf[i + 1]; + continue; + } else if (buf[i] == ',' || buf[i] == '/') { + *dst = '\0'; + + plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n", + field, value); + + if (!value) goto err; + if (!X509_NAME_add_entry_by_txt(name, field, + (value[0] == '*' && value[1] == 0) ? + V_ASN1_PRINTABLESTRING : MBSTRING_ASC, + (unsigned char *) value, -1, -1, 0)) { + plog(LLV_ERROR, LOCATION, NULL, + "Invalid DN field: %s=%s\n", + field, value); + plog(LLV_ERROR, LOCATION, NULL, + "%s\n", eay_strerror()); + goto err; + } + + while (i + 1 < len && buf[i + 1] == ' ') i++; + dst = field = &buf[i + 1]; + value = NULL; + continue; + } else { + *dst++ = buf[i]; + } + } + *dst = '\0'; + + plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n", + field, value); + + if (!value) goto err; + if (!X509_NAME_add_entry_by_txt(name, field, + (value[0] == '*' && value[1] == 0) ? + V_ASN1_PRINTABLESTRING : MBSTRING_ASC, + (unsigned char *) value, -1, -1, 0)) { + plog(LLV_ERROR, LOCATION, NULL, + "Invalid DN field: %s=%s\n", + field, value); + plog(LLV_ERROR, LOCATION, NULL, + "%s\n", eay_strerror()); + goto err; + } + + i = i2d_X509_NAME(name, NULL); + if (!i) + goto err; + ret = vmalloc(i); + if (!ret) + goto err; + p = ret->v; + i = i2d_X509_NAME(name, (void *)&p); + if (!i) + goto err; + + return ret; + + err: + if (buf) + racoon_free(buf); + if (name) + X509_NAME_free(name); + if (ret) + vfree(ret); + return NULL; +} + +/* + * convert the hex string of the subject name into DER + */ +vchar_t * +eay_hex2asn1dn(const char *hex, int len) +{ + BIGNUM *bn = BN_new(); + char *binbuf; + size_t binlen; + vchar_t *ret = NULL; + + if (len == -1) + len = strlen(hex); + + if (BN_hex2bn(&bn, hex) != len) { + plog(LLV_ERROR, LOCATION, NULL, + "conversion of Hex-encoded ASN1 string to binary failed: %s\n", + eay_strerror()); + goto out; + } + + binlen = BN_num_bytes(bn); + ret = vmalloc(binlen); + if (!ret) { + plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n"); + return NULL; + } + binbuf = ret->v; + + BN_bn2bin(bn, (unsigned char *) binbuf); + +out: + BN_free(bn); + + return ret; +} + +/* + * compare two subjectNames. + * OUT: 0: equal + * positive: + * -1: other error. + */ +int +eay_cmp_asn1dn(n1, n2) + vchar_t *n1, *n2; +{ + X509_NAME *a = NULL, *b = NULL; + caddr_t p; + char oneLine[512]; + int i = -1; + int idx; + + p = n1->v; + if (!d2i_X509_NAME(&a, (void *)&p, n1->l)) { + plog(LLV_ERROR, LOCATION, NULL, "eay_cmp_asn1dn: first dn not a dn"); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "1st name: %s\n", X509_NAME_oneline(a, oneLine, sizeof(oneLine))); + p = n2->v; + if (!d2i_X509_NAME(&b, (void *)&p, n2->l)) { + plog(LLV_ERROR, LOCATION, NULL, "eay_cmp_asn1dn: second dn not a dn"); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "2nd name: %s\n", X509_NAME_oneline(b, oneLine, sizeof(oneLine))); + + /* handle wildcard: do not compare entry content but only entry object type */ + for(idx = 0; idx < X509_NAME_entry_count(a); idx++) { + X509_NAME_ENTRY *ea = X509_NAME_get_entry(a, idx); + X509_NAME_ENTRY *eb = X509_NAME_get_entry(b, idx); + if (!eb) { /* reached end of eb while still entries in ea, can not be equal... */ + i = idx+1; + goto end; + } + if ((ea->value->length == 1 && ea->value->data[0] == '*') || + (eb->value->length == 1 && eb->value->data[0] == '*')) { + if (OBJ_cmp(ea->object,eb->object)) { + i = idx+1; + goto end; + } + /* OK: object type equals, we don't care for this entry anymore, so let's forget it... */ + X509_NAME_delete_entry(a, idx); + X509_NAME_delete_entry(b, idx); + X509_NAME_ENTRY_free(ea); + X509_NAME_ENTRY_free(eb); + idx--; + } + } + if (X509_NAME_entry_count(a) == 0 && X509_NAME_entry_count(b) == 0) + i = 0; + else + i = X509_NAME_cmp(a, b); + + end: + if (a) + X509_NAME_free(a); + if (b) + X509_NAME_free(b); + return i; +} + +/* + * this functions is derived from apps/verify.c in OpenSSL0.9.5 + */ +int +eay_check_x509cert(cert, CApath, CAfile, local) + vchar_t *cert; + char *CApath; + char *CAfile; + int local; +{ + X509_STORE *cert_ctx = NULL; + X509_LOOKUP *lookup = NULL; + X509 *x509 = NULL; + X509_STORE_CTX *csc; + int error = -1; + + cert_ctx = X509_STORE_new(); + if (cert_ctx == NULL) + goto end; + + if (local) + X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_local); + else + X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_remote); + + lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()); + if (lookup == NULL) + goto end; + + X509_LOOKUP_load_file(lookup, CAfile, + (CAfile == NULL) ? X509_FILETYPE_DEFAULT : X509_FILETYPE_PEM); + + lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + goto end; + error = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM); + if(!error) { + error = -1; + goto end; + } + error = -1; /* initialized */ + + /* read the certificate to be verified */ + x509 = mem2x509(cert); + if (x509 == NULL) + goto end; + + csc = X509_STORE_CTX_new(); + if (csc == NULL) + goto end; + X509_STORE_CTX_init(csc, cert_ctx, x509, NULL); + X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK); + X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK_ALL); + error = X509_verify_cert(csc); + X509_STORE_CTX_free(csc); + + /* + * if x509_verify_cert() is successful then the value of error is + * set non-zero. + */ + error = error ? 0 : -1; + +end: + if (error) + plog(LLV_WARNING, LOCATION, NULL,"%s\n", eay_strerror()); + if (cert_ctx != NULL) + X509_STORE_free(cert_ctx); + if (x509 != NULL) + X509_free(x509); + + return(error); +} + +/* + * callback function for verifing certificate. + * this function is derived from cb() in openssl/apps/s_server.c + */ +static int +cb_check_cert_local(ok, ctx) + int ok; + X509_STORE_CTX *ctx; +{ + char buf[256]; + int log_tag; + + if (!ok) { + X509_NAME_oneline( + X509_get_subject_name(ctx->current_cert), + buf, + 256); + /* + * since we are just checking the certificates, it is + * ok if they are self signed. But we should still warn + * the user. + */ + switch (ctx->error) { + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + case X509_V_ERR_INVALID_CA: + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + case X509_V_ERR_INVALID_PURPOSE: + case X509_V_ERR_UNABLE_TO_GET_CRL: + ok = 1; + log_tag = LLV_WARNING; + break; + default: + log_tag = LLV_ERROR; + } + plog(log_tag, LOCATION, NULL, + "%s(%d) at depth:%d SubjectName:%s\n", + X509_verify_cert_error_string(ctx->error), + ctx->error, + ctx->error_depth, + buf); + } + ERR_clear_error(); + + return ok; +} + +/* + * callback function for verifing remote certificates. + * this function is derived from cb() in openssl/apps/s_server.c + */ +static int +cb_check_cert_remote(ok, ctx) + int ok; + X509_STORE_CTX *ctx; +{ + char buf[256]; + int log_tag; + + if (!ok) { + X509_NAME_oneline( + X509_get_subject_name(ctx->current_cert), + buf, + 256); + switch (ctx->error) { + case X509_V_ERR_UNABLE_TO_GET_CRL: + ok = 1; + log_tag = LLV_WARNING; + break; + default: + log_tag = LLV_ERROR; + } + plog(log_tag, LOCATION, NULL, + "%s(%d) at depth:%d SubjectName:%s\n", + X509_verify_cert_error_string(ctx->error), + ctx->error, + ctx->error_depth, + buf); + } + ERR_clear_error(); + + return ok; +} + +/* + * get a subjectName from X509 certificate. + */ +vchar_t * +eay_get_x509asn1subjectname(cert) + vchar_t *cert; +{ + X509 *x509 = NULL; + u_char *bp; + vchar_t *name = NULL; + int len; + + x509 = mem2x509(cert); + if (x509 == NULL) + goto error; + + /* get the length of the name */ + len = i2d_X509_NAME(x509->cert_info->subject, NULL); + name = vmalloc(len); + if (!name) + goto error; + /* get the name */ + bp = (unsigned char *) name->v; + len = i2d_X509_NAME(x509->cert_info->subject, &bp); + + X509_free(x509); + + return name; + +error: + plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror()); + + if (name != NULL) + vfree(name); + + if (x509 != NULL) + X509_free(x509); + + return NULL; +} + +/* + * get the subjectAltName from X509 certificate. + * the name must be terminated by '\0'. + */ +int +eay_get_x509subjectaltname(cert, altname, type, pos) + vchar_t *cert; + char **altname; + int *type; + int pos; +{ + X509 *x509 = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen; + int len; + int error = -1; + + *altname = NULL; + *type = GENT_OTHERNAME; + + x509 = mem2x509(cert); + if (x509 == NULL) + goto end; + + gens = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL); + if (gens == NULL) + goto end; + + /* there is no data at "pos" */ + if (pos > sk_GENERAL_NAME_num(gens)) + goto end; + + gen = sk_GENERAL_NAME_value(gens, pos - 1); + + /* read DNSName / Email */ + if (gen->type == GEN_DNS || + gen->type == GEN_EMAIL || + gen->type == GEN_URI ) + { + /* make sure if the data is terminated by '\0'. */ + if (gen->d.ia5->data[gen->d.ia5->length] != '\0') + { + plog(LLV_ERROR, LOCATION, NULL, + "data is not terminated by NUL."); + racoon_hexdump(gen->d.ia5->data, gen->d.ia5->length + 1); + goto end; + } + + len = gen->d.ia5->length + 1; + *altname = racoon_malloc(len); + if (!*altname) + goto end; + + strlcpy(*altname, (char *) gen->d.ia5->data, len); + *type = gen->type; + error = 0; + } + /* read IP address */ + else if (gen->type == GEN_IPADD) + { + unsigned char p[5], *ip; + ip = p; + + /* only support IPv4 */ + if (gen->d.ip->length != 4) + goto end; + + /* convert Octet String to String + * XXX ??????? + */ + /*i2d_ASN1_OCTET_STRING(gen->d.ip,&ip);*/ + ip = gen->d.ip->data; + + /* XXX Magic, enough for an IPv4 address + */ + *altname = racoon_malloc(20); + if (!*altname) + goto end; + + sprintf(*altname, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); + *type = gen->type; + error = 0; + } + /* XXX other possible types ? + * For now, error will be -1 if unsupported type + */ + +end: + if (error) { + if (*altname) { + racoon_free(*altname); + *altname = NULL; + } + plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror()); + } + if (x509) + X509_free(x509); + if (gens) + /* free the whole stack. */ + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + + return error; +} + +/* + * get a issuerName from X509 certificate. + */ +vchar_t * +eay_get_x509asn1issuername(cert) + vchar_t *cert; +{ + X509 *x509 = NULL; + u_char *bp; + vchar_t *name = NULL; + int len; + + x509 = mem2x509(cert); + if (x509 == NULL) + goto error; + + /* get the length of the name */ + len = i2d_X509_NAME(x509->cert_info->issuer, NULL); + name = vmalloc(len); + if (name == NULL) + goto error; + + /* get the name */ + bp = (unsigned char *) name->v; + len = i2d_X509_NAME(x509->cert_info->issuer, &bp); + + X509_free(x509); + + return name; + +error: + plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror()); + + if (name != NULL) + vfree(name); + if (x509 != NULL) + X509_free(x509); + + return NULL; +} + +/* + * decode a X509 certificate and make a readable text terminated '\n'. + * return the buffer allocated, so must free it later. + */ +char * +eay_get_x509text(cert) + vchar_t *cert; +{ + X509 *x509 = NULL; + BIO *bio = NULL; + char *text = NULL; + u_char *bp = NULL; + int len = 0; + int error = -1; + + x509 = mem2x509(cert); + if (x509 == NULL) + goto end; + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) + goto end; + + error = X509_print(bio, x509); + if (error != 1) { + error = -1; + goto end; + } + + len = BIO_get_mem_data(bio, &bp); + text = racoon_malloc(len + 1); + if (text == NULL) + goto end; + memcpy(text, bp, len); + text[len] = '\0'; + + error = 0; + + end: + if (error) { + if (text) { + racoon_free(text); + text = NULL; + } + plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror()); + } + if (bio) + BIO_free(bio); + if (x509) + X509_free(x509); + + return text; +} + +/* get X509 structure from buffer. */ +static X509 * +mem2x509(cert) + vchar_t *cert; +{ + X509 *x509; + +#ifndef EAYDEBUG + { + u_char *bp; + + bp = (unsigned char *) cert->v + 1; + + x509 = d2i_X509(NULL, (void *)&bp, cert->l - 1); + } +#else + { + BIO *bio; + int len; + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) + return NULL; + len = BIO_write(bio, cert->v + 1, cert->l - 1); + if (len == -1) + return NULL; + x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); + BIO_free(bio); + } +#endif + return x509; +} + +/* + * get a X509 certificate from local file. + * a certificate must be PEM format. + * Input: + * path to a certificate. + * Output: + * NULL if error occured + * other is the cert. + */ +vchar_t * +eay_get_x509cert(path) + char *path; +{ + FILE *fp; + X509 *x509; + vchar_t *cert; + u_char *bp; + int len; + int error; + + /* Read private key */ + fp = fopen(path, "r"); + if (fp == NULL) + return NULL; + x509 = PEM_read_X509(fp, NULL, NULL, NULL); + fclose (fp); + + if (x509 == NULL) + return NULL; + + len = i2d_X509(x509, NULL); + cert = vmalloc(len + 1); + if (cert == NULL) { + X509_free(x509); + return NULL; + } + cert->v[0] = ISAKMP_CERT_X509SIGN; + bp = (unsigned char *) &cert->v[1]; + error = i2d_X509(x509, &bp); + X509_free(x509); + + if (error == 0) { + vfree(cert); + return NULL; + } + + return cert; +} + +/* + * check a X509 signature + * XXX: to be get hash type from my cert ? + * to be handled EVP_dss(). + * OUT: return -1 when error. + * 0 + */ +int +eay_check_x509sign(source, sig, cert) + vchar_t *source; + vchar_t *sig; + vchar_t *cert; +{ + X509 *x509; + EVP_PKEY *evp; + int res; + + x509 = mem2x509(cert); + if (x509 == NULL) + return -1; + + evp = X509_get_pubkey(x509); + if (! evp) { + plog(LLV_ERROR, LOCATION, NULL, "X509_get_pubkey(): %s\n", eay_strerror()); + X509_free(x509); + return -1; + } + + res = eay_rsa_verify(source, sig, evp->pkey.rsa); + + EVP_PKEY_free(evp); + X509_free(x509); + + return res; +} + +/* + * check RSA signature + * OUT: return -1 when error. + * 0 on success + */ +int +eay_check_rsasign(source, sig, rsa) + vchar_t *source; + vchar_t *sig; + RSA *rsa; +{ + return eay_rsa_verify(source, sig, rsa); +} + +/* + * get PKCS#1 Private Key of PEM format from local file. + */ +vchar_t * +eay_get_pkcs1privkey(path) + char *path; +{ + FILE *fp; + EVP_PKEY *evp = NULL; + vchar_t *pkey = NULL; + u_char *bp; + int pkeylen; + int error = -1; + + /* Read private key */ + fp = fopen(path, "r"); + if (fp == NULL) + return NULL; + + evp = PEM_read_PrivateKey(fp, NULL, NULL, NULL); + + fclose (fp); + + if (evp == NULL) + return NULL; + + pkeylen = i2d_PrivateKey(evp, NULL); + if (pkeylen == 0) + goto end; + pkey = vmalloc(pkeylen); + if (pkey == NULL) + goto end; + bp = (unsigned char *) pkey->v; + pkeylen = i2d_PrivateKey(evp, &bp); + if (pkeylen == 0) + goto end; + + error = 0; + +end: + if (evp != NULL) + EVP_PKEY_free(evp); + if (error != 0 && pkey != NULL) { + vfree(pkey); + pkey = NULL; + } + + return pkey; +} + +/* + * get PKCS#1 Public Key of PEM format from local file. + */ +vchar_t * +eay_get_pkcs1pubkey(path) + char *path; +{ + FILE *fp; + EVP_PKEY *evp = NULL; + vchar_t *pkey = NULL; + X509 *x509 = NULL; + u_char *bp; + int pkeylen; + int error = -1; + + /* Read private key */ + fp = fopen(path, "r"); + if (fp == NULL) + return NULL; + + x509 = PEM_read_X509(fp, NULL, NULL, NULL); + + fclose (fp); + + if (x509 == NULL) + return NULL; + + /* Get public key - eay */ + evp = X509_get_pubkey(x509); + if (evp == NULL) + return NULL; + + pkeylen = i2d_PublicKey(evp, NULL); + if (pkeylen == 0) + goto end; + pkey = vmalloc(pkeylen); + if (pkey == NULL) + goto end; + bp = (unsigned char *) pkey->v; + pkeylen = i2d_PublicKey(evp, &bp); + if (pkeylen == 0) + goto end; + + error = 0; +end: + if (evp != NULL) + EVP_PKEY_free(evp); + if (error != 0 && pkey != NULL) { + vfree(pkey); + pkey = NULL; + } + + return pkey; +} + +vchar_t * +eay_get_x509sign(src, privkey) + vchar_t *src, *privkey; +{ + EVP_PKEY *evp; + u_char *bp = (unsigned char *) privkey->v; + vchar_t *sig = NULL; + int len; + int pad = RSA_PKCS1_PADDING; + + /* XXX to be handled EVP_PKEY_DSA */ + evp = d2i_PrivateKey(EVP_PKEY_RSA, NULL, (void *)&bp, privkey->l); + if (evp == NULL) + return NULL; + + sig = eay_rsa_sign(src, evp->pkey.rsa); + + EVP_PKEY_free(evp); + + return sig; +} + +vchar_t * +eay_get_rsasign(src, rsa) + vchar_t *src; + RSA *rsa; +{ + return eay_rsa_sign(src, rsa); +} + +vchar_t * +eay_rsa_sign(vchar_t *src, RSA *rsa) +{ + int len; + vchar_t *sig = NULL; + int pad = RSA_PKCS1_PADDING; + + len = RSA_size(rsa); + + sig = vmalloc(len); + if (sig == NULL) + return NULL; + + len = RSA_private_encrypt(src->l, (unsigned char *) src->v, + (unsigned char *) sig->v, rsa, pad); + + if (len == 0 || len != sig->l) { + vfree(sig); + sig = NULL; + } + + return sig; +} + +int +eay_rsa_verify(src, sig, rsa) + vchar_t *src, *sig; + RSA *rsa; +{ + vchar_t *xbuf = NULL; + int pad = RSA_PKCS1_PADDING; + int len = 0; + int error; + + len = RSA_size(rsa); + xbuf = vmalloc(len); + if (xbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror()); + return -1; + } + + len = RSA_public_decrypt(sig->l, (unsigned char *) sig->v, + (unsigned char *) xbuf->v, rsa, pad); + if (len == 0 || len != src->l) { + plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror()); + vfree(xbuf); + return -1; + } + + error = memcmp(src->v, xbuf->v, src->l); + vfree(xbuf); + if (error != 0) + return -1; + + return 0; +} + +/* + * get error string + * MUST load ERR_load_crypto_strings() first. + */ +char * +eay_strerror() +{ + static char ebuf[512]; + int len = 0, n; + unsigned long l; + char buf[200]; + const char *file, *data; + int line, flags; + unsigned long es; + + es = CRYPTO_thread_id(); + + while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0){ + n = snprintf(ebuf + len, sizeof(ebuf) - len, + "%lu:%s:%s:%d:%s ", + es, ERR_error_string(l, buf), file, line, + (flags & ERR_TXT_STRING) ? data : ""); + if (n < 0 || n >= sizeof(ebuf) - len) + break; + len += n; + if (sizeof(ebuf) < len) + break; + } + + return ebuf; +} + +vchar_t * +evp_crypt(vchar_t *data, vchar_t *key, vchar_t *iv, const EVP_CIPHER *e, int enc) +{ + vchar_t *res; + EVP_CIPHER_CTX ctx; + + if (!e) + return NULL; + + if (data->l % EVP_CIPHER_block_size(e)) + return NULL; + + if ((res = vmalloc(data->l)) == NULL) + return NULL; + + EVP_CIPHER_CTX_init(&ctx); + + switch(EVP_CIPHER_nid(e)){ + case NID_bf_cbc: + case NID_bf_ecb: + case NID_bf_cfb64: + case NID_bf_ofb64: + case NID_cast5_cbc: + case NID_cast5_ecb: + case NID_cast5_cfb64: + case NID_cast5_ofb64: + /* XXX: can we do that also for algos with a fixed key size ? + */ + /* init context without key/iv + */ + if (!EVP_CipherInit(&ctx, e, NULL, NULL, enc)) + { + OpenSSL_BUG(); + vfree(res); + return NULL; + } + + /* update key size + */ + if (!EVP_CIPHER_CTX_set_key_length(&ctx, key->l)) + { + OpenSSL_BUG(); + vfree(res); + return NULL; + } + + /* finalize context init with desired key size + */ + if (!EVP_CipherInit(&ctx, NULL, (u_char *) key->v, + (u_char *) iv->v, enc)) + { + OpenSSL_BUG(); + vfree(res); + return NULL; + } + break; + default: + if (!EVP_CipherInit(&ctx, e, (u_char *) key->v, + (u_char *) iv->v, enc)) { + OpenSSL_BUG(); + vfree(res); + return NULL; + } + } + + /* disable openssl padding */ + EVP_CIPHER_CTX_set_padding(&ctx, 0); + + if (!EVP_Cipher(&ctx, (u_char *) res->v, (u_char *) data->v, data->l)) { + OpenSSL_BUG(); + vfree(res); + return NULL; + } + + EVP_CIPHER_CTX_cleanup(&ctx); + + return res; +} + +int +evp_weakkey(vchar_t *key, const EVP_CIPHER *e) +{ + return 0; +} + +int +evp_keylen(int len, const EVP_CIPHER *e) +{ + if (!e) + return -1; + /* EVP functions return lengths in bytes, ipsec-tools + * uses lengths in bits, therefore conversion is required. --AK + */ + if (len != 0 && len != (EVP_CIPHER_key_length(e) << 3)) + return -1; + + return EVP_CIPHER_key_length(e) << 3; +} + +/* + * DES-CBC + */ +vchar_t * +eay_des_encrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + return evp_crypt(data, key, iv, EVP_des_cbc(), 1); +} + +vchar_t * +eay_des_decrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + return evp_crypt(data, key, iv, EVP_des_cbc(), 0); +} + +int +eay_des_weakkey(key) + vchar_t *key; +{ +#ifdef USE_NEW_DES_API + return DES_is_weak_key((void *)key->v); +#else + return des_is_weak_key((void *)key->v); +#endif +} + +int +eay_des_keylen(len) + int len; +{ + return evp_keylen(len, EVP_des_cbc()); +} + +#ifdef HAVE_OPENSSL_IDEA_H +/* + * IDEA-CBC + */ +vchar_t * +eay_idea_encrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + vchar_t *res; + IDEA_KEY_SCHEDULE ks; + + idea_set_encrypt_key((unsigned char *)key->v, &ks); + + /* allocate buffer for result */ + if ((res = vmalloc(data->l)) == NULL) + return NULL; + + /* decryption data */ + idea_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l, + &ks, (unsigned char *)iv->v, IDEA_ENCRYPT); + + return res; +} + +vchar_t * +eay_idea_decrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + vchar_t *res; + IDEA_KEY_SCHEDULE ks, dks; + + idea_set_encrypt_key((unsigned char *)key->v, &ks); + idea_set_decrypt_key(&ks, &dks); + + /* allocate buffer for result */ + if ((res = vmalloc(data->l)) == NULL) + return NULL; + + /* decryption data */ + idea_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l, + &dks, (unsigned char *)iv->v, IDEA_DECRYPT); + + return res; +} + +int +eay_idea_weakkey(key) + vchar_t *key; +{ + return 0; /* XXX */ +} + +int +eay_idea_keylen(len) + int len; +{ + if (len != 0 && len != 128) + return -1; + return 128; +} +#endif + +/* + * BLOWFISH-CBC + */ +vchar_t * +eay_bf_encrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + return evp_crypt(data, key, iv, EVP_bf_cbc(), 1); +} + +vchar_t * +eay_bf_decrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + return evp_crypt(data, key, iv, EVP_bf_cbc(), 0); +} + +int +eay_bf_weakkey(key) + vchar_t *key; +{ + return 0; /* XXX to be done. refer to RFC 2451 */ +} + +int +eay_bf_keylen(len) + int len; +{ + if (len == 0) + return 448; + if (len < 40 || len > 448) + return -1; + return len; +} + +#ifdef HAVE_OPENSSL_RC5_H +/* + * RC5-CBC + */ +vchar_t * +eay_rc5_encrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + vchar_t *res; + RC5_32_KEY ks; + + /* in RFC 2451, there is information about the number of round. */ + RC5_32_set_key(&ks, key->l, (unsigned char *)key->v, 16); + + /* allocate buffer for result */ + if ((res = vmalloc(data->l)) == NULL) + return NULL; + + /* decryption data */ + RC5_32_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l, + &ks, (unsigned char *)iv->v, RC5_ENCRYPT); + + return res; +} + +vchar_t * +eay_rc5_decrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + vchar_t *res; + RC5_32_KEY ks; + + /* in RFC 2451, there is information about the number of round. */ + RC5_32_set_key(&ks, key->l, (unsigned char *)key->v, 16); + + /* allocate buffer for result */ + if ((res = vmalloc(data->l)) == NULL) + return NULL; + + /* decryption data */ + RC5_32_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l, + &ks, (unsigned char *)iv->v, RC5_DECRYPT); + + return res; +} + +int +eay_rc5_weakkey(key) + vchar_t *key; +{ + return 0; /* No known weak keys when used with 16 rounds. */ + +} + +int +eay_rc5_keylen(len) + int len; +{ + if (len == 0) + return 128; + if (len < 40 || len > 2040) + return -1; + return len; +} +#endif + +/* + * 3DES-CBC + */ +vchar_t * +eay_3des_encrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 1); +} + +vchar_t * +eay_3des_decrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 0); +} + +int +eay_3des_weakkey(key) + vchar_t *key; +{ +#ifdef USE_NEW_DES_API + return (DES_is_weak_key((void *)key->v) || + DES_is_weak_key((void *)(key->v + 8)) || + DES_is_weak_key((void *)(key->v + 16))); +#else + if (key->l < 24) + return 0; + + return (des_is_weak_key((void *)key->v) || + des_is_weak_key((void *)(key->v + 8)) || + des_is_weak_key((void *)(key->v + 16))); +#endif +} + +int +eay_3des_keylen(len) + int len; +{ + if (len != 0 && len != 192) + return -1; + return 192; +} + +/* + * CAST-CBC + */ +vchar_t * +eay_cast_encrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + return evp_crypt(data, key, iv, EVP_cast5_cbc(), 1); +} + +vchar_t * +eay_cast_decrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + return evp_crypt(data, key, iv, EVP_cast5_cbc(), 0); +} + +int +eay_cast_weakkey(key) + vchar_t *key; +{ + return 0; /* No known weak keys. */ +} + +int +eay_cast_keylen(len) + int len; +{ + if (len == 0) + return 128; + if (len < 40 || len > 128) + return -1; + return len; +} + +/* + * AES(RIJNDAEL)-CBC + */ +#ifndef HAVE_OPENSSL_AES_H +vchar_t * +eay_aes_encrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + vchar_t *res; + keyInstance k; + cipherInstance c; + + memset(&k, 0, sizeof(k)); + if (rijndael_makeKey(&k, DIR_ENCRYPT, key->l << 3, key->v) < 0) + return NULL; + + /* allocate buffer for result */ + if ((res = vmalloc(data->l)) == NULL) + return NULL; + + /* encryption data */ + memset(&c, 0, sizeof(c)); + if (rijndael_cipherInit(&c, MODE_CBC, iv->v) < 0){ + vfree(res); + return NULL; + } + if (rijndael_blockEncrypt(&c, &k, data->v, data->l << 3, res->v) < 0){ + vfree(res); + return NULL; + } + + return res; +} + +vchar_t * +eay_aes_decrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + vchar_t *res; + keyInstance k; + cipherInstance c; + + memset(&k, 0, sizeof(k)); + if (rijndael_makeKey(&k, DIR_DECRYPT, key->l << 3, key->v) < 0) + return NULL; + + /* allocate buffer for result */ + if ((res = vmalloc(data->l)) == NULL) + return NULL; + + /* decryption data */ + memset(&c, 0, sizeof(c)); + if (rijndael_cipherInit(&c, MODE_CBC, iv->v) < 0){ + vfree(res); + return NULL; + } + if (rijndael_blockDecrypt(&c, &k, data->v, data->l << 3, res->v) < 0){ + vfree(res); + return NULL; + } + + return res; +} +#else +static inline const EVP_CIPHER * +aes_evp_by_keylen(int keylen) +{ + switch(keylen) { + case 16: + case 128: + return EVP_aes_128_cbc(); + case 24: + case 192: + return EVP_aes_192_cbc(); + case 32: + case 256: + return EVP_aes_256_cbc(); + default: + return NULL; + } +} + +vchar_t * +eay_aes_encrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 1); +} + +vchar_t * +eay_aes_decrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 0); +} +#endif + +int +eay_aes_weakkey(key) + vchar_t *key; +{ + return 0; +} + +int +eay_aes_keylen(len) + int len; +{ + if (len == 0) + return 128; + if (len != 128 && len != 192 && len != 256) + return -1; + return len; +} + +#if defined(HAVE_OPENSSL_CAMELLIA_H) +/* + * CAMELLIA-CBC + */ +static inline const EVP_CIPHER * +camellia_evp_by_keylen(int keylen) +{ + switch(keylen) { + case 16: + case 128: + return EVP_camellia_128_cbc(); + case 24: + case 192: + return EVP_camellia_192_cbc(); + case 32: + case 256: + return EVP_camellia_256_cbc(); + default: + return NULL; + } +} + +vchar_t * +eay_camellia_encrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + return evp_crypt(data, key, iv, camellia_evp_by_keylen(key->l), 1); +} + +vchar_t * +eay_camellia_decrypt(data, key, iv) + vchar_t *data, *key, *iv; +{ + return evp_crypt(data, key, iv, camellia_evp_by_keylen(key->l), 0); +} + +int +eay_camellia_weakkey(key) + vchar_t *key; +{ + return 0; +} + +int +eay_camellia_keylen(len) + int len; +{ + if (len == 0) + return 128; + if (len != 128 && len != 192 && len != 256) + return -1; + return len; +} + +#endif + +/* for ipsec part */ +int +eay_null_hashlen() +{ + return 0; +} + +int +eay_kpdk_hashlen() +{ + return 0; +} + +int +eay_twofish_keylen(len) + int len; +{ + if (len < 0 || len > 256) + return -1; + return len; +} + +int +eay_null_keylen(len) + int len; +{ + return 0; +} + +/* + * HMAC functions + */ +static caddr_t +eay_hmac_init(key, md) + vchar_t *key; + const EVP_MD *md; +{ + HMAC_CTX *c = racoon_malloc(sizeof(*c)); + + HMAC_Init(c, key->v, key->l, md); + + return (caddr_t)c; +} + +static vchar_t *eay_hmac_one(key, data, type) + vchar_t *key, *data; + const EVP_MD *type; +{ + vchar_t *res; + + if ((res = vmalloc(EVP_MD_size(type))) == 0) + return NULL; + + if (!HMAC(type, (void *) key->v, key->l, + (void *) data->v, data->l, (void *) res->v, NULL)) { + vfree(res); + return NULL; + } + + return res; +} + +static vchar_t *eay_digest_one(data, type) + vchar_t *data; + const EVP_MD *type; +{ + vchar_t *res; + + if ((res = vmalloc(EVP_MD_size(type))) == 0) + return NULL; + + if (!EVP_Digest((void *) data->v, data->l, + (void *) res->v, NULL, type, NULL)) { + vfree(res); + return NULL; + } + + return res; +} + +#ifdef WITH_SHA2 +/* + * HMAC SHA2-512 + */ +vchar_t * +eay_hmacsha2_512_one(key, data) + vchar_t *key, *data; +{ + return eay_hmac_one(key, data, EVP_sha2_512()); +} + +caddr_t +eay_hmacsha2_512_init(key) + vchar_t *key; +{ + return eay_hmac_init(key, EVP_sha2_512()); +} + +void +eay_hmacsha2_512_update(c, data) + caddr_t c; + vchar_t *data; +{ + HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l); +} + +vchar_t * +eay_hmacsha2_512_final(c) + caddr_t c; +{ + vchar_t *res; + unsigned int l; + + if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0) + return NULL; + + HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l); + res->l = l; + HMAC_cleanup((HMAC_CTX *)c); + (void)racoon_free(c); + + if (SHA512_DIGEST_LENGTH != res->l) { + plog(LLV_ERROR, LOCATION, NULL, + "hmac sha2_512 length mismatch %zd.\n", res->l); + vfree(res); + return NULL; + } + + return(res); +} + +/* + * HMAC SHA2-384 + */ +vchar_t * +eay_hmacsha2_384_one(key, data) + vchar_t *key, *data; +{ + return eay_hmac_one(key, data, EVP_sha2_384()); +} + +caddr_t +eay_hmacsha2_384_init(key) + vchar_t *key; +{ + return eay_hmac_init(key, EVP_sha2_384()); +} + +void +eay_hmacsha2_384_update(c, data) + caddr_t c; + vchar_t *data; +{ + HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l); +} + +vchar_t * +eay_hmacsha2_384_final(c) + caddr_t c; +{ + vchar_t *res; + unsigned int l; + + if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0) + return NULL; + + HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l); + res->l = l; + HMAC_cleanup((HMAC_CTX *)c); + (void)racoon_free(c); + + if (SHA384_DIGEST_LENGTH != res->l) { + plog(LLV_ERROR, LOCATION, NULL, + "hmac sha2_384 length mismatch %zd.\n", res->l); + vfree(res); + return NULL; + } + + return(res); +} + +/* + * HMAC SHA2-256 + */ +vchar_t * +eay_hmacsha2_256_one(key, data) + vchar_t *key, *data; +{ + return eay_hmac_one(key, data, EVP_sha2_256()); +} + +caddr_t +eay_hmacsha2_256_init(key) + vchar_t *key; +{ + return eay_hmac_init(key, EVP_sha2_256()); +} + +void +eay_hmacsha2_256_update(c, data) + caddr_t c; + vchar_t *data; +{ + HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l); +} + +vchar_t * +eay_hmacsha2_256_final(c) + caddr_t c; +{ + vchar_t *res; + unsigned int l; + + if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0) + return NULL; + + HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l); + res->l = l; + HMAC_cleanup((HMAC_CTX *)c); + (void)racoon_free(c); + + if (SHA256_DIGEST_LENGTH != res->l) { + plog(LLV_ERROR, LOCATION, NULL, + "hmac sha2_256 length mismatch %zd.\n", res->l); + vfree(res); + return NULL; + } + + return(res); +} +#endif /* WITH_SHA2 */ + +/* + * HMAC SHA1 + */ +vchar_t * +eay_hmacsha1_one(key, data) + vchar_t *key, *data; +{ + return eay_hmac_one(key, data, EVP_sha1()); +} + +caddr_t +eay_hmacsha1_init(key) + vchar_t *key; +{ + return eay_hmac_init(key, EVP_sha1()); +} + +void +eay_hmacsha1_update(c, data) + caddr_t c; + vchar_t *data; +{ + HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l); +} + +vchar_t * +eay_hmacsha1_final(c) + caddr_t c; +{ + vchar_t *res; + unsigned int l; + + if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0) + return NULL; + + HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l); + res->l = l; + HMAC_cleanup((HMAC_CTX *)c); + (void)racoon_free(c); + + if (SHA_DIGEST_LENGTH != res->l) { + plog(LLV_ERROR, LOCATION, NULL, + "hmac sha1 length mismatch %zd.\n", res->l); + vfree(res); + return NULL; + } + + return(res); +} + +/* + * HMAC MD5 + */ +vchar_t * +eay_hmacmd5_one(key, data) + vchar_t *key, *data; +{ + return eay_hmac_one(key, data, EVP_md5()); +} + +caddr_t +eay_hmacmd5_init(key) + vchar_t *key; +{ + return eay_hmac_init(key, EVP_md5()); +} + +void +eay_hmacmd5_update(c, data) + caddr_t c; + vchar_t *data; +{ + HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l); +} + +vchar_t * +eay_hmacmd5_final(c) + caddr_t c; +{ + vchar_t *res; + unsigned int l; + + if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0) + return NULL; + + HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l); + res->l = l; + HMAC_cleanup((HMAC_CTX *)c); + (void)racoon_free(c); + + if (MD5_DIGEST_LENGTH != res->l) { + plog(LLV_ERROR, LOCATION, NULL, + "hmac md5 length mismatch %zd.\n", res->l); + vfree(res); + return NULL; + } + + return(res); +} + +#ifdef WITH_SHA2 +/* + * SHA2-512 functions + */ +caddr_t +eay_sha2_512_init() +{ + SHA512_CTX *c = racoon_malloc(sizeof(*c)); + + SHA512_Init(c); + + return((caddr_t)c); +} + +void +eay_sha2_512_update(c, data) + caddr_t c; + vchar_t *data; +{ + SHA512_Update((SHA512_CTX *)c, (unsigned char *) data->v, data->l); + + return; +} + +vchar_t * +eay_sha2_512_final(c) + caddr_t c; +{ + vchar_t *res; + + if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0) + return(0); + + SHA512_Final((unsigned char *) res->v, (SHA512_CTX *)c); + (void)racoon_free(c); + + return(res); +} + +vchar_t * +eay_sha2_512_one(data) + vchar_t *data; +{ + return eay_digest_one(data, EVP_sha512()); +} + +int +eay_sha2_512_hashlen() +{ + return SHA512_DIGEST_LENGTH << 3; +} +#endif + +#ifdef WITH_SHA2 +/* + * SHA2-384 functions + */ +caddr_t +eay_sha2_384_init() +{ + SHA384_CTX *c = racoon_malloc(sizeof(*c)); + + SHA384_Init(c); + + return((caddr_t)c); +} + +void +eay_sha2_384_update(c, data) + caddr_t c; + vchar_t *data; +{ + SHA384_Update((SHA384_CTX *)c, (unsigned char *) data->v, data->l); + + return; +} + +vchar_t * +eay_sha2_384_final(c) + caddr_t c; +{ + vchar_t *res; + + if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0) + return(0); + + SHA384_Final((unsigned char *) res->v, (SHA384_CTX *)c); + (void)racoon_free(c); + + return(res); +} + +vchar_t * +eay_sha2_384_one(data) + vchar_t *data; +{ + return eay_digest_one(data, EVP_sha2_384()); +} + +int +eay_sha2_384_hashlen() +{ + return SHA384_DIGEST_LENGTH << 3; +} +#endif + +#ifdef WITH_SHA2 +/* + * SHA2-256 functions + */ +caddr_t +eay_sha2_256_init() +{ + SHA256_CTX *c = racoon_malloc(sizeof(*c)); + + SHA256_Init(c); + + return((caddr_t)c); +} + +void +eay_sha2_256_update(c, data) + caddr_t c; + vchar_t *data; +{ + SHA256_Update((SHA256_CTX *)c, (unsigned char *) data->v, data->l); + + return; +} + +vchar_t * +eay_sha2_256_final(c) + caddr_t c; +{ + vchar_t *res; + + if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0) + return(0); + + SHA256_Final((unsigned char *) res->v, (SHA256_CTX *)c); + (void)racoon_free(c); + + return(res); +} + +vchar_t * +eay_sha2_256_one(data) + vchar_t *data; +{ + return eay_digest_one(data, EVP_sha2_256()); +} + +int +eay_sha2_256_hashlen() +{ + return SHA256_DIGEST_LENGTH << 3; +} +#endif + +/* + * SHA functions + */ +caddr_t +eay_sha1_init() +{ + SHA_CTX *c = racoon_malloc(sizeof(*c)); + + SHA1_Init(c); + + return((caddr_t)c); +} + +void +eay_sha1_update(c, data) + caddr_t c; + vchar_t *data; +{ + SHA1_Update((SHA_CTX *)c, data->v, data->l); + + return; +} + +vchar_t * +eay_sha1_final(c) + caddr_t c; +{ + vchar_t *res; + + if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0) + return(0); + + SHA1_Final((unsigned char *) res->v, (SHA_CTX *)c); + (void)racoon_free(c); + + return(res); +} + +vchar_t * +eay_sha1_one(data) + vchar_t *data; +{ + return eay_digest_one(data, EVP_sha1()); +} + +int +eay_sha1_hashlen() +{ + return SHA_DIGEST_LENGTH << 3; +} + +/* + * MD5 functions + */ +caddr_t +eay_md5_init() +{ + MD5_CTX *c = racoon_malloc(sizeof(*c)); + + MD5_Init(c); + + return((caddr_t)c); +} + +void +eay_md5_update(c, data) + caddr_t c; + vchar_t *data; +{ + MD5_Update((MD5_CTX *)c, data->v, data->l); + + return; +} + +vchar_t * +eay_md5_final(c) + caddr_t c; +{ + vchar_t *res; + + if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0) + return(0); + + MD5_Final((unsigned char *) res->v, (MD5_CTX *)c); + (void)racoon_free(c); + + return(res); +} + +vchar_t * +eay_md5_one(data) + vchar_t *data; +{ + return eay_digest_one(data, EVP_md5()); +} + +int +eay_md5_hashlen() +{ + return MD5_DIGEST_LENGTH << 3; +} + +/* + * eay_set_random + * size: number of bytes. + */ +vchar_t * +eay_set_random(size) + u_int32_t size; +{ + BIGNUM *r = NULL; + vchar_t *res = 0; + + if ((r = BN_new()) == NULL) + goto end; + BN_rand(r, size * 8, 0, 0); + eay_bn2v(&res, r); + +end: + if (r) + BN_free(r); + return(res); +} + +/* DH */ +int +eay_dh_generate(prime, g, publen, pub, priv) + vchar_t *prime, **pub, **priv; + u_int publen; + u_int32_t g; +{ + BIGNUM *p = NULL; + DH *dh = NULL; + int error = -1; + + /* initialize */ + /* pre-process to generate number */ + if (eay_v2bn(&p, prime) < 0) + goto end; + + if ((dh = DH_new()) == NULL) + goto end; + dh->p = p; + p = NULL; /* p is now part of dh structure */ + dh->g = NULL; + if ((dh->g = BN_new()) == NULL) + goto end; + if (!BN_set_word(dh->g, g)) + goto end; + + if (publen != 0) + dh->length = publen; + + /* generate public and private number */ + if (!DH_generate_key(dh)) + goto end; + + /* copy results to buffers */ + if (eay_bn2v(pub, dh->pub_key) < 0) + goto end; + if (eay_bn2v(priv, dh->priv_key) < 0) { + vfree(*pub); + goto end; + } + + error = 0; + +end: + if (dh != NULL) + DH_free(dh); + if (p != 0) + BN_free(p); + return(error); +} + +int +eay_dh_compute(prime, g, pub, priv, pub2, key) + vchar_t *prime, *pub, *priv, *pub2, **key; + u_int32_t g; +{ + BIGNUM *dh_pub = NULL; + DH *dh = NULL; + int l; + unsigned char *v = NULL; + int error = -1; + + /* make public number to compute */ + if (eay_v2bn(&dh_pub, pub2) < 0) + goto end; + + /* make DH structure */ + if ((dh = DH_new()) == NULL) + goto end; + if (eay_v2bn(&dh->p, prime) < 0) + goto end; + if (eay_v2bn(&dh->pub_key, pub) < 0) + goto end; + if (eay_v2bn(&dh->priv_key, priv) < 0) + goto end; + dh->length = pub2->l * 8; + + dh->g = NULL; + if ((dh->g = BN_new()) == NULL) + goto end; + if (!BN_set_word(dh->g, g)) + goto end; + + if ((v = racoon_calloc(prime->l, sizeof(u_char))) == NULL) + goto end; + if ((l = DH_compute_key(v, dh_pub, dh)) == -1) + goto end; + memcpy((*key)->v + (prime->l - l), v, l); + + error = 0; + +end: + if (dh_pub != NULL) + BN_free(dh_pub); + if (dh != NULL) + DH_free(dh); + if (v != NULL) + racoon_free(v); + return(error); +} + +/* + * convert vchar_t <-> BIGNUM. + * + * vchar_t: unit is u_char, network endian, most significant byte first. + * BIGNUM: unit is BN_ULONG, each of BN_ULONG is in host endian, + * least significant BN_ULONG must come first. + * + * hex value of "0x3ffe050104" is represented as follows: + * vchar_t: 3f fe 05 01 04 + * BIGNUM (BN_ULONG = u_int8_t): 04 01 05 fe 3f + * BIGNUM (BN_ULONG = u_int16_t): 0x0104 0xfe05 0x003f + * BIGNUM (BN_ULONG = u_int32_t_t): 0xfe050104 0x0000003f + */ +int +eay_v2bn(bn, var) + BIGNUM **bn; + vchar_t *var; +{ + if ((*bn = BN_bin2bn((unsigned char *) var->v, var->l, NULL)) == NULL) + return -1; + + return 0; +} + +int +eay_bn2v(var, bn) + vchar_t **var; + BIGNUM *bn; +{ + *var = vmalloc(BN_num_bytes(bn)); + if (*var == NULL) + return(-1); + + (*var)->l = BN_bn2bin(bn, (unsigned char *) (*var)->v); + + return 0; +} + +void +eay_init() +{ + OpenSSL_add_all_algorithms(); + ERR_load_crypto_strings(); +#ifdef HAVE_OPENSSL_ENGINE_H + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); +#endif +} + +vchar_t * +base64_decode(char *in, long inlen) +{ + BIO *bio=NULL, *b64=NULL; + vchar_t *res = NULL; + char *outb; + long outlen; + + outb = malloc(inlen * 2); + if (outb == NULL) + goto out; + bio = BIO_new_mem_buf(in, inlen); + b64 = BIO_new(BIO_f_base64()); + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + bio = BIO_push(b64, bio); + + outlen = BIO_read(bio, outb, inlen * 2); + if (outlen <= 0) { + plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror()); + goto out; + } + + res = vmalloc(outlen); + if (!res) + goto out; + + memcpy(res->v, outb, outlen); + +out: + if (outb) + free(outb); + if (bio) + BIO_free_all(bio); + + return res; +} + +vchar_t * +base64_encode(char *in, long inlen) +{ + BIO *bio=NULL, *b64=NULL; + char *ptr; + long plen = -1; + vchar_t *res = NULL; + + bio = BIO_new(BIO_s_mem()); + b64 = BIO_new(BIO_f_base64()); + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + bio = BIO_push(b64, bio); + + BIO_write(bio, in, inlen); + BIO_flush(bio); + + plen = BIO_get_mem_data(bio, &ptr); + res = vmalloc(plen+1); + if (!res) + goto out; + + memcpy (res->v, ptr, plen); + res->v[plen] = '\0'; + +out: + if (bio) + BIO_free_all(bio); + + return res; +} + +static RSA * +binbuf_pubkey2rsa(vchar_t *binbuf) +{ + BIGNUM *exp, *mod; + RSA *rsa_pub = NULL; + + if (binbuf->v[0] > binbuf->l - 1) { + plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: decoded string doesn't make sense.\n"); + goto out; + } + + exp = BN_bin2bn((unsigned char *) (binbuf->v + 1), binbuf->v[0], NULL); + mod = BN_bin2bn((unsigned char *) (binbuf->v + binbuf->v[0] + 1), + binbuf->l - binbuf->v[0] - 1, NULL); + rsa_pub = RSA_new(); + + if (!exp || !mod || !rsa_pub) { + plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey parsing error: %s\n", eay_strerror()); + if (exp) + BN_free(exp); + if (mod) + BN_free(exp); + if (rsa_pub) + RSA_free(rsa_pub); + rsa_pub = NULL; + goto out; + } + + rsa_pub->n = mod; + rsa_pub->e = exp; + +out: + return rsa_pub; +} + +RSA * +base64_pubkey2rsa(char *in) +{ + BIGNUM *exp, *mod; + RSA *rsa_pub = NULL; + vchar_t *binbuf; + + if (strncmp(in, "0s", 2) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: doesn't start with '0s'\n"); + return NULL; + } + + binbuf = base64_decode(in + 2, strlen(in + 2)); + if (!binbuf) { + plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: Base64 decoding failed.\n"); + return NULL; + } + + if (binbuf->v[0] > binbuf->l - 1) { + plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: decoded string doesn't make sense.\n"); + goto out; + } + + rsa_pub = binbuf_pubkey2rsa(binbuf); + +out: + if (binbuf) + vfree(binbuf); + + return rsa_pub; +} + +RSA * +bignum_pubkey2rsa(BIGNUM *in) +{ + RSA *rsa_pub = NULL; + vchar_t *binbuf; + + binbuf = vmalloc(BN_num_bytes(in)); + if (!binbuf) { + plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey conversion: memory allocation failed..\n"); + return NULL; + } + + BN_bn2bin(in, (unsigned char *) binbuf->v); + + rsa_pub = binbuf_pubkey2rsa(binbuf); + +out: + if (binbuf) + vfree(binbuf); + + return rsa_pub; +} + +u_int32_t +eay_random() +{ + u_int32_t result; + vchar_t *vrand; + + vrand = eay_set_random(sizeof(result)); + memcpy(&result, vrand->v, sizeof(result)); + vfree(vrand); + + return result; +} + +const char * +eay_version() +{ + return SSLeay_version(SSLEAY_VERSION); +} diff --git a/ipsec-tools/src/racoon/crypto_openssl.h b/ipsec-tools/src/racoon/crypto_openssl.h new file mode 100644 index 00000000..66fac737 --- /dev/null +++ b/ipsec-tools/src/racoon/crypto_openssl.h @@ -0,0 +1,233 @@ +/* $NetBSD: crypto_openssl.h,v 1.7 2009/08/17 11:59:10 vanhu Exp $ */ + +/* Id: crypto_openssl.h,v 1.11 2004/11/13 11:28:01 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _CRYPTO_OPENSSL_H +#define _CRYPTO_OPENSSL_H + +#include +#include + +#define GENT_OTHERNAME GEN_OTHERNAME +#define GENT_EMAIL GEN_EMAIL +#define GENT_DNS GEN_DNS +#define GENT_X400 GEN_X400 +#define GENT_DIRNAME GEN_DIRNAME +#define GENT_EDIPARTY GEN_EDIPARTY +#define GENT_URI GEN_URI +#define GENT_IPADD GEN_IPADD +#define GENT_RID GEN_RID + +extern vchar_t *eay_str2asn1dn __P((const char *, int)); +extern vchar_t *eay_hex2asn1dn __P((const char *, int)); +extern int eay_cmp_asn1dn __P((vchar_t *, vchar_t *)); +extern int eay_check_x509cert __P((vchar_t *, char *, char *, int)); +extern vchar_t *eay_get_x509asn1subjectname __P((vchar_t *)); +extern int eay_get_x509subjectaltname __P((vchar_t *, char **, int *, int)); +extern vchar_t * eay_get_x509asn1issuername __P((vchar_t *)); +extern char *eay_get_x509text __P((vchar_t *)); +extern vchar_t *eay_get_x509cert __P((char *)); +extern vchar_t *eay_get_x509sign __P((vchar_t *, vchar_t *)); +extern int eay_check_x509sign __P((vchar_t *, vchar_t *, vchar_t *)); + +extern int eay_check_rsasign __P((vchar_t *, vchar_t *, RSA *)); +extern vchar_t *eay_get_rsasign __P((vchar_t *, RSA *)); + +/* RSA */ +extern vchar_t *eay_rsa_sign __P((vchar_t *, RSA *)); +extern int eay_rsa_verify __P((vchar_t *, vchar_t *, RSA *)); + +/* ASN.1 */ +extern vchar_t *eay_get_pkcs1privkey __P((char *)); +extern vchar_t *eay_get_pkcs1pubkey __P((char *)); + +/* string error */ +extern char *eay_strerror __P((void)); + +/* OpenSSL initialization */ +extern void eay_init __P((void)); + +/* Generic EVP */ +extern vchar_t *evp_crypt __P((vchar_t *data, vchar_t *key, vchar_t *iv, + const EVP_CIPHER *e, int enc)); +extern int evp_weakkey __P((vchar_t *key, const EVP_CIPHER *e)); +extern int evp_keylen __P((int len, const EVP_CIPHER *e)); + +/* DES */ +extern vchar_t *eay_des_encrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern vchar_t *eay_des_decrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern int eay_des_weakkey __P((vchar_t *)); +extern int eay_des_keylen __P((int)); + +/* IDEA */ +extern vchar_t *eay_idea_encrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern vchar_t *eay_idea_decrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern int eay_idea_weakkey __P((vchar_t *)); +extern int eay_idea_keylen __P((int)); + +/* blowfish */ +extern vchar_t *eay_bf_encrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern vchar_t *eay_bf_decrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern int eay_bf_weakkey __P((vchar_t *)); +extern int eay_bf_keylen __P((int)); + +/* RC5 */ +extern vchar_t *eay_rc5_encrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern vchar_t *eay_rc5_decrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern int eay_rc5_weakkey __P((vchar_t *)); +extern int eay_rc5_keylen __P((int)); + +/* 3DES */ +extern vchar_t *eay_3des_encrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern vchar_t *eay_3des_decrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern int eay_3des_weakkey __P((vchar_t *)); +extern int eay_3des_keylen __P((int)); + +/* CAST */ +extern vchar_t *eay_cast_encrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern vchar_t *eay_cast_decrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern int eay_cast_weakkey __P((vchar_t *)); +extern int eay_cast_keylen __P((int)); + +/* AES(RIJNDAEL) */ +extern vchar_t *eay_aes_encrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern vchar_t *eay_aes_decrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern int eay_aes_weakkey __P((vchar_t *)); +extern int eay_aes_keylen __P((int)); + +#if defined(HAVE_OPENSSL_CAMELLIA_H) +/* Camellia */ +extern vchar_t *eay_camellia_encrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern vchar_t *eay_camellia_decrypt __P((vchar_t *, vchar_t *, vchar_t *)); +extern int eay_camellia_weakkey __P((vchar_t *)); +extern int eay_camellia_keylen __P((int)); +#endif + +/* misc */ +extern int eay_null_keylen __P((int)); +extern int eay_null_hashlen __P((void)); +extern int eay_kpdk_hashlen __P((void)); +extern int eay_twofish_keylen __P((int)); + +/* hash */ +#if defined(WITH_SHA2) +/* HMAC SHA2 */ +extern vchar_t *eay_hmacsha2_512_one __P((vchar_t *, vchar_t *)); +extern caddr_t eay_hmacsha2_512_init __P((vchar_t *)); +extern void eay_hmacsha2_512_update __P((caddr_t, vchar_t *)); +extern vchar_t *eay_hmacsha2_512_final __P((caddr_t)); +extern vchar_t *eay_hmacsha2_384_one __P((vchar_t *, vchar_t *)); +extern caddr_t eay_hmacsha2_384_init __P((vchar_t *)); +extern void eay_hmacsha2_384_update __P((caddr_t, vchar_t *)); +extern vchar_t *eay_hmacsha2_384_final __P((caddr_t)); +extern vchar_t *eay_hmacsha2_256_one __P((vchar_t *, vchar_t *)); +extern caddr_t eay_hmacsha2_256_init __P((vchar_t *)); +extern void eay_hmacsha2_256_update __P((caddr_t, vchar_t *)); +extern vchar_t *eay_hmacsha2_256_final __P((caddr_t)); +#endif +/* HMAC SHA1 */ +extern vchar_t *eay_hmacsha1_one __P((vchar_t *, vchar_t *)); +extern caddr_t eay_hmacsha1_init __P((vchar_t *)); +extern void eay_hmacsha1_update __P((caddr_t, vchar_t *)); +extern vchar_t *eay_hmacsha1_final __P((caddr_t)); +/* HMAC MD5 */ +extern vchar_t *eay_hmacmd5_one __P((vchar_t *, vchar_t *)); +extern caddr_t eay_hmacmd5_init __P((vchar_t *)); +extern void eay_hmacmd5_update __P((caddr_t, vchar_t *)); +extern vchar_t *eay_hmacmd5_final __P((caddr_t)); + +#if defined(WITH_SHA2) +/* SHA2 functions */ +extern caddr_t eay_sha2_512_init __P((void)); +extern void eay_sha2_512_update __P((caddr_t, vchar_t *)); +extern vchar_t *eay_sha2_512_final __P((caddr_t)); +extern vchar_t *eay_sha2_512_one __P((vchar_t *)); +#endif +extern int eay_sha2_512_hashlen __P((void)); + +#if defined(WITH_SHA2) +extern caddr_t eay_sha2_384_init __P((void)); +extern void eay_sha2_384_update __P((caddr_t, vchar_t *)); +extern vchar_t *eay_sha2_384_final __P((caddr_t)); +extern vchar_t *eay_sha2_384_one __P((vchar_t *)); +#endif +extern int eay_sha2_384_hashlen __P((void)); + +#if defined(WITH_SHA2) +extern caddr_t eay_sha2_256_init __P((void)); +extern void eay_sha2_256_update __P((caddr_t, vchar_t *)); +extern vchar_t *eay_sha2_256_final __P((caddr_t)); +extern vchar_t *eay_sha2_256_one __P((vchar_t *)); +#endif +extern int eay_sha2_256_hashlen __P((void)); + +/* SHA functions */ +extern caddr_t eay_sha1_init __P((void)); +extern void eay_sha1_update __P((caddr_t, vchar_t *)); +extern vchar_t *eay_sha1_final __P((caddr_t)); +extern vchar_t *eay_sha1_one __P((vchar_t *)); +extern int eay_sha1_hashlen __P((void)); + +/* MD5 functions */ +extern caddr_t eay_md5_init __P((void)); +extern void eay_md5_update __P((caddr_t, vchar_t *)); +extern vchar_t *eay_md5_final __P((caddr_t)); +extern vchar_t *eay_md5_one __P((vchar_t *)); +extern int eay_md5_hashlen __P((void)); + +/* RNG */ +extern vchar_t *eay_set_random __P((u_int32_t)); +extern u_int32_t eay_random __P((void)); + +/* DH */ +extern int eay_dh_generate __P((vchar_t *, u_int32_t, u_int, vchar_t **, vchar_t **)); +extern int eay_dh_compute __P((vchar_t *, u_int32_t, vchar_t *, vchar_t *, vchar_t *, vchar_t **)); + +/* Base 64 */ +vchar_t *base64_encode(char *in, long inlen); +vchar_t *base64_decode(char *in, long inlen); + +RSA *base64_pubkey2rsa(char *in); +RSA *bignum_pubkey2rsa(BIGNUM *in); + +/* misc */ +extern int eay_revbnl __P((vchar_t *)); +#include +extern int eay_v2bn __P((BIGNUM **, vchar_t *)); +extern int eay_bn2v __P((vchar_t **, BIGNUM *)); + +extern const char *eay_version __P((void)); + +#define CBC_BLOCKLEN 8 +#define IPSEC_ENCRYPTKEYLEN 8 + +#endif /* _CRYPTO_OPENSSL_H */ diff --git a/ipsec-tools/src/racoon/debug.h b/ipsec-tools/src/racoon/debug.h new file mode 100644 index 00000000..4270b6a3 --- /dev/null +++ b/ipsec-tools/src/racoon/debug.h @@ -0,0 +1,42 @@ +/* $NetBSD: debug.h,v 1.5 2008/12/23 14:03:12 tteras Exp $ */ + +/* Id: debug.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _DEBUG_H +#define _DEBUG_H + +/* define by main.c */ +extern int f_local; +extern int vflag; +extern int dump_config; + +#endif /* _DEBUG_H */ diff --git a/ipsec-tools/src/racoon/debugrm.h b/ipsec-tools/src/racoon/debugrm.h new file mode 100644 index 00000000..6a2f411e --- /dev/null +++ b/ipsec-tools/src/racoon/debugrm.h @@ -0,0 +1,102 @@ +/* $NetBSD: debugrm.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: debugrm.h,v 1.4 2006/04/06 14:00:06 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _DEBUGRM_H +#define _DEBUGRM_H + +#define DRMDUMPFILE "/var/tmp/debugrm.dump" + +#ifdef NONEED_DRM +#ifndef racoon_malloc +#define racoon_malloc(sz) malloc((sz)) +#endif +#ifndef racoon_calloc +#define racoon_calloc(cnt, sz) calloc((cnt), (sz)) +#endif +#ifndef racoon_realloc +#define racoon_realloc(old, sz) realloc((old), (sz)) +#endif +#ifndef racoon_free +#define racoon_free(p) free((p)) +#endif +#ifndef racoon_strdup +#define racoon_strdup(p) strdup((p)) +#endif +#else /*!NONEED_DRM*/ +#ifndef racoon_malloc +#define racoon_malloc(sz) \ + DRM_malloc(__FILE__, __LINE__, __func__, (sz)) +#endif +#ifndef racoon_calloc +#define racoon_calloc(cnt, sz) \ + DRM_calloc(__FILE__, __LINE__, __func__, (cnt), (sz)) +#endif +#ifndef racoon_realloc +#define racoon_realloc(old, sz) \ + DRM_realloc(__FILE__, __LINE__, __func__, (old), (sz)) +#endif +#ifndef racoon_free +#define racoon_free(p) \ + DRM_free(__FILE__, __LINE__, __func__, (p)) +#endif +#ifndef racoon_strdup +#define racoon_strdup(p) \ + DRM_strdup(__FILE__, __LINE__, __func__, (p)) +#endif +#endif /*NONEED_DRM*/ + +extern void DRM_init __P((void)); +extern void DRM_dump __P((void)); +extern void *DRM_malloc __P((char *, int, char *, size_t)); +extern void *DRM_calloc __P((char *, int, char *, size_t, size_t)); +extern void *DRM_realloc __P((char *, int, char *, void *, size_t)); +extern void DRM_free __P((char *, int, char *, void *)); +extern char *DRM_strdup __P((char *, int, char *, const char *)); + +#ifndef NONEED_DRM +#define vmalloc(sz) \ + DRM_vmalloc(__FILE__, __LINE__, __func__, (sz)) +#define vdup(old) \ + DRM_vdup(__FILE__, __LINE__, __func__, (old)) +#define vrealloc(old, sz) \ + DRM_vrealloc(__FILE__, __LINE__, __func__, (old), (sz)) +#define vfree(p) \ + DRM_vfree(__FILE__, __LINE__, __func__, (p)) +#endif + +extern void *DRM_vmalloc __P((char *, int, char *, size_t)); +extern void *DRM_vrealloc __P((char *, int, char *, void *, size_t)); +extern void DRM_vfree __P((char *, int, char *, void *)); +extern void *DRM_vdup __P((char *, int, char *, void *)); + +#endif /* _DEBUGRM_H */ diff --git a/ipsec-tools/src/racoon/dhgroup.h b/ipsec-tools/src/racoon/dhgroup.h new file mode 100644 index 00000000..54d7eebb --- /dev/null +++ b/ipsec-tools/src/racoon/dhgroup.h @@ -0,0 +1,205 @@ +/* $NetBSD: dhgroup.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: dhgroup.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _DHGROUP_H +#define _DHGROUP_H + +#define OAKLEY_PRIME_MODP768 \ + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \ + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \ + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \ + "E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF" + +#define OAKLEY_PRIME_MODP1024 \ + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \ + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \ + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \ + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \ + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381" \ + "FFFFFFFF FFFFFFFF" + +#define OAKLEY_PRIME_MODP1536 \ + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \ + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \ + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \ + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \ + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \ + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \ + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \ + "670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF" + +/* RFC 3526 */ +#define OAKLEY_PRIME_MODP2048 \ + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \ + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \ + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \ + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \ + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \ + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \ + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \ + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \ + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \ + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \ + "15728E5A 8AACAA68 FFFFFFFF FFFFFFFF" + +#define OAKLEY_PRIME_MODP3072 \ + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \ + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \ + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \ + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \ + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \ + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \ + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \ + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \ + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \ + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \ + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \ + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \ + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \ + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \ + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \ + "43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF" + +#define OAKLEY_PRIME_MODP4096 \ + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \ + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \ + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \ + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \ + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \ + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \ + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \ + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \ + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \ + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \ + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \ + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \ + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \ + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \ + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \ + "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" \ + "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" \ + "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" \ + "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" \ + "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" \ + "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199" \ + "FFFFFFFF FFFFFFFF" + +#define OAKLEY_PRIME_MODP6144 \ + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \ + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \ + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \ + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \ + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \ + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \ + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \ + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \ + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \ + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \ + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \ + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \ + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \ + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \ + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \ + "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" \ + "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" \ + "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" \ + "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" \ + "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" \ + "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" \ + "36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" \ + "F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" \ + "179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" \ + "DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" \ + "5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" \ + "D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" \ + "23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" \ + "CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" \ + "06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" \ + "DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" \ + "12BF2D5B 0B7474D6 E694F91E 6DCC4024 FFFFFFFF FFFFFFFF" + +#define OAKLEY_PRIME_MODP8192 \ + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \ + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \ + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \ + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \ + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \ + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \ + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \ + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \ + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \ + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \ + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \ + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \ + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \ + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \ + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \ + "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" \ + "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" \ + "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" \ + "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" \ + "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" \ + "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" \ + "36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" \ + "F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" \ + "179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" \ + "DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" \ + "5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" \ + "D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" \ + "23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" \ + "CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" \ + "06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" \ + "DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" \ + "12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4" \ + "38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300" \ + "741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568" \ + "3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9" \ + "22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B" \ + "4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A" \ + "062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36" \ + "4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1" \ + "B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92" \ + "4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47" \ + "9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71" \ + "60C980DD 98EDD3DF FFFFFFFF FFFFFFFF" + +extern struct dhgroup dh_modp768; +extern struct dhgroup dh_modp1024; +extern struct dhgroup dh_modp1536; +extern struct dhgroup dh_modp2048; +extern struct dhgroup dh_modp3072; +extern struct dhgroup dh_modp4096; +extern struct dhgroup dh_modp6144; +extern struct dhgroup dh_modp8192; + +#endif /* _DHGROUP_H */ diff --git a/ipsec-tools/src/racoon/dnssec.c b/ipsec-tools/src/racoon/dnssec.c new file mode 100644 index 00000000..d52a243f --- /dev/null +++ b/ipsec-tools/src/racoon/dnssec.c @@ -0,0 +1,137 @@ +/* $NetBSD: dnssec.c,v 1.5 2009/03/12 10:57:26 tteras Exp $ */ + +/* $KAME: dnssec.c,v 1.2 2001/08/05 18:46:07 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "var.h" +#include "vmbuf.h" +#include "misc.h" +#include "plog.h" +#include "debug.h" + +#include "isakmp_var.h" +#include "isakmp.h" +#include "ipsec_doi.h" +#include "oakley.h" +#include "netdb_dnssec.h" +#include "strnames.h" +#include "dnssec.h" +#include "gcmalloc.h" + +extern int h_errno; + +vchar_t * +dnssec_getcert(id) + vchar_t *id; +{ + vchar_t *cert = NULL; + struct certinfo *res = NULL; + struct ipsecdoi_id_b *id_b; + int type; + char *name = NULL; + int namelen; + int error; + + id_b = (struct ipsecdoi_id_b *)id->v; + + namelen = id->l - sizeof(*id_b); + name = racoon_malloc(namelen + 1); + if (!name) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer.\n"); + return NULL; + } + memcpy(name, id_b + 1, namelen); + name[namelen] = '\0'; + + switch (id_b->type) { + case IPSECDOI_ID_FQDN: + error = getcertsbyname(name, &res); + if (error != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "getcertsbyname(\"%s\") failed.\n", name); + goto err; + } + break; + case IPSECDOI_ID_IPV4_ADDR: + case IPSECDOI_ID_IPV6_ADDR: + /* XXX should be processed to query PTR ? */ + default: + plog(LLV_ERROR, LOCATION, NULL, + "inpropper ID type passed %s " + "though getcert method is dnssec.\n", + s_ipsecdoi_ident(id_b->type)); + goto err; + } + + /* check response */ + if (res->ci_next != NULL) { + plog(LLV_WARNING, LOCATION, NULL, + "not supported multiple CERT RR.\n"); + } + switch (res->ci_type) { + case DNSSEC_TYPE_PKIX: + /* XXX is it enough condition to set this type ? */ + type = ISAKMP_CERT_X509SIGN; + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "not supported CERT RR type %d.\n", res->ci_type); + goto err; + } + + /* create cert holder */ + cert = vmalloc(res->ci_certlen + 1); + if (cert == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get cert buffer.\n"); + goto err; + } + cert->v[0] = type; + memcpy(&cert->v[1], res->ci_cert, res->ci_certlen); + + plog(LLV_DEBUG, LOCATION, NULL, "created CERT payload:\n"); + plogdump(LLV_DEBUG, cert->v, cert->l); + +err: + if (name) + racoon_free(name); + if (res) + freecertinfo(res); + return cert; +} diff --git a/ipsec-tools/src/racoon/dnssec.h b/ipsec-tools/src/racoon/dnssec.h new file mode 100644 index 00000000..1a03d770 --- /dev/null +++ b/ipsec-tools/src/racoon/dnssec.h @@ -0,0 +1,39 @@ +/* $NetBSD: dnssec.h,v 1.5 2009/03/12 10:57:26 tteras Exp $ */ + +/* Id: dnssec.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _DNSSEC_H +#define _DNSSEC_H + +extern vchar_t *dnssec_getcert __P((vchar_t *)); + +#endif /* _DNSSEC_H */ diff --git a/ipsec-tools/src/racoon/doc/FAQ b/ipsec-tools/src/racoon/doc/FAQ new file mode 100644 index 00000000..cf9c3947 --- /dev/null +++ b/ipsec-tools/src/racoon/doc/FAQ @@ -0,0 +1,114 @@ +This document is derived from the KAME racoon FAQ. Some answers do not +apply to ipsec-tools (they are obsolete or not up to date). They are +tagged [KAME] + +Q: With what other IKE/IPsec implementation racoon is known to be interoperable? + +A: [KAME] + See "IMPLEMENTATION" document supplied with KAME kit, or: + http://www.kame.net/dev/cvsweb.cgi/kame/IMPLEMENTATION + As we have tested/got test reports in the past, and our end and + the other end may have changed their implemenations, we are not sure + if we can interoperate with them today (we hope them to interoperate, + but we are not sure). + Also note that, IKE interoperability highly depends on configuration + on both ends. You must configure both ends exactly the same. + +Q: How can I make racoon interoperate with ? + +A: + Configure both ends exactly the same. With just a tiny little + difference, you will be in trouble. + +Q: How to build racoon on my platform? + +A: + As usual: configure && make && make install + ipsec-tools is also available as a package in the NetBSD pkgsrc + +Q: Describe me the options to "configure". + +A: + --enable-adminport: + Lets racoon to listen to racoon admin port, which is to + be contacted by racoonctl(8). + --enable-natt: + Enable NAT-Traversal. This needs kernel support, which is + available on Linux. On NetBSD, NAT-Traversal kernel support + has not been integrated yet, you can get it from here: + http://ipsec-tools.sourceforge.net/netbsd_nat-t.diff + If you live in a country where software patents are legal, + using NAT-Traversal might infringe a patent. + --enable-broken-natt: + When ipsec-tools is built with --enable-natt, racoon + sets IKE ports in SAD and SPD so that the kernel is + able to ditinguish peers hidden behind the same NAT. + Some kernel will not cope with that ports. Use that + option to force the ports to 0 in SAD ans SPD. Of + course this means that you cannot have multiple peers + behind the same NAT. + --enable-frag: + Enable IKE fragmentation, which is a workaround for + broken routers that drop fragmented packets + --enable-hybrid: + Enable hybrid authentication, and ISAKMP mode config and + Xauth as well. Note that plain Xauth (without hybrid auth) + is not implemented. + --with-libradius: + Enable the use of RADIUS with hybrid authentication on the + server side. RADIUS is used for authentication, configuration + and accounting. + --with-libpam: + Enable the use of PAM with hybrid authentication on the + server side. PAM can be used for authentication and accounting. + --enable-gssapi: + Enable GSS-API, for Kerberos V support. + --enable-stats: + Enable statistics logging function. + --enable-samode-unspec: + Enable to use unspecified a mode of SA. + --enable-ipv6: + Enable IPv6 support. + --with-kernel-headers: + Supply the location of Linux kernel headers. + --with-readline: + Support readline input (yes by default). + --with-openssl: + Specify OpenSSL directory. + --sysconfdir: + Where racoon config file goes. Default is /etc, which means + that racoon will look for /etc/racoon.conf + --localstatedir: + Where is the directory where racoon stores the control socket + (when using --enable-adminport). Default is /var, which + means racoon will use /var/racoon/racoon.sock + --prefix: + Where racoon gets installed. + +Q: How can I get help? + +A: + Always identify your operating system platforms, the versions you are + using (like "ipsec-tools-0.5"), and information to repeat the + problem. The more revelant information you supply, the better your + chances of getting help are. Useful informations include, depending + of the problem: + - version identification + - trace from racoon, taken by "racoon -d 0xffffffff" + (maximum debug level) + - configuration file you are using + - probabaly, tcpdump trace + http://orange.kame.net/dev/send-pr.html has the guideline. + + If your question is not confidential, send your questions to: + + + If your question is confidential, send your questions to: + + +Q: Other documents to look at? + +A: + http://www.NetBSD.org/docs/network/ipsec/ + http://www.kame.net/ + http://www.kame.net/newsletter/ diff --git a/ipsec-tools/src/racoon/doc/README.certificate b/ipsec-tools/src/racoon/doc/README.certificate new file mode 100644 index 00000000..a8bbfa2b --- /dev/null +++ b/ipsec-tools/src/racoon/doc/README.certificate @@ -0,0 +1 @@ +See http://www.kame.net/newsletter/20001119b/ diff --git a/ipsec-tools/src/racoon/doc/README.gssapi b/ipsec-tools/src/racoon/doc/README.gssapi new file mode 100644 index 00000000..9cb3fbb5 --- /dev/null +++ b/ipsec-tools/src/racoon/doc/README.gssapi @@ -0,0 +1,106 @@ +The gss-api authentication mechanism implementation for racoon was +based on the ietf draft draft-ietf-ipsec-isakmp-gss-auth-06.txt. + +The implementation uses the Heimdal gss-api library, i.e. gss-api +on top of Kerberos 5. The Heimdal gss-api library had to be modified +to meet the requirements of using gss-api in a daemon. More specifically, +the gss_acquire_cred() call did not work for other cases than +GSS_C_NO_CREDENTIAL ("use default creds"). Daemons are often started +as root, and have no Kerberos 5 credentials, so racoon explicitly +needs to acquire its credentials. The usual method (already used +by login authentication daemons) in these situations is to add +a set of special credentials to be used. For example, authentication +by daemons concerned with login credentials, uses 'host/fqdn' as +its credential, where fqdn is the hostname on the interface that +is being used. These special credentials need to be extracted into +a local keytab from the kdc. The default value used in racoon +is 'ike/fqdn', but it can be overridden in the racoon config file. + +The modification to the Heimdal gss-api library implements the +mechanism above. If a credential other than GSS_C_NO_CREDENTIAL +is specified to gss_acquire_cred(), it first looks in the default +credential cache if it its principal matches the desired credential. +If not, it extracts it from the default keytab file, and stores +it in a memory-based credential cache, part of the gss credential +structure. + + + +The modifcations to racoon itself are as follows: + + * The racoon.conf config file accepts a new keyword, "gssapi_id", + to be used inside a proposal specification. It specifies + a string (a Kerberos 5 principal in this case), specifying the + credential that racoon will try to acquire. The default value + is 'ike/fqdn', where fqdn is the hostname for the interface + being used for the exchange. If the id is not specified, no + GSS endpoint attribute will be specified in the first SA sent. + However, if the initiator does specify a GSS endpoint attribute, + racoon will always respond with its own GSS endpoint name + in the SA (the default one if not specified by this option). + + * The racoon.conf file accepts "gssapi_krb" as authentication + method inside a proposal specification. The number used + for this method is 65001, which is a temporary number as + specified in the draft. + + * The cftoken.l and cfparse.y source files were modified to + pick up the configuration options. The original sources + stored algorithms in bitmask, which unfortunately meant + that the maximum value was 32, clearly not enough for 65001. + After consulting with the author (sakane@kame.net), it turned + out that method was a leftover, and no longer needed. I replaced + it with plain integers. + + * The gss-api specific code was concentrated as much as possible + in gssapi.c and gssapi.h. The code to call functions defined + in these files is conditional on HAVE_GSSAPI, except for the + config scan code. Specifying this flag on the compiler commandline + is conditional on the --enable-gssapi option to the configure + script. + + * Racoon seems to want to send accepted SA proposals back to + the initiator in a verbatim fashion, leaving no room to + insert the (variable-length) GSS endpoint name attribute. + I worked around this by re-assembling the extracted SA + into a new SA if the gssapi_krb method is used, and the + initiator sent the name attribute. This scheme should + possibly be re-examined by the racoon maintainers, storing + the SAs (the transformations, to be more precise) in a different + fashion to allow for variable-length attributes to be + re-inserted would be a good change, but I considered it to be + beyond the scope of this project. + + * The various state functions for aggressive and main mode + (in isakmp_agg.c and isakmp_ident.c respectively) were + changed to conditionally change their behavior if the + gssapi_krb method is specified. + + +This implementation tried to follow the specification in the ietf draft +as close as possible. However, it has not been tested against other +IKE daemon implementations. The only other one I know of is Windows 2000, +and it has some caveats. I attempted to be Windows 2000 compatible. +Should racoon be tried against Windows 2000, the gssapi_id option in +the config file must be used, as Windows 2000 expects the GSS endpoint +name to be sent at all times. I have my doubts as to the W2K compatibility, +because the spec describes the GSS endpoint name sent by W2K as +an unicode string 'xxx@domain', which doesn't seem to match the +required standard for gss-api + kerberos 5 (i.e. I am fairly certain +that such a string will be rejected by the Heimdal gss-api library, as it +is not a valid Kerberos 5 principal). + +With the Heimdal gss-api implementation, the gssapi_krb authentication +method will only work in main mode. Aggressive mode does not allow +for the extra round-trips needed by gss_init_sec_context and +gss_accept_sec_context when mutual authentication is requested. +The draft specifies that the a fallback should be done to main mode, +through the return of INVALID-EXCHANGE-TYPE if it turns out that +the gss-api mechanisms needs more roundtrips. This is implemented. +Unfortunately, racoon does not seem to properly fall back to +its next mode, and this is not specific to the gssapi_krb method. +So, to avoid problems, only specify main mode in the config file. + + + -- Frank van der Linden + diff --git a/ipsec-tools/src/racoon/doc/README.plainrsa b/ipsec-tools/src/racoon/doc/README.plainrsa new file mode 100644 index 00000000..36de09c4 --- /dev/null +++ b/ipsec-tools/src/racoon/doc/README.plainrsa @@ -0,0 +1,109 @@ +HOW-TO use plainrsa auth, contributed by Simon Chang + +Before you begin, you should understand that the RSA authentication +mechanism hinges upon the idea of a split cryptographic key: one used +by the public, the other readable only to you. Any data that is +encrypted by a public key can be decrypted only by the corresponding +private key, so that the private key user can be assured that the +content of the transmission has not been examined by unauthorized +parties. Similarly, any data encrypted by the private key can be +decrypted by the public key so that the public knows that this +transmission came from this user and nobody else (this idea is called +non-repudiation). Also, the longer the key length, the more difficult +it would be for potential attacker to conduct brute-force discovery of +the keys. So, what all this means for the security administrator is +that the setup needs a pair of reasonably long keys for each host that +wishes to authenticate in this manner. + +With this in mind, it should be relatively straightforward to set up +RSA authentication. For the purpose of this document, we assume that +we are setting up RSA authentication between two networked hosts +called Boston and Chicago. Unless otherwise noted, all steps should +be performed on both hosts with corresponding key names. Here are the +steps: + +1) Included in each default installation of ipsec-tools is a binary +called plainrsa-gen. This executable is used to generate a pair of +RSA keys for the host. There are only two parameters that you should +be concerned about: -b, which sets the number of bits for the keys, +and -f, which specifies the output file for plainrsa-gen to send the +results. On an ordinary Pentium-II with 128 MB of RAM, it takes only +seconds to generate keys that are 2048 bits long, and only slightly +longer to generate 4096-bit keys. Either key length should be +sufficient; any longer key length actually reduces performance and +does not increase security significantly. You should therefore run it +as: + + plainrsa-gen -b 2048 -f /var/tmp/boston.keys + +2) When the process completes, you should have a text file that +includes both public and private keys. GUARD THIS FILE CAREFULLY, +because once a private key is compromised it is no longer any good, +and you must generate a new pair from scratch. Reading the file +itself, you should see several very long lines of alphanumeric data. +The only line you should be concerned with is the line towards the top +of the output file that begins with "# pubkey=0sAQPAmBdT/" or +something to that effect. This line is your public key, which should +be made available to the other host that you are setting up. Copy +this line to a separate file called "boston.pub" and change the +beginning of the line so that it reads ": PUB 0sAQPAmBdT/". +Alternatively, you can also grab the first line of the boston.keys +file and uncomment the line so that it reads the same as above. Now +rename the file you generated initially to "boston.priv". + +3) You should now have two files, boston.priv and boston.pub +(chicago.priv and chicago.pub on Chicago). The first file contains +your private key and the second file your public key. Next you should +find a way to get the public key over to the other host involved. +Boston should have (1) its own key pair, and (2) Chicago's public key +ONLY. Do not copy Chicago's private key over to Boston, because (a) +it is not necessary, and (b) you would now have two potential places +for losing control of your private key. + +4) You should now configure the racoon.conf configuration file for +each host to (a) turn on RSA authentication, and (b) designate each +host's private key and the remote host(s)'s public key(s). Take all +your keys and place it in one directory and use the global directive +"path certificate" to specify the location of the keys. This step is +especially important if you are running racoon with privilege +separation, because if racoon cannot find the keys inside the +directory you have just specified it will fail the authentication +process. So, write the directive like the following: + + path certificate "/etc/racoon"; + +Next, you need to specify the host's own private key and the public +keys of all the remote peers involved. For your local private key and +remote public key(s), you should use the following directives: + + certificate_type plain_rsa "/etc/racoon/boston.priv"; + peers_certfile plain_rsa "/etc/racoon/chicago.pub"; + +Notice the option "plain_rsa" for both directives. + +Finally, under the "proposal" statement section, you should specify +the "rsasig" option for "authentication_method". + +5) You have finished configuring the host for RSA authentication. +Now use racoonctl to reload the configuration or simply restart the +machine and you should be all set. + +TROUBLESHOOTING + +In the event that the hosts fail to communicate, first go back to the +instructions above and make sure that: + +1) You have placed all the keys in the directory that is specified by +the "path certificate" directive. Keep in mind that privilege +separation will force racoon to look into that directory and nowhere +else. +2) You have specified correctly the host's own private key and the +remote peer's public key. +3) You have specified the "rsasig" method for authentication in the +proposal statement. + +If you run into any further problems, you should try to use "racoon +-v" to debug the setup, and send a copy of the debug messages to the +mailing list so that we can help you determine what the problem is. + +Last modified: $Date: 2006/12/10 05:51:14 $ diff --git a/ipsec-tools/src/racoon/doc/README.privsep b/ipsec-tools/src/racoon/doc/README.privsep new file mode 100644 index 00000000..e01c8207 --- /dev/null +++ b/ipsec-tools/src/racoon/doc/README.privsep @@ -0,0 +1,152 @@ + Using Racoon with Privilege Separation + Tue Mar 25 16:37:09 MDT 2008 + + +Racoon can run in a chroot'd environment. When so instructed, it runs as two +processes, one of which handles a small number of simple requests and runs as +root in the full native filesystem, and another which runs as a less +privileged user in a chroot'd environment and which handles all the other and +very complex business of racoon. + +Because racoon does many complex things there are many opportunities for +coding errors to lead to compromises and so this separation is important. If +someone breaks into your system using racoon and you have enabled privilege +separation, they will find themselves in a very limited environment and unable +to do much damage. They may be able to alter the host's security associations +or obtain the private keys stored on that system using file descriptors +available to the unprivileged instance of racoon, and from there they will be +able to alter security associations on other hosts in disruptive or dangerous +ways if you have generate_policy enabled on those hosts. But that's because +in its current form generate_policy is itself dangerous and requires that you +trust anyone with the credentials to use it. + +They will also be able to execute any scripts you have placed in the scripts +directory, although racoon will prevent them from mis-using the traditional +environment variables PATH, LD_LIBRARY_PATH, and IFS. But if you have +introduced vulnerabilities into your scripts you may want to re-visit them. +The thing to watch for is blindly trusting the environment variables passed +in by racoon - assume they could be set to anything by a malicious entity and +check them for suitability before using them. + +All these possibilities are present when privilege separation is not enabled, +and they are greatly reduced when it is enabled because the resources +available to the attacker are less. + +***** + +The basic concept with racoon's privilege separation is that a minimal +environment containing all the files racoon needs to operate - with the +exception of private keys, scripts, and system-wide authentication services - +is placed in a stripped-down copy of the original environment. The private +keys and scripts are left in the original environment where only the +privileged instance of racoon will have access to them. + +Here are basic instructions for setting up racoon to run with privilege +separation: + + +First, create a user/group for racoon to run under. For example, user:group +ike:ike. The account should not have a usable password or real home +directory, so copy the general format of another system-services type account +such as 'daemon'. + +You already have files in, e.g. /usr/local/etc/racoon - perhaps racoon.conf, a +certs directory containing certificates, a scripts directory, and other +miscellaneous files such as welcome messages. Perform the following steps: + +cd /usr/local/etc/racoon +mkdir root +mv certs root +mkdir certs +mv root/certs/*.key certs + +If you want to be able to switch back and forth between using and not using +privsep, do this too: + +cd /usr/local/etc/racoon/certs +for i in ../root/certs/* +do + ln -s $i . +done + +Now root/certs contains certificates and certs contains the keys. The idea is +that the public certificates are in the chroot'd area +(/usr/local/etc/racoon/root) and the keys are available only to the privileged +instance of racoon. + +Move any other racoon configuration data into /usr/local/etc/racoon/root, +with the exception of the scripts directory and racoon.conf. + +All the files in /usr/local/etc/racoon/root should be owned by root and the +ike:ike user you created should not have write access to any directories or +files (unless you are using something like 'path backupsa', but you get the +idea). + +Create the device nodes: + +mkdir root/dev + +Do whatever your OS requires to populate the new dev directory with a +minimal set of devices, e.g. mknod, MAKEDEV, or mount devfs... In freebsd +this is done by adding a line to /etc/fstab: + +devfs /usr/local/etc/racoon/root/dev devfs rw 0 0 + +and then adding a line like this to /etc/rc.conf: + +devfs_set_rulesets="/usr/local/etc/racoon/root/dev=devfsrules_basic" + +and then adding the following lines to /etc/devfs.rules: + +[devfsrules_basic=10] +add include $devfsrules_hide_all +add include $devfsrules_unhide_basic + +and then either rebooting or entering "mount -a && /etc/rc.d/devfs start". + +When done with that: + +mkdir -p root/usr/local/etc +ln -s ../../../ root/usr/local/etc/racoon + +This dummy hierarchy keeps the config file consistent between both copies of +racoon. Of course, you could actually put the certs directory and any other +configuration data down in the hierarchy but I prefer to leave it at the root +and link to it as shown. You may end up with something like this: + +root# ls -FC /usr/local/etc/racoon/root +certs/ dev/ usr/ + +root# ls -l /usr/local/etc/racoon/root/usr/local/etc +lrwxr-xr-x 1 root wheel 9 Mar 7 22:13 racoon -> ../../../ + +root# ls -FC /usr/local/etc/racoon/root/usr/local/etc/racoon/ +certs/ dev/ usr/ + +Presumably your racoon.conf already contains something like: + +path certificate "/usr/local/etc/racoon/certs"; +path script "/usr/local/etc/racoon/scripts"; + +If so, great. If not, add them. Then, finally, add the privsep section: + +privsep { + user "ike"; + group "ike"; + chroot "/usr/local/etc/racoon/root"; +} + +Apply the patches posted to the list and rebuild racoon (the patches will be +incorporated into the release subsequent to the date of this memo, so if you +use that or a later release you can skip this step). + +Restart racoon and hopefully things will work. As of the date of this memo, +re-loading the configuration file with racoonctl will not work with privsep +enabled. However, the problem is not insurmountable and if you figure it out +let us know. + +I have not tested privsep with many of racoon's features such as XAUTH or +scripts, so if you have trouble with them and work anything out please reply +to the list so that your discoveries may be incorporated into this document. + +Last modified: $Date: 2008/03/28 04:18:52 $ diff --git a/ipsec-tools/src/racoon/dump.h b/ipsec-tools/src/racoon/dump.h new file mode 100644 index 00000000..3e8a5df8 --- /dev/null +++ b/ipsec-tools/src/racoon/dump.h @@ -0,0 +1,41 @@ +/* $NetBSD: dump.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: dump.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */ + +/* + * Copyright (C) 2000 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _DUMP_H +#define _DUMP_H + +extern int isakmp_dump_open __P((char *)); +extern int isakmp_dump_close __P((void)); +extern int isakmp_dump __P((vchar_t *, struct sockaddr *, struct sockaddr *)); + +#endif /* _DUMP_H */ diff --git a/ipsec-tools/src/racoon/eaytest.c b/ipsec-tools/src/racoon/eaytest.c new file mode 100644 index 00000000..1474bdcb --- /dev/null +++ b/ipsec-tools/src/racoon/eaytest.c @@ -0,0 +1,1069 @@ +/* $NetBSD: eaytest.c,v 1.10 2010/01/17 23:02:48 wiz Exp $ */ + +/* Id: eaytest.c,v 1.22 2005/06/19 18:02:54 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "var.h" +#include "vmbuf.h" +#include "misc.h" +#include "debug.h" +#include "str2val.h" +#include "plog.h" + +#include "oakley.h" +#include "dhgroup.h" +#include "crypto_openssl.h" +#include "gnuc.h" + +#include "package_version.h" + +#define PVDUMP(var) racoon_hexdump((var)->v, (var)->l) + +/*#define CERTTEST_BROKEN */ + +/* prototype */ + +static vchar_t *pem_read_buf __P((char *)); +void Usage __P((void)); + +int rsatest __P((int, char **)); +int ciphertest __P((int, char **)); +int hmactest __P((int, char **)); +int sha1test __P((int, char **)); +int md5test __P((int, char **)); +int dhtest __P((int, char **)); +int bntest __P((int, char **)); +#ifndef CERTTEST_BROKEN +static char **getcerts __P((char *)); +int certtest __P((int, char **)); +#endif + +/* test */ + +static int +rsa_verify_with_pubkey(src, sig, pubkey_txt) + vchar_t *src, *sig; + char *pubkey_txt; +{ + BIO *bio; + EVP_PKEY *evp; + int error; + + bio = BIO_new_mem_buf(pubkey_txt, strlen(pubkey_txt)); + evp = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); + if (! evp) { + printf ("PEM_read_PUBKEY(): %s\n", eay_strerror()); + return -1; + } + error = eay_check_rsasign(src, sig, evp->pkey.rsa); + + return error; +} + +int +rsatest(ac, av) + int ac; + char **av; +{ + char *text = "this is test."; + vchar_t src; + vchar_t *priv, *sig; + int loglevel_saved; + + char *pkcs1 = +"-----BEGIN RSA PRIVATE KEY-----\n" +"MIICXQIBAAKBgQChe5/Fzk9SA0vCKBOcu9jBcLb9oLv50PeuEfQojhakY+OH8A3Q\n" +"M8A0qIDG6uhTNGPvzCWb/+mKeOB48n5HJpLxlDFyP3kyd2yXHIZ/MN8g1nh4FsB0\n" +"iTkk8QUCJkkan6FCOBrIeLEsGA5AdodzuR+khnCMt8vO+NFHZYKAQeynyQIDAQAB\n" +"AoGAOfDcnCHxjhDGrwyoNNWl6Yqi7hAtQm67YAbrH14UO7nnmxAENM9MyNgpFLaW\n" +"07v5m8IZQIcradcDXAJOUwNBN8E06UflwEYCaScIwndvr5UpVlN3e2NC6Wyg2yC7\n" +"GarxQput3zj35XNR5bK42UneU0H6zDxpHWqI1SwE+ToAHu0CQQDNl9gUJTpg0L09\n" +"HkbE5jeb8bA5I20nKqBOBP0v5tnzpwu41umQwk9I7Ru0ucD7j+DW4k8otadW+FnI\n" +"G1M1MpSjAkEAyRMt4bN8otfpOpsOQWzw4jQtouohOxRFCrQTntHhU20PrQnQLZWs\n" +"pOVzqCjRytYtkPEUA1z8QK5gGcVPcOQsowJBALmt2rwPB1NrEo5Bat7noO+Zb3Ob\n" +"WDiYWeE8xkHd95gDlSWiC53ur9aINo6ZeP556jGIgL+el/yHHecJLrQL84sCQH48\n" +"zUxq/C/cb++8UzneJGlPqusiJNTLiAENR1gpmlZfHT1c8Nb9phMsfu0vG29GAfuC\n" +"bzchVLljALCNQK+2gRMCQQCNIgN+R9mRWZhFAcC1sq++YnuSBlw4VwdL/fd1Yg9e\n" +"Ul+U98yPl/NXt8Rs4TRBFcOZjkFI8xv0hQtevTgTmgz+\n" +"-----END RSA PRIVATE KEY-----\n\n"; + char *pubkey = +"-----BEGIN PUBLIC KEY-----\n" +"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChe5/Fzk9SA0vCKBOcu9jBcLb9\n" +"oLv50PeuEfQojhakY+OH8A3QM8A0qIDG6uhTNGPvzCWb/+mKeOB48n5HJpLxlDFy\n" +"P3kyd2yXHIZ/MN8g1nh4FsB0iTkk8QUCJkkan6FCOBrIeLEsGA5AdodzuR+khnCM\n" +"t8vO+NFHZYKAQeynyQIDAQAB\n" +"-----END PUBLIC KEY-----\n\n"; + char *pubkey_wrong = +"-----BEGIN PUBLIC KEY-----\n" +"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwDncG2tSokRBhK8la1mO\n" +"QnUpxg6KvpoFUjEyRiIE1GRap5V6jCCEOmA9ZAz4Oa/97oxewwMWtchIxSBZVCia\n" +"H9oGasbOFzrtSR+MKl6Cb/Ow3Fu+PKbHTsnfTk/nOOWyaQh91PRD7fdwHe8L9P7w\n" +"2kFPmDW6+RNKIR4OErhXf1O0eSShPe0TO3vx43O7dWqhmh3Kgr4Jq7zAGqHtwu0B\n" +"RFZnmsocOnVZb2yAHndp51/Mk1H37ThHwN7qMx7RqrS3ru3XtchpJd9IQJPBIRfY\n" +"VYQ68u5ix/Z80Y6VkRf0qnAvel8B6D3N3Zyq5u7G60PfvvtCybeMn7nVrSMxqMW/\n" +"xwIDAQAB\n" +"-----END PUBLIC KEY-----\n\n"; + + printf ("%s", pkcs1); + printf ("%s", pubkey); + priv = pem_read_buf(pkcs1); + + src.v = text; + src.l = strlen(text); + + /* sign */ + sig = eay_get_x509sign(&src, priv); + if (sig == NULL) { + printf("sign failed. %s\n", eay_strerror()); + return -1; + } + + printf("RSA signed data.\n"); + PVDUMP(sig); + + printf("Verification with correct pubkey: "); + if (rsa_verify_with_pubkey (&src, sig, pubkey) != 0) { + printf ("Failed.\n"); + return -1; + } + else + printf ("Verified. Good.\n"); + + loglevel_saved = loglevel; + loglevel = 0; + printf("Verification with wrong pubkey: "); + if (rsa_verify_with_pubkey (&src, sig, pubkey_wrong) != 0) + printf ("Not verified. Good.\n"); + else { + printf ("Verified. This is bad...\n"); + loglevel = loglevel_saved; + return -1; + } + loglevel = loglevel_saved; + + return 0; +} + +static vchar_t * +pem_read_buf(buf) + char *buf; +{ + BIO *bio; + char *nm = NULL, *header = NULL; + unsigned char *data = NULL; + long len; + vchar_t *ret; + int error; + + bio = BIO_new_mem_buf(buf, strlen(buf)); + error = PEM_read_bio(bio, &nm, &header, &data, &len); + if (error == 0) + errx(1, "%s", eay_strerror()); + ret = vmalloc(len); + if (ret == NULL) + err(1, "vmalloc"); + memcpy(ret->v, data, len); + + return ret; +} + +#ifndef CERTTEST_BROKEN +int +certtest(ac, av) + int ac; + char **av; +{ + char *certpath; + char **certs; + int type; + int error; + + printf("\n**Test for Certificate.**\n"); + + { + vchar_t *asn1dn = NULL, asn1dn0; +#ifdef ORIG_DN + char dnstr[] = "C=JP, ST=Kanagawa, L=Fujisawa, O=WIDE Project, OU=KAME Project, CN=Shoichi Sakane/Email=sakane@kame.net"; + char *dnstr_w1 = NULL; + char *dnstr_w2 = NULL; + char dn0[] = { + 0x30,0x81,0x9a,0x31,0x0b,0x30,0x09,0x06, + 0x03,0x55,0x04,0x06,0x13,0x02,0x4a,0x50, + 0x31,0x11,0x30,0x0f,0x06,0x03,0x55,0x04, + 0x08,0x13,0x08,0x4b,0x61,0x6e,0x61,0x67, + 0x61,0x77,0x61,0x31,0x11,0x30,0x0f,0x06, + 0x03,0x55,0x04,0x07,0x13,0x08,0x46,0x75, + 0x6a,0x69,0x73,0x61,0x77,0x61,0x31,0x15, + 0x30,0x13,0x06,0x03,0x55,0x04,0x0a,0x13, + 0x0c,0x57,0x49,0x44,0x45,0x20,0x50,0x72, + 0x6f,0x6a,0x65,0x63,0x74,0x31,0x15,0x30, + 0x13,0x06,0x03,0x55,0x04,0x0b,0x13,0x0c, + 0x4b,0x41,0x4d,0x45,0x20,0x50,0x72,0x6f, + 0x6a,0x65,0x63,0x74,0x31,0x17,0x30,0x15, + 0x06,0x03,0x55,0x04,0x03,0x13,0x0e,0x53, + 0x68,0x6f,0x69,0x63,0x68,0x69,0x20,0x53, + 0x61,0x6b,0x61,0x6e,0x65,0x31,0x1e,0x30, + 0x1c,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7, + 0x0d,0x01,0x09,0x01, + 0x0c, /* <== XXX */ + 0x0f,0x73,0x61, + 0x6b,0x61,0x6e,0x65,0x40,0x6b,0x61,0x6d, + 0x65,0x2e,0x6e,0x65,0x74, + }; +#else /* not ORIG_DN */ + char dnstr[] = "C=JP, ST=Kanagawa, L=Fujisawa, O=WIDE Project, OU=KAME Project, CN=Shoichi Sakane"; + char dnstr_w1[] = "C=JP, ST=Kanagawa, L=Fujisawa, O=WIDE Project, OU=*, CN=Shoichi Sakane"; + char dnstr_w2[] = "C=JP, ST=Kanagawa, L=Fujisawa, O=WIDE Project, OU=KAME Project, CN=*"; + char dn0[] = { + 0x30,0x7a,0x31,0x0b,0x30,0x09,0x06,0x03, + 0x55,0x04,0x06,0x13,0x02,0x4a,0x50,0x31, + 0x11,0x30,0x0f,0x06,0x03,0x55,0x04,0x08, + 0x13,0x08,0x4b,0x61,0x6e,0x61,0x67,0x61, + 0x77,0x61,0x31,0x11,0x30,0x0f,0x06,0x03, + 0x55,0x04,0x07,0x13,0x08,0x46,0x75,0x6a, + 0x69,0x73,0x61,0x77,0x61,0x31,0x15,0x30, + 0x13,0x06,0x03,0x55,0x04,0x0a,0x13,0x0c, + 0x57,0x49,0x44,0x45,0x20,0x50,0x72,0x6f, + 0x6a,0x65,0x63,0x74,0x31,0x15,0x30,0x13, + 0x06,0x03,0x55,0x04,0x0b,0x13,0x0c,0x4b, + 0x41,0x4d,0x45,0x20,0x50,0x72,0x6f,0x6a, + 0x65,0x63,0x74,0x31,0x17,0x30,0x15,0x06, + 0x03,0x55,0x04,0x03,0x13,0x0e,0x53,0x68, + 0x6f,0x69,0x63,0x68,0x69,0x20,0x53,0x61, + 0x6b,0x61,0x6e,0x65, + }; +#endif /* ORIG_DN */ + + printf("check to convert the string into subjectName.\n"); + printf("%s\n", dnstr); + + asn1dn0.v = dn0; + asn1dn0.l = sizeof(dn0); + + asn1dn = eay_str2asn1dn(dnstr, strlen(dnstr)); + if (asn1dn == NULL || asn1dn->l != asn1dn0.l) +#ifdef OUTPUT_VALID_ASN1DN + { + unsigned char *cp; int i; + printf("asn1dn length mismatched (%zu != %zu).\n", asn1dn ? asn1dn->l : -1, asn1dn0.l); + for (cp = asn1dn->v, i = 0; i < asn1dn->l; i++) + printf ("0x%02x,", *cp++); + exit (1); + } +#else + errx(1, "asn1dn length mismatched (%zu != %zu).\n", asn1dn ? asn1dn->l : -1, asn1dn0.l); +#endif + + /* + * NOTE: The value pointed by "<==" above is different from the + * return of eay_str2asn1dn(). but eay_cmp_asn1dn() can distinguish + * both of the names are same name. + */ + if (eay_cmp_asn1dn(&asn1dn0, asn1dn)) + errx(1, "asn1dn mismatched.\n"); + vfree(asn1dn); + + printf("exact match: succeed.\n"); + + if (dnstr_w1 != NULL) { + asn1dn = eay_str2asn1dn(dnstr_w1, strlen(dnstr_w1)); + if (asn1dn == NULL || asn1dn->l == asn1dn0.l) + errx(1, "asn1dn length wrong for wildcard 1\n"); + if (eay_cmp_asn1dn(&asn1dn0, asn1dn)) + errx(1, "asn1dn mismatched for wildcard 1.\n"); + vfree(asn1dn); + printf("wildcard 1 match: succeed.\n"); + } + + if (dnstr_w1 != NULL) { + asn1dn = eay_str2asn1dn(dnstr_w2, strlen(dnstr_w2)); + if (asn1dn == NULL || asn1dn->l == asn1dn0.l) + errx(1, "asn1dn length wrong for wildcard 2\n"); + if (eay_cmp_asn1dn(&asn1dn0, asn1dn)) + errx(1, "asn1dn mismatched for wildcard 2.\n"); + vfree(asn1dn); + printf("wildcard 2 match: succeed.\n"); + } + + } + eay_init(); + + /* get certs */ + if (ac > 1) { + certpath = *(av + 1); + certs = getcerts(certpath); + } else { +#ifdef ORIG_DN + printf("\nCAUTION: These certificates are probably invalid " + "on your environment because you don't have their " + "issuer's certs in your environment.\n\n"); + + certpath = "/usr/local/openssl/certs"; + certs = getcerts(NULL); +#else + printf("\nWARNING: The main certificates are probably invalid " + "on your environment\nbecause you don't have their " + "issuer's certs in your environment\nso not doing " + "this test.\n\n"); + return (0); +#endif + } + + while (*certs != NULL) { + + vchar_t c; + char *str; + vchar_t *vstr; + + printf("===CERT===\n"); + + c.v = *certs; + c.l = strlen(*certs); + + /* print text */ + str = eay_get_x509text(&c); + printf("%s", str); + racoon_free(str); + + /* print ASN.1 of subject name */ + vstr = eay_get_x509asn1subjectname(&c); + if (!vstr) + return 0; + PVDUMP(vstr); + printf("\n"); + vfree(vstr); + + /* print subject alt name */ + { + int pos; + for (pos = 1; ; pos++) { + error = eay_get_x509subjectaltname(&c, &str, &type, pos); + if (error) { + printf("no subjectaltname found.\n"); + break; + } + if (!str) + break; + printf("SubjectAltName: %d: %s\n", type, str); + racoon_free(str); + } + } + + /* NULL => name of the certificate file */ + error = eay_check_x509cert(&c, certpath, NULL, 1); + if (error) + printf("ERROR: cert is invalid.\n"); + printf("\n"); + + certs++; + } + return 0; +} + +static char ** +getcerts(path) + char *path; +{ + char **certs = NULL, **p; + DIR *dirp; + struct dirent *dp; + struct stat sb; + char buf[512]; + int len; + int n; + int fd; + + static char *samplecerts[] = { +/* self signed */ +"-----BEGIN CERTIFICATE-----\n" +"MIICpTCCAg4CAQAwDQYJKoZIhvcNAQEEBQAwgZoxCzAJBgNVBAYTAkpQMREwDwYD\n" +"VQQIEwhLYW5hZ2F3YTERMA8GA1UEBxMIRnVqaXNhd2ExFTATBgNVBAoTDFdJREUg\n" +"UHJvamVjdDEVMBMGA1UECxMMS0FNRSBQcm9qZWN0MRcwFQYDVQQDEw5TaG9pY2hp\n" +"IFNha2FuZTEeMBwGCSqGSIb3DQEJARYPc2FrYW5lQGthbWUubmV0MB4XDTAwMDgy\n" +"NDAxMzc0NFoXDTAwMDkyMzAxMzc0NFowgZoxCzAJBgNVBAYTAkpQMREwDwYDVQQI\n" +"EwhLYW5hZ2F3YTERMA8GA1UEBxMIRnVqaXNhd2ExFTATBgNVBAoTDFdJREUgUHJv\n" +"amVjdDEVMBMGA1UECxMMS0FNRSBQcm9qZWN0MRcwFQYDVQQDEw5TaG9pY2hpIFNh\n" +"a2FuZTEeMBwGCSqGSIb3DQEJARYPc2FrYW5lQGthbWUubmV0MIGfMA0GCSqGSIb3\n" +"DQEBAQUAA4GNADCBiQKBgQCpIQG/H3zn4czAmPBcbkDrYxE1A9vcpghpib3Of0Op\n" +"SsiWIBOyIMiVAzK/I/JotWp3Vdn5fzGp/7DGAbWXAALas2xHkNmTMPpu6qhmNQ57\n" +"kJHZHal24mgc1hwbrI9fb5olvIexx9a1riNPnKMRVHzXYizsyMbf+lJJmZ8QFhWN\n" +"twIDAQABMA0GCSqGSIb3DQEBBAUAA4GBACKs6X/BYycuHI3iop403R3XWMHHnNBN\n" +"5XTHVWiWgR1cMWkq/dp51gn+nPftpdAaYGpqGkiHGhZcXLoBaX9uON3p+7av+sQN\n" +"plXwnvUf2Zsgu+fojskS0gKcDlYiq1O8TOaBgJouFZgr1q6PiYjVEJGogAP28+HN\n" +"M4o+GBFbFoqK\n" +"-----END CERTIFICATE-----\n\n", +/* signed by SSH testing CA + CA1 + CA2 */ +"-----BEGIN X509 CERTIFICATE-----\n" +"MIICtTCCAj+gAwIBAgIEOaR8NjANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJG\n" +"STEkMCIGA1UEChMbU1NIIENvbW11bmljYXRpb25zIFNlY3VyaXR5MREwDwYDVQQL\n" +"EwhXZWIgdGVzdDEbMBkGA1UEAxMSVGVzdCBDQSAxIHN1YiBjYSAyMB4XDTAwMDgy\n" +"NDAwMDAwMFoXDTAwMTAwMTAwMDAwMFowgZoxCzAJBgNVBAYTAkpQMREwDwYDVQQI\n" +"EwhLYW5hZ2F3YTERMA8GA1UEBxMIRnVqaXNhd2ExFTATBgNVBAoTDFdJREUgUHJv\n" +"amVjdDEVMBMGA1UECxMMS0FNRSBQcm9qZWN0MRcwFQYDVQQDEw5TaG9pY2hpIFNh\n" +"a2FuZTEeMBwGCSqGSIb3DQEJAQwPc2FrYW5lQGthbWUubmV0MIGfMA0GCSqGSIb3\n" +"DQEBAQUAA4GNADCBiQKBgQCpIQG/H3zn4czAmPBcbkDrYxE1A9vcpghpib3Of0Op\n" +"SsiWIBOyIMiVAzK/I/JotWp3Vdn5fzGp/7DGAbWXAALas2xHkNmTMPpu6qhmNQ57\n" +"kJHZHal24mgc1hwbrI9fb5olvIexx9a1riNPnKMRVHzXYizsyMbf+lJJmZ8QFhWN\n" +"twIDAQABo18wXTALBgNVHQ8EBAMCBaAwGgYDVR0RBBMwEYEPc2FrYW5lQGthbWUu\n" +"bmV0MDIGA1UdHwQrMCkwJ6AloCOGIWh0dHA6Ly9sZGFwLnNzaC5maS9jcmxzL2Nh\n" +"MS0yLmNybDANBgkqhkiG9w0BAQUFAANhADtaqual41OWshF/rwCTuR6zySBJysGp\n" +"+qjkp5efCiYKhAu1L4WXlMsV/SNdzspui5tHasPBvUw8gzFsU/VW/B2zuQZkimf1\n" +"u6ZPjUb/vt8vLOPScP5MeH7xrTk9iigsqQ==\n" +"-----END X509 CERTIFICATE-----\n\n", +/* VP100 */ +"-----BEGIN CERTIFICATE-----\n" +"MIICXzCCAcigAwIBAgIEOXGBIzANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJG\n" +"STEkMCIGA1UEChMbU1NIIENvbW11bmljYXRpb25zIFNlY3VyaXR5MREwDwYDVQQL\n" +"EwhXZWIgdGVzdDESMBAGA1UEAxMJVGVzdCBDQSAxMB4XDTAwMDcxNjAwMDAwMFoX\n" +"DTAwMDkwMTAwMDAwMFowNTELMAkGA1UEBhMCanAxETAPBgNVBAoTCHRhaGl0ZXN0\n" +"MRMwEQYDVQQDEwpmdXJ1a2F3YS0xMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKB\n" +"gQDUmI2RaAuoLvtRDbASwRhbkj/Oq0BBIKgAqbFknc/EanJSQwZQu82gD88nf7gG\n" +"VEioWmKPLDuEjz5JCuM+k5f7HYHI1wWmz1KFr7UA+avZm4Kp6YKnhuH7soZp7kBL\n" +"hTiZEpL0jdmCWLW3ZXoro55rmPrBsCd+bt8VU6tRZm5dUwIBKaNZMFcwCwYDVR0P\n" +"BAQDAgWgMBYGA1UdEQQPMA2CBVZQMTAwhwQKFIaFMDAGA1UdHwQpMCcwJaAjoCGG\n" +"H2h0dHA6Ly9sZGFwLnNzaC5maS9jcmxzL2NhMS5jcmwwDQYJKoZIhvcNAQEFBQAD\n" +"gYEAKJ/2Co/KYW65mwpGG3CBvsoRL8xyUMHGt6gQpFLHiiHuAdix1ADTL6uoFuYi\n" +"4sE5omQm1wKVv2ZhS03zDtUfKoVEv0HZ7IY3AU/FZT/M5gQvbt43Dki/ma3ock2I\n" +"PPhbLsvXm+GCVh3jvkYGk1zr7VERVeTPtmT+hW63lcxfFp4=\n" +"-----END CERTIFICATE-----\n\n", +/* IKED */ +"-----BEGIN CERTIFICATE-----\n" +"MIIEFTCCA7+gAwIBAgIKYU5X6AAAAAAACTANBgkqhkiG9w0BAQUFADCBljEpMCcG\n" +"CSqGSIb3DQEJARYaeS13YXRhbmFAc2RsLmhpdGFjaGkuY28uanAxCzAJBgNVBAYT\n" +"AkpQMREwDwYDVQQIEwhLQU5BR0FXQTERMA8GA1UEBxMIWW9rb2hhbWExEDAOBgNV\n" +"BAoTB0hJVEFDSEkxDDAKBgNVBAsTA1NETDEWMBQGA1UEAxMNSVBzZWMgVGVzdCBD\n" +"QTAeFw0wMDA3MTUwMjUxNDdaFw0wMTA3MTUwMzAxNDdaMEUxCzAJBgNVBAYTAkpQ\n" +"MREwDwYDVQQIEwhLQU5BR0FXQTEQMA4GA1UEChMHSElUQUNISTERMA8GA1UEAxMI\n" +"V0FUQU5BQkUwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA6Wja5A7Ldzrtx+rMWHEB\n" +"Cyt+/ZoG0qdFQbuuUiU1vOSq+1f+ZSCYAdTq13Lrr6Xfz3jDVFEZLPID9PSTFwq+\n" +"yQIDAQABo4ICPTCCAjkwDgYDVR0PAQH/BAQDAgTwMBMGA1UdJQQMMAoGCCsGAQUF\n" +"CAICMB0GA1UdDgQWBBTkv7/MH5Ra+S1zBAmnUIH5w8ZTUTCB0gYDVR0jBIHKMIHH\n" +"gBQsF2qoaTl5F3GFLKrttaxPJ8j4faGBnKSBmTCBljEpMCcGCSqGSIb3DQEJARYa\n" +"eS13YXRhbmFAc2RsLmhpdGFjaGkuY28uanAxCzAJBgNVBAYTAkpQMREwDwYDVQQI\n" +"EwhLQU5BR0FXQTERMA8GA1UEBxMIWW9rb2hhbWExEDAOBgNVBAoTB0hJVEFDSEkx\n" +"DDAKBgNVBAsTA1NETDEWMBQGA1UEAxMNSVBzZWMgVGVzdCBDQYIQeccIf4GYDIBA\n" +"rS6HSUt8XjB7BgNVHR8EdDByMDagNKAyhjBodHRwOi8vZmxvcmEyMjAvQ2VydEVu\n" +"cm9sbC9JUHNlYyUyMFRlc3QlMjBDQS5jcmwwOKA2oDSGMmZpbGU6Ly9cXGZsb3Jh\n" +"MjIwXENlcnRFbnJvbGxcSVBzZWMlMjBUZXN0JTIwQ0EuY3JsMIGgBggrBgEFBQcB\n" +"AQSBkzCBkDBFBggrBgEFBQcwAoY5aHR0cDovL2Zsb3JhMjIwL0NlcnRFbnJvbGwv\n" +"ZmxvcmEyMjBfSVBzZWMlMjBUZXN0JTIwQ0EuY3J0MEcGCCsGAQUFBzAChjtmaWxl\n" +"Oi8vXFxmbG9yYTIyMFxDZXJ0RW5yb2xsXGZsb3JhMjIwX0lQc2VjJTIwVGVzdCUy\n" +"MENBLmNydDANBgkqhkiG9w0BAQUFAANBAG8yZAWHb6g3zba453Hw5loojVDZO6fD\n" +"9lCsyaxeo9/+7x1JEEcdZ6qL7KKqe7ZBwza+hIN0ITkp2WEWo22gTz4=\n" +"-----END CERTIFICATE-----\n\n", +/* From Entrust */ +"-----BEGIN CERTIFICATE-----\n" +"MIIDXTCCAsagAwIBAgIEOb6khTANBgkqhkiG9w0BAQUFADA4MQswCQYDVQQGEwJV\n" +"UzEQMA4GA1UEChMHRW50cnVzdDEXMBUGA1UECxMOVlBOIEludGVyb3AgUk8wHhcN\n" +"MDAwOTE4MjMwMDM3WhcNMDMwOTE4MjMzMDM3WjBTMQswCQYDVQQGEwJVUzEQMA4G\n" +"A1UEChMHRW50cnVzdDEXMBUGA1UECxMOVlBOIEludGVyb3AgUk8xGTAXBgNVBAMT\n" +"EFNob2ljaGkgU2FrYW5lIDIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKj3\n" +"eXSt1qXxFXzpa265B/NQYk5BZN7pNJg0tlTKBTVV3UgpQ92Bx5DoNfZh11oIv0Sw\n" +"6YnG5p9F9ma36U9HDoD3hVTjAvQKy4ssCsnU1y6v5XOU1QvYQo6UTzgsXUTaIau4\n" +"Lrccl+nyoiNzy3lG51tLR8CxuA+3OOAK9xPjszClAgMBAAGjggFXMIIBUzBABgNV\n" +"HREEOTA3gQ9zYWthbmVAa2FtZS5uZXSHBM6vIHWCHjIwNi0xNzUtMzItMTE3LnZw\n" +"bndvcmtzaG9wLmNvbTATBgNVHSUEDDAKBggrBgEFBQgCAjALBgNVHQ8EBAMCAKAw\n" +"KwYDVR0QBCQwIoAPMjAwMDA5MTgyMzAwMzdagQ8yMDAyMTAyNTExMzAzN1owWgYD\n" +"VR0fBFMwUTBPoE2gS6RJMEcxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0\n" +"MRcwFQYDVQQLEw5WUE4gSW50ZXJvcCBSTzENMAsGA1UEAxMEQ1JMMTAfBgNVHSME\n" +"GDAWgBTzVmhu0tBoWKwkZE5mXpooE9630DAdBgNVHQ4EFgQUEgBHPtXggJqei5Xz\n" +"92CrWXTJxfAwCQYDVR0TBAIwADAZBgkqhkiG9n0HQQAEDDAKGwRWNS4wAwIEsDAN\n" +"BgkqhkiG9w0BAQUFAAOBgQCIFriNGMUE8GH5LuDrTJfA8uGx8vLy2seljuo694TR\n" +"et/ojp9QnfOJ1PF9iAdGaEaSLfkwhY4fZNZzxic5HBoHLeo9BXLP7i7FByXjvOZC\n" +"Y8++0dC8NVvendIILcJBM5nbDq1TqIbb8K3SP80XhO5JLVJkoZiQftAMjo0peZPO\n" +"EQ==\n" +"-----END CERTIFICATE-----\n\n", + NULL, + }; + + if (path == NULL) + return (char **)&samplecerts; + + stat(path, &sb); + if (!(sb.st_mode & S_IFDIR)) { + printf("ERROR: %s is not directory.\n", path); + exit(0); + } + + dirp = opendir(path); + if (dirp == NULL) { + printf("opendir failed.\n"); + exit(0); + } + + n = 0; + while ((dp = readdir(dirp)) != NULL) { + if (dp->d_type != DT_REG) + continue; + if (strcmp(dp->d_name + strlen(dp->d_name) - 4, "cert")) + continue; + snprintf(buf, sizeof(buf), "%s/%s", path, dp->d_name); + stat(buf, &sb); + + p = (char **)realloc(certs, (n + 1) * sizeof(certs)); + if (p == NULL) + err(1, "realloc"); + certs = p; + + certs[n] = malloc(sb.st_size + 1); + if (certs[n] == NULL) + err(1, "malloc"); + + fd = open(buf, O_RDONLY); + if (fd == -1) + err(1, "open"); + len = read(fd, certs[n], sb.st_size); + if (len == -1) + err(1, "read"); + if (len != sb.st_size) + errx(1, "read: length mismatch"); + certs[n][sb.st_size] = '\0'; + close(fd); + + printf("%s: %d\n", dp->d_name, (int)sb.st_size); + + n++; + } + closedir(dirp); + + p = (char **)realloc(certs, (n + 1) * sizeof(certs)); + if (p == NULL) + err(1, "realloc"); + certs = p; + certs[n] = NULL; + + return certs; +} +#endif /* CERTTEST_BROKEN */ + +typedef vchar_t* (eay_func) (vchar_t *, vchar_t *, vchar_t *); + +static int +ciphertest_1 (const char *name, + vchar_t *data, + size_t data_align, + vchar_t *key, + size_t min_keysize, + vchar_t *iv0, + size_t iv_length, + eay_func encrypt, + eay_func decrypt) +{ + int padlen; + vchar_t *buf, *iv, *res1, *res2; + iv = vmalloc(iv_length); + + printf("Test for cipher %s\n", name); + printf("data:\n"); + PVDUMP(data); + + if (data_align <= 1 || (data->l % data_align) == 0) + padlen = 0; + else + padlen = data_align - data->l % data_align; + + buf = vmalloc(data->l + padlen); + memcpy(buf->v, data->v, data->l); + + memcpy(iv->v, iv0->v, iv_length); + res1 = (encrypt)(buf, key, iv); + if (res1 == NULL) { + printf("%s encryption failed.\n", name); + return -1; + } + printf("encrypted:\n"); + PVDUMP(res1); + + memcpy(iv->v, iv0->v, iv_length); + res2 = (decrypt)(res1, key, iv); + if (res2 == NULL) { + printf("%s decryption failed.\n", name); + return -1; + } + printf("decrypted:\n"); + PVDUMP(res2); + + if (memcmp(data->v, res2->v, data->l)) { + printf("XXXX NG (%s) XXXX\n", name); + return -1; + } + else + printf("%s cipher verified.\n", name); + vfree(res1); + vfree(res2); + vfree(buf); + vfree(iv); + + return 0; +} + +int +ciphertest(ac, av) + int ac; + char **av; +{ + vchar_t data; + vchar_t key; + vchar_t iv0; + + printf("\n**Testing CIPHERS**\n"); + + data.v = str2val("\ +06000017 03000000 73616b61 6e65406b 616d652e 6e657409 0002c104 308202b8 \ +04f05a90 \ + ", 16, &data.l); + key.v = str2val("f59bd70f 81b9b9cc 2a32c7fd 229a4b37", 16, &key.l); + iv0.v = str2val("26b68c90 9467b4ab 7ec29fa0 0b696b55", 16, &iv0.l); + + if (ciphertest_1 ("DES", + &data, 8, + &key, 8, + &iv0, 8, + eay_des_encrypt, eay_des_decrypt) < 0) + return -1; + + if (ciphertest_1 ("3DES", + &data, 8, + &key, 24, + &iv0, 8, + eay_3des_encrypt, eay_3des_decrypt) < 0) + return -1; + + if (ciphertest_1 ("AES", + &data, 16, + &key, key.l, + &iv0, 16, + eay_aes_encrypt, eay_aes_decrypt) < 0) + return -1; + + if (ciphertest_1 ("BLOWFISH", + &data, 8, + &key, key.l, + &iv0, 8, + eay_bf_encrypt, eay_bf_decrypt) < 0) + return -1; + + if (ciphertest_1 ("CAST", + &data, 8, + &key, key.l, + &iv0, 8, + eay_cast_encrypt, eay_cast_decrypt) < 0) + return -1; + +#ifdef HAVE_OPENSSL_IDEA_H + if (ciphertest_1 ("IDEA", + &data, 8, + &key, key.l, + &iv0, 8, + eay_idea_encrypt, eay_idea_decrypt) < 0) + return -1; +#endif + +#ifdef HAVE_OPENSSL_RC5_H + if (ciphertest_1 ("RC5", + &data, 8, + &key, key.l, + &iv0, 8, + eay_rc5_encrypt, eay_rc5_decrypt) < 0) + return -1; +#endif +#if defined(HAVE_OPENSSL_CAMELLIA_H) + if (ciphertest_1 ("CAMELLIA", + &data, 16, + &key, key.l, + &iv0, 16, + eay_camellia_encrypt, eay_camellia_decrypt) < 0) + return -1; +#endif + return 0; +} + +int +hmactest(ac, av) + int ac; + char **av; +{ + char *keyword = "hehehe test secret!"; + char *object = "d7e6a6c1876ef0488bb74958b9fee94e"; + char *object1 = "d7e6a6c1876ef048"; + char *object2 = "8bb74958b9fee94e"; + char *r_hmd5 = "5702d7d1 fd1bfc7e 210fc9fa cda7d02c"; + char *r_hsha1 = "309999aa 9779a43e ebdea839 1b4e7ee1 d8646874"; +#ifdef WITH_SHA2 + char *r_hsha2 = "d47262d8 a5b6f39d d8686939 411b3e79 ed2e27f9 2c4ea89f dd0a06ae 0c0aa396"; +#endif + vchar_t *key, *data, *data1, *data2, *res; + vchar_t mod; + caddr_t ctx; + +#ifdef WITH_SHA2 + printf("\n**Test for HMAC MD5, SHA1, and SHA256.**\n"); +#else + printf("\n**Test for HMAC MD5 & SHA1.**\n"); +#endif + + key = vmalloc(strlen(keyword)); + memcpy(key->v, keyword, key->l); + + data = vmalloc(strlen(object)); + data1 = vmalloc(strlen(object1)); + data2 = vmalloc(strlen(object2)); + memcpy(data->v, object, data->l); + memcpy(data1->v, object1, data1->l); + memcpy(data2->v, object2, data2->l); + + /* HMAC MD5 */ + printf("HMAC MD5 by eay_hmacmd5_one()\n"); + res = eay_hmacmd5_one(key, data); + PVDUMP(res); + mod.v = str2val(r_hmd5, 16, &mod.l); + if (memcmp(res->v, mod.v, mod.l)) { + printf(" XXX NG XXX\n"); + return -1; + } + free(mod.v); + vfree(res); + + /* HMAC MD5 */ + printf("HMAC MD5 by eay_hmacmd5_xxx()\n"); + ctx = eay_hmacmd5_init(key); + eay_hmacmd5_update(ctx, data1); + eay_hmacmd5_update(ctx, data2); + res = eay_hmacmd5_final(ctx); + PVDUMP(res); + mod.v = str2val(r_hmd5, 16, &mod.l); + if (memcmp(res->v, mod.v, mod.l)) { + printf(" XXX NG XXX\n"); + return -1; + } + free(mod.v); + vfree(res); + + /* HMAC SHA1 */ + printf("HMAC SHA1 by eay_hmacsha1_one()\n"); + res = eay_hmacsha1_one(key, data); + PVDUMP(res); + mod.v = str2val(r_hsha1, 16, &mod.l); + if (memcmp(res->v, mod.v, mod.l)) { + printf(" XXX NG XXX\n"); + return -1; + } + free(mod.v); + vfree(res); + + /* HMAC SHA1 */ + printf("HMAC SHA1 by eay_hmacsha1_xxx()\n"); + ctx = eay_hmacsha1_init(key); + eay_hmacsha1_update(ctx, data1); + eay_hmacsha1_update(ctx, data2); + res = eay_hmacsha1_final(ctx); + PVDUMP(res); + mod.v = str2val(r_hsha1, 16, &mod.l); + if (memcmp(res->v, mod.v, mod.l)) { + printf(" XXX NG XXX\n"); + return -1; + } + free(mod.v); + vfree(res); + +#ifdef WITH_SHA2 + /* HMAC SHA2 */ + printf("HMAC SHA2 by eay_hmacsha2_256_one()\n"); + res = eay_hmacsha2_256_one(key, data); + PVDUMP(res); + mod.v = str2val(r_hsha2, 16, &mod.l); + if (memcmp(res->v, mod.v, mod.l)) { + printf(" XXX NG XXX\n"); + return -1; + } + free(mod.v); + vfree(res); +#endif + + vfree(data); + vfree(data1); + vfree(data2); + vfree(key); + + return 0; +} + +int +sha1test(ac, av) + int ac; + char **av; +{ + char *word1 = "1234567890", *word2 = "12345678901234567890"; + caddr_t ctx; + vchar_t *buf, *res; + + printf("\n**Test for SHA1.**\n"); + + ctx = eay_sha1_init(); + buf = vmalloc(strlen(word1)); + memcpy(buf->v, word1, buf->l); + eay_sha1_update(ctx, buf); + eay_sha1_update(ctx, buf); + res = eay_sha1_final(ctx); + PVDUMP(res); + vfree(res); + vfree(buf); + + ctx = eay_sha1_init(); + buf = vmalloc(strlen(word2)); + memcpy(buf->v, word2, buf->l); + eay_sha1_update(ctx, buf); + res = eay_sha1_final(ctx); + PVDUMP(res); + vfree(res); + + res = eay_sha1_one(buf); + PVDUMP(res); + vfree(res); + vfree(buf); + + return 0; +} + +int +md5test(ac, av) + int ac; + char **av; +{ + char *word1 = "1234567890", *word2 = "12345678901234567890"; + caddr_t ctx; + vchar_t *buf, *res; + + printf("\n**Test for MD5.**\n"); + + ctx = eay_md5_init(); + buf = vmalloc(strlen(word1)); + memcpy(buf->v, word1, buf->l); + eay_md5_update(ctx, buf); + eay_md5_update(ctx, buf); + res = eay_md5_final(ctx); + PVDUMP(res); + vfree(res); + vfree(buf); + + ctx = eay_md5_init(); + buf = vmalloc(strlen(word2)); + memcpy(buf->v, word2, buf->l); + eay_md5_update(ctx, buf); + res = eay_md5_final(ctx); + PVDUMP(res); + vfree(res); + + res = eay_md5_one(buf); + PVDUMP(res); + vfree(res); + vfree(buf); + + return 0; +} + +int +dhtest(ac, av) + int ac; + char **av; +{ + static struct { + char *name; + char *p; + } px[] = { + { "modp768", OAKLEY_PRIME_MODP768, }, + { "modp1024", OAKLEY_PRIME_MODP1024, }, + { "modp1536", OAKLEY_PRIME_MODP1536, }, + { "modp2048", OAKLEY_PRIME_MODP2048, }, + { "modp3072", OAKLEY_PRIME_MODP3072, }, + { "modp4096", OAKLEY_PRIME_MODP4096, }, + { "modp6144", OAKLEY_PRIME_MODP6144, }, + { "modp8192", OAKLEY_PRIME_MODP8192, }, + }; + vchar_t p1, *pub1, *priv1, *gxy1; + vchar_t p2, *pub2, *priv2, *gxy2; + int i; + + printf("\n**Test for DH.**\n"); + + for (i = 0; i < sizeof(px)/sizeof(px[0]); i++) { + printf("\n**Test for DH %s.**\n", px[i].name); + + p1.v = str2val(px[i].p, 16, &p1.l); + p2.v = str2val(px[i].p, 16, &p2.l); + printf("prime number = \n"); PVDUMP(&p1); + + if (eay_dh_generate(&p1, 2, 96, &pub1, &priv1) < 0) { + printf("error\n"); + return -1; + } + printf("private key for user 1 = \n"); PVDUMP(priv1); + printf("public key for user 1 = \n"); PVDUMP(pub1); + + if (eay_dh_generate(&p2, 2, 96, &pub2, &priv2) < 0) { + printf("error\n"); + return -1; + } + printf("private key for user 2 = \n"); PVDUMP(priv2); + printf("public key for user 2 = \n"); PVDUMP(pub2); + + /* process to generate key for user 1 */ + gxy1 = vmalloc(p1.l); + memset(gxy1->v, 0, gxy1->l); + eay_dh_compute(&p1, 2, pub1, priv1, pub2, &gxy1); + printf("sharing gxy1 of user 1 = \n"); PVDUMP(gxy1); + + /* process to generate key for user 2 */ + gxy2 = vmalloc(p1.l); + memset(gxy2->v, 0, gxy2->l); + eay_dh_compute(&p2, 2, pub2, priv2, pub1, &gxy2); + printf("sharing gxy2 of user 2 = \n"); PVDUMP(gxy2); + + if (memcmp(gxy1->v, gxy2->v, gxy1->l)) { + printf("ERROR: sharing gxy mismatched.\n"); + return -1; + } + + vfree(pub1); + vfree(pub2); + vfree(priv1); + vfree(priv2); + vfree(gxy1); + vfree(gxy2); + } + + return 0; +} + +int +bntest(ac, av) + int ac; + char **av; +{ + vchar_t *rn; + + printf("\n**Test for generate a random number.**\n"); + + rn = eay_set_random((u_int32_t)96); + PVDUMP(rn); + vfree(rn); + + return 0; +} + +struct { + char *name; + int (*func) __P((int, char **)); +} func[] = { + { "random", bntest, }, + { "dh", dhtest, }, + { "md5", md5test, }, + { "sha1", sha1test, }, + { "hmac", hmactest, }, + { "cipher", ciphertest, }, +#ifndef CERTTEST_BROKEN + { "cert", certtest, }, +#endif + { "rsa", rsatest, }, +}; + +int +main(ac, av) + int ac; + char **av; +{ + int i; + int len = sizeof(func)/sizeof(func[0]); + + f_foreground = 1; + ploginit(); + + printf ("\nTestsuite of the %s\nlinked with %s\n\n", TOP_PACKAGE_STRING, eay_version()); + + if (strcmp(*av, "-h") == 0) + Usage(); + + ac--; + av++; + + for (i = 0; i < len; i++) { + if ((ac == 0) || (strcmp(*av, func[i].name) == 0)) { + if ((func[i].func)(ac, av) != 0) { + printf ("\n!!!!! Test '%s' failed. !!!!!\n\n", func[i].name); + exit(1); + } + if (ac) + break; + } + } + if (ac && i == len) + Usage(); + + printf ("\n===== All tests passed =====\n\n"); + exit(0); +} + +void +Usage() +{ + int i; + int len = sizeof(func)/sizeof(func[0]); + + printf("Usage: eaytest ["); + for (i = 0; i < len; i++) + printf("%s%s", func[i].name, (i +#include +#include +#include +#include +#include +#include +#include + +#include "vmbuf.h" +#include "plog.h" +#include "misc.h" +#include "admin.h" +#include "handler.h" +#include "session.h" +#include "gcmalloc.h" +#include "evt.h" +#include "var.h" + +#ifdef ENABLE_ADMINPORT + +static EVT_LISTENER_LIST(evt_listeners); + +struct evt_message { + struct admin_com adm; + struct evt_async evt; +}; + +struct evt { + struct evtdump *dump; + TAILQ_ENTRY(evt) next; +}; + +TAILQ_HEAD(evtlist, evt); + +#define EVTLIST_MAX 32 + +static struct evtlist evtlist = TAILQ_HEAD_INITIALIZER(evtlist); +static int evtlist_len = 0; +static int evtlist_inuse = 0; + +static struct { + int newtype, oldtype; +} evttype_map[] = { + { EVT_RACOON_QUIT, EVTT_RACOON_QUIT }, + { EVT_PHASE1_UP, EVTT_PHASE1_UP }, + { EVT_PHASE1_DOWN, EVTT_PHASE1_DOWN }, + { EVT_PHASE1_NO_RESPONSE, EVTT_PEER_NO_RESPONSE }, + { EVT_PHASE1_NO_PROPOSAL, EVTT_PEERPH1_NOPROP }, + { EVT_PHASE1_AUTH_FAILED, EVTT_PEERPH1AUTH_FAILED }, + { EVT_PHASE1_DPD_TIMEOUT, EVTT_DPD_TIMEOUT }, + { EVT_PHASE1_PEER_DELETED, EVTT_PEER_DELETE }, + { EVT_PHASE1_MODE_CFG, EVTT_ISAKMP_CFG_DONE }, + { EVT_PHASE1_XAUTH_SUCCESS, EVTT_XAUTH_SUCCESS }, + { EVT_PHASE1_XAUTH_FAILED, EVTT_XAUTH_FAILED }, + { EVT_PHASE2_NO_PHASE1, -1 }, + { EVT_PHASE2_UP, EVTT_PHASE2_UP }, + { EVT_PHASE2_DOWN, EVTT_PHASE2_DOWN }, + { EVT_PHASE2_NO_RESPONSE, EVTT_PEER_NO_RESPONSE }, +}; + +static void +evt_push(src, dst, type, optdata) + struct sockaddr *src; + struct sockaddr *dst; + int type; + vchar_t *optdata; +{ + struct evtdump *evtdump; + struct evt *evt; + size_t len; + int i; + + /* If admin socket is disabled, silently discard anything */ + if (adminsock_path == NULL || !evtlist_inuse) + return; + + /* Map the event type to old */ + for (i = 0; i < sizeof(evttype_map) / sizeof(evttype_map[0]); i++) + if (evttype_map[i].newtype == type) + break; + if (i >= sizeof(evttype_map) / sizeof(evttype_map[0])) + return; + + type = evttype_map[i].oldtype; + if (type < 0) + return; + + /* If we are above the limit, don't record anything */ + if (evtlist_len > EVTLIST_MAX) { + plog(LLV_DEBUG, LOCATION, NULL, + "Cannot record event: event queue overflowed\n"); + return; + } + + /* If we hit the limit, record an overflow event instead */ + if (evtlist_len == EVTLIST_MAX) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot record event: event queue overflow\n"); + src = NULL; + dst = NULL; + type = EVTT_OVERFLOW; + optdata = NULL; + } + + len = sizeof(*evtdump); + if (optdata) + len += optdata->l; + + if ((evtdump = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot record event: %s\n", + strerror(errno)); + return; + } + + if ((evt = racoon_malloc(sizeof(*evt))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot record event: %s\n", + strerror(errno)); + racoon_free(evtdump); + return; + } + + if (src) + memcpy(&evtdump->src, src, sysdep_sa_len(src)); + if (dst) + memcpy(&evtdump->dst, dst, sysdep_sa_len(dst)); + evtdump->len = len; + evtdump->type = type; + time(&evtdump->timestamp); + + if (optdata) + memcpy(evtdump + 1, optdata->v, optdata->l); + + evt->dump = evtdump; + TAILQ_INSERT_TAIL(&evtlist, evt, next); + + evtlist_len++; + + return; +} + +static struct evtdump * +evt_pop(void) { + struct evtdump *evtdump; + struct evt *evt; + + if ((evt = TAILQ_FIRST(&evtlist)) == NULL) + return NULL; + + evtdump = evt->dump; + TAILQ_REMOVE(&evtlist, evt, next); + racoon_free(evt); + evtlist_len--; + + return evtdump; +} + +vchar_t * +evt_dump(void) { + struct evtdump *evtdump; + vchar_t *buf = NULL; + + if (!evtlist_inuse) { + evtlist_inuse = 1; + plog(LLV_ERROR, LOCATION, NULL, + "evt_dump: deprecated event polling used\n"); + } + + if ((evtdump = evt_pop()) != NULL) { + if ((buf = vmalloc(evtdump->len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "evt_dump failed: %s\n", strerror(errno)); + return NULL; + } + memcpy(buf->v, evtdump, evtdump->len); + racoon_free(evtdump); + } + + return buf; +} + +static struct evt_message * +evtmsg_create(type, optdata) + int type; + vchar_t *optdata; +{ + struct evt_message *e; + size_t len; + + len = sizeof(struct evt_message); + if (optdata != NULL) + len += optdata->l; + + if ((e = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate event: %s\n", + strerror(errno)); + return NULL; + } + + memset(e, 0, sizeof(struct evt_message)); + e->adm.ac_len = len; + e->adm.ac_cmd = ADMIN_SHOW_EVT; + e->adm.ac_errno = 0; + e->adm.ac_proto = 0; + e->evt.ec_type = type; + time(&e->evt.ec_timestamp); + if (optdata != NULL) + memcpy(e + 1, optdata->v, optdata->l); + + return e; +} + +static void +evt_unsubscribe(l) + struct evt_listener *l; +{ + plog(LLV_DEBUG, LOCATION, NULL, + "[%d] admin connection released\n", l->fd); + + LIST_REMOVE(l, ll_chain); + unmonitor_fd(l->fd); + close(l->fd); + racoon_free(l); +} + +static int +evt_unsubscribe_cb(ctx, fd) + void *ctx; + int fd; +{ + evt_unsubscribe((struct evt_listener *) ctx); + return 0; +} + +static void +evtmsg_broadcast(ll, e) + const struct evt_listener_list *ll; + struct evt_message *e; +{ + struct evt_listener *l, *nl; + + for (l = LIST_FIRST(ll); l != NULL; l = nl) { + nl = LIST_NEXT(l, ll_chain); + + if (send(l->fd, e, e->adm.ac_len, MSG_DONTWAIT) < 0) { + plog(LLV_DEBUG, LOCATION, NULL, "Cannot send event to fd: %s\n", + strerror(errno)); + evt_unsubscribe(l); + } + } +} + +void +evt_generic(type, optdata) + int type; + vchar_t *optdata; +{ + struct evt_message *e; + + if ((e = evtmsg_create(type, optdata)) == NULL) + return; + + evtmsg_broadcast(&evt_listeners, e); + evt_push(&e->evt.ec_ph1src, &e->evt.ec_ph1dst, type, optdata); + + racoon_free(e); +} + +void +evt_phase1(ph1, type, optdata) + const struct ph1handle *ph1; + int type; + vchar_t *optdata; +{ + struct evt_message *e; + + if ((e = evtmsg_create(type, optdata)) == NULL) + return; + + if (ph1->local) + memcpy(&e->evt.ec_ph1src, ph1->local, sysdep_sa_len(ph1->local)); + if (ph1->remote) + memcpy(&e->evt.ec_ph1dst, ph1->remote, sysdep_sa_len(ph1->remote)); + + evtmsg_broadcast(&ph1->evt_listeners, e); + evtmsg_broadcast(&evt_listeners, e); + evt_push(&e->evt.ec_ph1src, &e->evt.ec_ph1dst, type, optdata); + + racoon_free(e); +} + +void +evt_phase2(ph2, type, optdata) + const struct ph2handle *ph2; + int type; + vchar_t *optdata; +{ + struct evt_message *e; + struct ph1handle *ph1 = ph2->ph1; + + if ((e = evtmsg_create(type, optdata)) == NULL) + return; + + if (ph1) { + if (ph1->local) + memcpy(&e->evt.ec_ph1src, ph1->local, sysdep_sa_len(ph1->local)); + if (ph1->remote) + memcpy(&e->evt.ec_ph1dst, ph1->remote, sysdep_sa_len(ph1->remote)); + } + e->evt.ec_ph2msgid = ph2->msgid; + + evtmsg_broadcast(&ph2->evt_listeners, e); + if (ph1) + evtmsg_broadcast(&ph1->evt_listeners, e); + evtmsg_broadcast(&evt_listeners, e); + evt_push(&e->evt.ec_ph1src, &e->evt.ec_ph1dst, type, optdata); + + racoon_free(e); +} + +int +evt_subscribe(list, fd) + struct evt_listener_list *list; + int fd; +{ + struct evt_listener *l; + + if ((l = racoon_malloc(sizeof(*l))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate event listener: %s\n", + strerror(errno)); + return errno; + } + + if (list == NULL) + list = &evt_listeners; + + LIST_INSERT_HEAD(list, l, ll_chain); + l->fd = fd; + monitor_fd(l->fd, evt_unsubscribe_cb, l, 0); + + plog(LLV_DEBUG, LOCATION, NULL, + "[%d] admin connection is polling events\n", fd); + + return -2; +} + +void +evt_list_init(list) + struct evt_listener_list *list; +{ + LIST_INIT(list); +} + +void +evt_list_cleanup(list) + struct evt_listener_list *list; +{ + while (!LIST_EMPTY(list)) + evt_unsubscribe(LIST_FIRST(list)); +} + +#endif /* ENABLE_ADMINPORT */ diff --git a/ipsec-tools/src/racoon/evt.h b/ipsec-tools/src/racoon/evt.h new file mode 100644 index 00000000..42e14d77 --- /dev/null +++ b/ipsec-tools/src/racoon/evt.h @@ -0,0 +1,146 @@ +/* $NetBSD: evt.h,v 1.7 2008/12/23 14:03:12 tteras Exp $ */ + +/* Id: evt.h,v 1.5 2006/01/19 10:24:09 fredsen Exp */ + +/* + * Copyright (C) 2004 Emmanuel Dreyfus + * Copyright (C) 2008 Timo Teras + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _EVT_H +#define _EVT_H + +/* + * Old style (deprecated) events which are polled. + */ + +struct evtdump { + size_t len; + struct sockaddr_storage src; + struct sockaddr_storage dst; + time_t timestamp; + int type; + /* + * Optionnal list of struct isakmp_data + * for type EVTT_ISAKMP_CFG_DONE + */ +}; + +/* type */ +#define EVTT_UNSEPC 0 +#define EVTT_PHASE1_UP 1 +#define EVTT_PHASE1_DOWN 2 +#define EVTT_XAUTH_SUCCESS 3 +#define EVTT_ISAKMP_CFG_DONE 4 +#define EVTT_PHASE2_UP 5 +#define EVTT_PHASE2_DOWN 6 +#define EVTT_DPD_TIMEOUT 7 +#define EVTT_PEER_NO_RESPONSE 8 +#define EVTT_PEER_DELETE 9 +#define EVTT_RACOON_QUIT 10 +#define EVTT_XAUTH_FAILED 11 +#define EVTT_OVERFLOW 12 /* Event queue overflowed */ +#define EVTT_PEERPH1AUTH_FAILED 13 +#define EVTT_PEERPH1_NOPROP 14 /* NO_PROPOSAL_CHOSEN & friends */ +#define EVTT_NO_ISAKMP_CFG 15 /* no need to wait for mode_cfg */ + +/* + * New style, asynchronous events. + */ + +struct evt_async { + uint32_t ec_type; + time_t ec_timestamp; + + struct sockaddr_storage ec_ph1src; + struct sockaddr_storage ec_ph1dst; + u_int32_t ec_ph2msgid; + + /* + * Optionnal list of struct isakmp_data + * for type EVTT_ISAKMP_CFG_DONE + */ +}; + +/* type */ +#define EVT_RACOON_QUIT 0x0001 + +#define EVT_PHASE1_UP 0x0100 +#define EVT_PHASE1_DOWN 0x0101 +#define EVT_PHASE1_NO_RESPONSE 0x0102 +#define EVT_PHASE1_NO_PROPOSAL 0x0103 +#define EVT_PHASE1_AUTH_FAILED 0x0104 +#define EVT_PHASE1_DPD_TIMEOUT 0x0105 +#define EVT_PHASE1_PEER_DELETED 0x0106 +#define EVT_PHASE1_MODE_CFG 0x0107 +#define EVT_PHASE1_XAUTH_SUCCESS 0x0108 +#define EVT_PHASE1_XAUTH_FAILED 0x0109 + +#define EVT_PHASE2_NO_PHASE1 0x0200 +#define EVT_PHASE2_UP 0x0201 +#define EVT_PHASE2_DOWN 0x0202 +#define EVT_PHASE2_NO_RESPONSE 0x0203 + +#ifdef ENABLE_ADMINPORT + +struct ph1handle; +struct ph2handle; + +struct evt_listener { + LIST_ENTRY(evt_listener) ll_chain; + int fd; +}; +LIST_HEAD(evt_listener_list, evt_listener); +#define EVT_LISTENER_LIST(x) struct evt_listener_list x + +void evt_generic __P((int type, vchar_t *optdata)); +void evt_phase1 __P((const struct ph1handle *ph1, int type, vchar_t *optdata)); +void evt_phase2 __P((const struct ph2handle *ph2, int type, vchar_t *optdata)); +vchar_t *evt_dump __P((void)); + +int evt_subscribe __P((struct evt_listener_list *list, int fd)); +void evt_list_init __P((struct evt_listener_list *list)); +void evt_list_cleanup __P((struct evt_listener_list *list)); + +#else + +#define EVT_LISTENER_LIST(x) + +#define evt_generic(type, optdata) ; +#define evt_phase1(ph1, type, optdata) ; +#define evt_phase2(ph2, type, optdata) ; + +#define evt_subscribe(eventlist, fd) ; +#define evt_list_init(eventlist) ; +#define evt_list_cleanup(eventlist) ; +#define evt_get_fdmask(nfds, fdset) nfds +#define evt_handle_fdmask(fdset) ; + +#endif /* ENABLE_ADMINPORT */ + +#endif /* _EVT_H */ diff --git a/ipsec-tools/src/racoon/gcmalloc.h b/ipsec-tools/src/racoon/gcmalloc.h new file mode 100644 index 00000000..acdf7fa5 --- /dev/null +++ b/ipsec-tools/src/racoon/gcmalloc.h @@ -0,0 +1,127 @@ +/* $NetBSD: gcmalloc.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* $KAME: gcmalloc.h,v 1.4 2001/11/16 04:34:57 sakane Exp $ */ + +/* + * Copyright (C) 2000, 2001 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Debugging malloc glue for Racoon. + */ + +#ifndef _GCMALLOC_H_DEFINED +#define _GCMALLOC_H_DEFINED + +/* ElectricFence needs no special handling. */ + +/* + * Boehm-GC provides GC_malloc(), GC_realloc(), GC_free() functions, + * but not the traditional entry points. So what we do is provide + * malloc(), calloc(), realloc(), and free() entry points in the main + * program and letting the linker do the rest. + */ +#ifdef GC +#define GC_DEBUG +#include + +#ifdef RACOON_MAIN_PROGRAM +void * +malloc(size_t size) +{ + + return (GC_MALLOC(size)); +} + +void * +calloc(size_t number, size_t size) +{ + + /* GC_malloc() clears the storage. */ + return (GC_MALLOC(number * size)); +} + +void * +realloc(void *ptr, size_t size) +{ + + return (GC_REALLOC(ptr, size)); +} + +void +free(void *ptr) +{ + + GC_FREE(ptr); +} + +char * +strdup(const char *str) +{ + + return (GC_STRDUP(str)); +} +#endif /* RACOON_MAIN_PROGRAM */ + +#define racoon_malloc(sz) GC_debug_malloc(sz, GC_EXTRAS) +#define racoon_calloc(cnt, sz) GC_debug_malloc(cnt * sz, GC_EXTRAS) +#define racoon_realloc(old, sz) GC_debug_realloc(old, sz, GC_EXTRAS) +#define racoon_free(p) GC_debug_free(p) +#define racoon_strdup(str) GC_debug_strdup(str) + +#endif /* GC */ + +/* + * Dmalloc only requires that you pull in a header file and link + * against libdmalloc. + */ +#ifdef DMALLOC +#include +#endif /* DMALLOC */ + +#ifdef DEBUG_RECORD_MALLOCATION +#include +#else +#ifndef racoon_malloc +#define racoon_malloc(sz) malloc((sz)) +#endif +#ifndef racoon_calloc +#define racoon_calloc(cnt, sz) calloc((cnt), (sz)) +#endif +#ifndef racoon_realloc +#define racoon_realloc(old, sz) realloc((old), (sz)) +#endif +#ifndef racoon_free +#define racoon_free(p) free((p)) +#endif +#ifndef racoon_strdup +#define racoon_strdup(s) strdup((s)) +#endif +#endif /* DEBUG_RECORD_MALLOCATION */ + +#endif /* _GCMALLOC_H_DEFINED */ diff --git a/ipsec-tools/src/racoon/genlist.c b/ipsec-tools/src/racoon/genlist.c new file mode 100644 index 00000000..b5204c00 --- /dev/null +++ b/ipsec-tools/src/racoon/genlist.c @@ -0,0 +1,174 @@ +/* $NetBSD: genlist.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: genlist.c,v 1.2 2004/07/12 20:43:50 ludvigm Exp */ + +/* + * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. + * Contributed by: Michal Ludvig , SUSE Labs + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include "genlist.h" + +struct genlist * +genlist_init (void) +{ + struct genlist *new = calloc(sizeof(struct genlist), 1); + TAILQ_INIT(new); + return new; +} + +struct genlist_entry * +genlist_insert (struct genlist *head, void *data) +{ + struct genlist_entry *entry = calloc(sizeof(struct genlist_entry), 1); + entry->data = data; + TAILQ_INSERT_HEAD(head, entry, chain); + return entry; +} + +struct genlist_entry * +genlist_append (struct genlist *head, void *data) +{ + struct genlist_entry *entry = calloc(sizeof(struct genlist_entry), 1); + entry->data = data; + TAILQ_INSERT_TAIL(head, entry, chain); + return entry; +} + +void * +genlist_foreach (struct genlist *head, genlist_func_t func, void *arg) +{ + struct genlist_entry *p; + void *ret = NULL; + TAILQ_FOREACH(p, head, chain) { + ret = (*func)(p->data, arg); + if (ret) + break; + } + + return ret; +} + +void * +genlist_next (struct genlist *head, struct genlist_entry **buf) +{ + struct genlist_entry *p; + + if (head) + p = TAILQ_FIRST(head); + else + p = (buf && *buf) ? TAILQ_NEXT(*buf, chain) : NULL; + if (buf) + *buf = p; + return (p ? p->data : NULL); +} + +void +genlist_free (struct genlist *head, genlist_freedata_t func) +{ + struct genlist_entry *p; + + while ((p = TAILQ_LAST(head, genlist)) != NULL) { + TAILQ_REMOVE(head, p, chain); + if (func) + func(p->data); + free(p); + } + free(head); +} + + +#if 0 +/* Here comes the example... */ +struct conf { + struct genlist *l1, *l2; +}; + +void * +print_entry(void *entry, void *arg) +{ + if (!entry) + return NULL; + printf("%s\n", (char *)entry); + return NULL; +} + +void +dump_list(struct genlist *head) +{ + genlist_foreach(head, print_entry, NULL); +} + +void +free_data(void *data) +{ + printf ("removing %s\n", (char *)data); +} + +int main() +{ + struct conf *cf; + char *cp; + struct genlist_entry *gpb; + + cf = calloc(sizeof(struct conf), 1); + cf->l1 = genlist_init(); + cf->l2 = genlist_init(); + + genlist_insert(cf->l1, "Ahoj"); + genlist_insert(cf->l1, "Cau"); + genlist_insert(cf->l1, "Nazdar"); + genlist_insert(cf->l1, "Te buch"); + + genlist_append(cf->l2, "Curak"); + genlist_append(cf->l2, "Kozy"); + genlist_append(cf->l2, "Pica"); + genlist_append(cf->l2, "Prdel"); + + printf("List 2\n"); + dump_list(cf->l2); + printf("\nList 1\n"); + dump_list(cf->l1); + + printf("\nList 2 - using genlist_next()\n"); + for (cp = genlist_next (cf->l2, &gpb); cp; cp = genlist_next (0, &gpb)) + printf("%s\n", cp); + + printf("\nFreeing List 1\n"); + /* the data here isn't actually alloc'd so we would really call + * genlist_free (cf->l1, 0); but to illustrate the idea */ + genlist_free (cf->l1, free_data); + cf->l1 = 0; + + return 0; +} +#endif diff --git a/ipsec-tools/src/racoon/genlist.h b/ipsec-tools/src/racoon/genlist.h new file mode 100644 index 00000000..ee15392b --- /dev/null +++ b/ipsec-tools/src/racoon/genlist.h @@ -0,0 +1,82 @@ +/* $NetBSD: genlist.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: genlist.h,v 1.2 2004/07/12 20:43:50 ludvigm Exp */ + +/* + * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. + * Contributed by: Michal Ludvig , SUSE Labs + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _GENLIST_H +#define _GENLIST_H + +#include + +/* See the bottom of genlist.c for example use. */ + +/* This declares 'struct genlist' */ +TAILQ_HEAD(genlist, genlist_entry); + +/* This is where the data are actually stored. */ +struct genlist_entry { + void *data; + TAILQ_ENTRY(genlist_entry) chain; +}; + +/* This function returns an initialized list head. */ +struct genlist *genlist_init (void); + +/* Insert an entry at the beginning/end og the list. */ +struct genlist_entry *genlist_insert (struct genlist *head, void *data); +struct genlist_entry *genlist_append (struct genlist *head, void *data); + +/* Create a function with this prototype for use with genlist_foreach(). + * See genlist_foreach() description below for details. */ +typedef void *(genlist_func_t)(void *entry, void *arg); + +/* Traverse the list and call 'func' for each entry. As long as func() returns + * NULL the list traversal continues, once it returns non-NULL (usually the + * 'entry' arg), the list traversal exits and the return value is returned + * further from genlist_foreach(). Optional 'arg' may be passed to func(), e.g. + * for some lookup purposes, etc. */ +void *genlist_foreach (struct genlist *head, genlist_func_t func, void *arg); + +/* Get first entry in list if head is not NULL, otherwise get next + * entry based on saved position in list from previous call as stored in buf. + * If buf is NULL no position is saved */ +void *genlist_next (struct genlist *head, struct genlist_entry **buf); + +/* Create a function with this prototype for use with genlist_free() + * to free any storage associated with genlist_entry.data */ +typedef void (genlist_freedata_t)(void *entry); + +/* Free all storage associated with list at head using func to free any + * alloc()d data in data field of genlist_entry */ +void genlist_free (struct genlist *head, genlist_freedata_t func); + +#endif /* _GENLIST_H */ diff --git a/ipsec-tools/src/racoon/getcertsbyname.c b/ipsec-tools/src/racoon/getcertsbyname.c new file mode 100644 index 00000000..1ce7c62e --- /dev/null +++ b/ipsec-tools/src/racoon/getcertsbyname.c @@ -0,0 +1,418 @@ +/* $NetBSD: getcertsbyname.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* $KAME: getcertsbyname.c,v 1.7 2001/11/16 04:12:59 sakane Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#if (defined(__APPLE__) && defined(__MACH__)) +# include +#endif +#include +#ifdef HAVE_LWRES_GETRRSETBYNAME +#include +#include +#else +#include +#endif +#include +#include +#include + +#ifdef DNSSEC_DEBUG +#include +#include +#endif + +#include "netdb_dnssec.h" + +/* XXX should it use ci_errno to hold errno instead of h_errno ? */ +extern int h_errno; + +static struct certinfo *getnewci __P((int, int, int, int, int, + unsigned char *)); + +static struct certinfo * +getnewci(qtype, keytag, algorithm, flags, certlen, cert) + int qtype, keytag, algorithm, flags, certlen; + unsigned char *cert; +{ + struct certinfo *res; + + res = malloc(sizeof(*res)); + if (!res) + return NULL; + + memset(res, 0, sizeof(*res)); + res->ci_type = qtype; + res->ci_keytag = keytag; + res->ci_algorithm = algorithm; + res->ci_flags = flags; + res->ci_certlen = certlen; + res->ci_cert = malloc(certlen); + if (!res->ci_cert) { + free(res); + return NULL; + } + memcpy(res->ci_cert, cert, certlen); + + return res; +} + +void +freecertinfo(ci) + struct certinfo *ci; +{ + struct certinfo *next; + + do { + next = ci->ci_next; + if (ci->ci_cert) + free(ci->ci_cert); + free(ci); + ci = next; + } while (ci); +} + +/* + * get CERT RR by FQDN and create certinfo structure chain. + */ +#ifdef HAVE_LWRES_GETRRSETBYNAME +#define getrrsetbyname lwres_getrrsetbyname +#define freerrset lwres_freerrset +#define hstrerror lwres_hstrerror +#endif +#if defined(HAVE_LWRES_GETRRSETBYNAME) || defined(AHVE_GETRRSETBYNAME) +int +getcertsbyname(name, res) + char *name; + struct certinfo **res; +{ + int rdlength; + char *cp; + int type, keytag, algorithm; + struct certinfo head, *cur; + struct rrsetinfo *rr = NULL; + int i; + int error = -1; + + /* initialize res */ + *res = NULL; + + memset(&head, 0, sizeof(head)); + cur = &head; + + error = getrrsetbyname(name, C_IN, T_CERT, 0, &rr); + if (error) { +#ifdef DNSSEC_DEBUG + printf("getrrsetbyname: %s\n", hstrerror(error)); +#endif + h_errno = NO_RECOVERY; + goto end; + } + + if (rr->rri_rdclass != C_IN + || rr->rri_rdtype != T_CERT + || rr->rri_nrdatas == 0) { +#ifdef DNSSEC_DEBUG + printf("getrrsetbyname: %s", hstrerror(error)); +#endif + h_errno = NO_RECOVERY; + goto end; + } +#ifdef DNSSEC_DEBUG + if (!(rr->rri_flags & LWRDATA_VALIDATED)) + printf("rr is not valid"); +#endif + + for (i = 0; i < rr->rri_nrdatas; i++) { + rdlength = rr->rri_rdatas[i].rdi_length; + cp = rr->rri_rdatas[i].rdi_data; + + GETSHORT(type, cp); /* type */ + rdlength -= INT16SZ; + GETSHORT(keytag, cp); /* key tag */ + rdlength -= INT16SZ; + algorithm = *cp++; /* algorithm */ + rdlength -= 1; + +#ifdef DNSSEC_DEBUG + printf("type=%d keytag=%d alg=%d len=%d\n", + type, keytag, algorithm, rdlength); +#endif + + /* create new certinfo */ + cur->ci_next = getnewci(type, keytag, algorithm, + rr->rri_flags, rdlength, cp); + if (!cur->ci_next) { +#ifdef DNSSEC_DEBUG + printf("getnewci: %s", strerror(errno)); +#endif + h_errno = NO_RECOVERY; + goto end; + } + cur = cur->ci_next; + } + + *res = head.ci_next; + error = 0; + +end: + if (rr) + freerrset(rr); + if (error && head.ci_next) + freecertinfo(head.ci_next); + + return error; +} +#else /*!HAVE_LWRES_GETRRSETBYNAME*/ +int +getcertsbyname(name, res) + char *name; + struct certinfo **res; +{ + unsigned char *answer = NULL, *p; + int buflen, anslen, len; + HEADER *hp; + int qdcount, ancount, rdlength; + unsigned char *cp, *eom; + char hostbuf[1024]; /* XXX */ + int qtype, qclass, keytag, algorithm; + struct certinfo head, *cur; + int error = -1; + + /* initialize res */ + *res = NULL; + + memset(&head, 0, sizeof(head)); + cur = &head; + + /* get CERT RR */ + buflen = 512; + do { + + buflen *= 2; + p = realloc(answer, buflen); + if (!p) { +#ifdef DNSSEC_DEBUG + printf("realloc: %s", strerror(errno)); +#endif + h_errno = NO_RECOVERY; + goto end; + } + answer = p; + + anslen = res_query(name, C_IN, T_CERT, answer, buflen); + if (anslen == -1) + goto end; + + } while (buflen < anslen); + +#ifdef DNSSEC_DEBUG + printf("get a DNS packet len=%d\n", anslen); +#endif + + /* parse CERT RR */ + eom = answer + anslen; + + hp = (HEADER *)answer; + qdcount = ntohs(hp->qdcount); + ancount = ntohs(hp->ancount); + + /* question section */ + if (qdcount != 1) { +#ifdef DNSSEC_DEBUG + printf("query count is not 1.\n"); +#endif + h_errno = NO_RECOVERY; + goto end; + } + cp = (unsigned char *)(hp + 1); + len = dn_expand(answer, eom, cp, hostbuf, sizeof(hostbuf)); + if (len < 0) { +#ifdef DNSSEC_DEBUG + printf("dn_expand failed.\n"); +#endif + goto end; + } + cp += len; + GETSHORT(qtype, cp); /* QTYPE */ + GETSHORT(qclass, cp); /* QCLASS */ + + /* answer section */ + while (ancount-- && cp < eom) { + len = dn_expand(answer, eom, cp, hostbuf, sizeof(hostbuf)); + if (len < 0) { +#ifdef DNSSEC_DEBUG + printf("dn_expand failed.\n"); +#endif + goto end; + } + cp += len; + GETSHORT(qtype, cp); /* TYPE */ + GETSHORT(qclass, cp); /* CLASS */ + cp += INT32SZ; /* TTL */ + GETSHORT(rdlength, cp); /* RDLENGTH */ + + /* CERT RR */ + if (qtype != T_CERT) { +#ifdef DNSSEC_DEBUG + printf("not T_CERT\n"); +#endif + h_errno = NO_RECOVERY; + goto end; + } + GETSHORT(qtype, cp); /* type */ + rdlength -= INT16SZ; + GETSHORT(keytag, cp); /* key tag */ + rdlength -= INT16SZ; + algorithm = *cp++; /* algorithm */ + rdlength -= 1; + if (cp + rdlength > eom) { +#ifdef DNSSEC_DEBUG + printf("rdlength is too long.\n"); +#endif + h_errno = NO_RECOVERY; + goto end; + } +#ifdef DNSSEC_DEBUG + printf("type=%d keytag=%d alg=%d len=%d\n", + qtype, keytag, algorithm, rdlength); +#endif + + /* create new certinfo */ + cur->ci_next = getnewci(qtype, keytag, algorithm, + 0, rdlength, cp); + if (!cur->ci_next) { +#ifdef DNSSEC_DEBUG + printf("getnewci: %s", strerror(errno)); +#endif + h_errno = NO_RECOVERY; + goto end; + } + cur = cur->ci_next; + + cp += rdlength; + } + + *res = head.ci_next; + error = 0; + +end: + if (answer) + free(answer); + if (error && head.ci_next) + freecertinfo(head.ci_next); + + return error; +} +#endif + +#ifdef DNSSEC_DEBUG +int +b64encode(p, len) + char *p; + int len; +{ + static const char b64t[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/="; + + while (len > 2) { + printf("%c", b64t[(p[0] >> 2) & 0x3f]); + printf("%c", b64t[((p[0] << 4) & 0x30) | ((p[1] >> 4) & 0x0f)]); + printf("%c", b64t[((p[1] << 2) & 0x3c) | ((p[2] >> 6) & 0x03)]); + printf("%c", b64t[p[2] & 0x3f]); + len -= 3; + p += 3; + } + + if (len == 2) { + printf("%c", b64t[(p[0] >> 2) & 0x3f]); + printf("%c", b64t[((p[0] << 4) & 0x30)| ((p[1] >> 4) & 0x0f)]); + printf("%c", b64t[((p[1] << 2) & 0x3c)]); + printf("%c", '='); + } else if (len == 1) { + printf("%c", b64t[(p[0] >> 2) & 0x3f]); + printf("%c", b64t[((p[0] << 4) & 0x30)]); + printf("%c", '='); + printf("%c", '='); + } + + return 0; +} + +int +main(ac, av) + int ac; + char **av; +{ + struct certinfo *res, *p; + int i; + + if (ac < 2) { + printf("Usage: a.out (FQDN)\n"); + exit(1); + } + + i = getcertsbyname(*(av + 1), &res); + if (i != 0) { + herror("getcertsbyname"); + exit(1); + } + printf("getcertsbyname succeeded.\n"); + + i = 0; + for (p = res; p; p = p->ci_next) { + printf("certinfo[%d]:\n", i); + printf("\tci_type=%d\n", p->ci_type); + printf("\tci_keytag=%d\n", p->ci_keytag); + printf("\tci_algorithm=%d\n", p->ci_algorithm); + printf("\tci_flags=%d\n", p->ci_flags); + printf("\tci_certlen=%d\n", p->ci_certlen); + printf("\tci_cert: "); + b64encode(p->ci_cert, p->ci_certlen); + printf("\n"); + i++; + } + + freecertinfo(res); + + exit(0); +} +#endif diff --git a/ipsec-tools/src/racoon/gnuc.h b/ipsec-tools/src/racoon/gnuc.h new file mode 100644 index 00000000..8537ad2b --- /dev/null +++ b/ipsec-tools/src/racoon/gnuc.h @@ -0,0 +1,46 @@ +/* $NetBSD: gnuc.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: gnuc.h,v 1.4 2004/11/18 15:14:44 ludvigm Exp */ + +/* Define __P() macro, if necessary */ +#undef __P +#ifndef __P +#if __STDC__ +#define __P(protos) protos +#else +#define __P(protos) () +#endif +#endif + +/* inline foo */ +#ifdef __GNUC__ +#define inline __inline +#else +#define inline +#endif + +/* + * Handle new and old "dead" routine prototypes + * + * For example: + * + * __dead void foo(void) __attribute__((volatile)); + * + */ +#ifdef __GNUC__ +#ifndef __dead +#define __dead volatile +#endif +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) +#ifndef __attribute__ +#define __attribute__(args) +#endif +#endif +#else +#ifndef __dead +#define __dead +#endif +#ifndef __attribute__ +#define __attribute__(args) +#endif +#endif diff --git a/ipsec-tools/src/racoon/grabmyaddr.c b/ipsec-tools/src/racoon/grabmyaddr.c new file mode 100644 index 00000000..467a4876 --- /dev/null +++ b/ipsec-tools/src/racoon/grabmyaddr.c @@ -0,0 +1,881 @@ +/* $NetBSD: grabmyaddr.c,v 1.28.2.2 2013/04/12 09:53:52 tteras Exp $ */ +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * Copyright (C) 2008 Timo Teras . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __linux__ +#include +#include +#define USE_NETLINK +#else +#include +#include +#include +#include +#define USE_ROUTE +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "session.h" +#include "debug.h" + +#include "localconf.h" +#include "handler.h" +#include "grabmyaddr.h" +#include "sockmisc.h" +#include "isakmp_var.h" +#include "gcmalloc.h" +#include "nattraversal.h" + +static int kernel_receive __P((void *ctx, int fd)); +static int kernel_open_socket __P((void)); +static void kernel_sync __P((void)); + +struct myaddr { + LIST_ENTRY(myaddr) chain; + struct sockaddr_storage addr; + int fd; + int udp_encap; +}; + +static LIST_HEAD(_myaddr_list_, myaddr) configured, opened; + +static void +myaddr_delete(my) + struct myaddr *my; +{ + if (my->fd != -1) + isakmp_close(my->fd); + LIST_REMOVE(my, chain); + racoon_free(my); +} + +static int +myaddr_configured(addr) + struct sockaddr *addr; +{ + struct myaddr *cfg; + + if (LIST_EMPTY(&configured)) + return TRUE; + + LIST_FOREACH(cfg, &configured, chain) { + if (cmpsaddr(addr, (struct sockaddr *) &cfg->addr) <= CMPSADDR_WILDPORT_MATCH) + return TRUE; + } + + return FALSE; +} + +static int +myaddr_open(addr, udp_encap) + struct sockaddr *addr; + int udp_encap; +{ + struct myaddr *my; + + /* Already open? */ + LIST_FOREACH(my, &opened, chain) { + if (cmpsaddr(addr, (struct sockaddr *) &my->addr) <= CMPSADDR_WILDPORT_MATCH) + return TRUE; + } + + my = racoon_calloc(1, sizeof(struct myaddr)); + if (my == NULL) + return FALSE; + + memcpy(&my->addr, addr, sysdep_sa_len(addr)); + my->fd = isakmp_open(addr, udp_encap); + if (my->fd < 0) { + racoon_free(my); + return FALSE; + } + my->udp_encap = udp_encap; + LIST_INSERT_HEAD(&opened, my, chain); + return TRUE; +} + +static int +myaddr_open_all_configured(addr) + struct sockaddr *addr; +{ + /* create all configured, not already opened addresses */ + struct myaddr *cfg, *my; + + if (addr != NULL) { + switch (addr->sa_family) { + case AF_INET: +#ifdef INET6 + case AF_INET6: +#endif + break; + default: + return FALSE; + } + } + + LIST_FOREACH(cfg, &configured, chain) { + if (addr != NULL && + cmpsaddr(addr, (struct sockaddr *) &cfg->addr) > CMPSADDR_WILDPORT_MATCH) + continue; + if (!myaddr_open((struct sockaddr *) &cfg->addr, cfg->udp_encap)) + return FALSE; + } + if (LIST_EMPTY(&configured)) { +#ifdef ENABLE_HYBRID + /* Exclude any address we got through ISAKMP mode config */ + if (exclude_cfg_addr(addr) == 0) + return FALSE; +#endif + set_port(addr, lcconf->port_isakmp); + myaddr_open(addr, FALSE); +#ifdef ENABLE_NATT + set_port(addr, lcconf->port_isakmp_natt); + myaddr_open(addr, TRUE); +#endif + } + return TRUE; +} + +static void +myaddr_close_all_open(addr) + struct sockaddr *addr; +{ + /* delete all matching open sockets */ + struct myaddr *my, *next; + + for (my = LIST_FIRST(&opened); my; my = next) { + next = LIST_NEXT(my, chain); + + if (cmpsaddr((struct sockaddr *) addr, + (struct sockaddr *) &my->addr) + <= CMPSADDR_WOP_MATCH) + myaddr_delete(my); + } +} + +static void +myaddr_flush_list(list) + struct _myaddr_list_ *list; +{ + struct myaddr *my, *next; + + for (my = LIST_FIRST(list); my; my = next) { + next = LIST_NEXT(my, chain); + myaddr_delete(my); + } +} + +void +myaddr_flush() +{ + myaddr_flush_list(&configured); +} + +int +myaddr_listen(addr, udp_encap) + struct sockaddr *addr; + int udp_encap; +{ + struct myaddr *my; + + if (sysdep_sa_len(addr) > sizeof(my->addr)) { + plog(LLV_ERROR, LOCATION, NULL, + "sockaddr size larger than sockaddr_storage\n"); + return -1; + } + + my = racoon_calloc(1, sizeof(struct myaddr)); + if (my == NULL) + return -1; + + memcpy(&my->addr, addr, sysdep_sa_len(addr)); + my->udp_encap = udp_encap; + my->fd = -1; + LIST_INSERT_HEAD(&configured, my, chain); + + return 0; +} + +void +myaddr_sync() +{ + struct myaddr *my, *next; + + if (!lcconf->strict_address) { + kernel_sync(); + + /* delete all existing listeners which are not configured */ + for (my = LIST_FIRST(&opened); my; my = next) { + next = LIST_NEXT(my, chain); + + if (!myaddr_configured((struct sockaddr *) &my->addr)) + myaddr_delete(my); + } + } +} + +int +myaddr_getfd(addr) + struct sockaddr *addr; +{ + struct myaddr *my; + + LIST_FOREACH(my, &opened, chain) { + if (cmpsaddr((struct sockaddr *) &my->addr, addr) <= CMPSADDR_WILDPORT_MATCH) + return my->fd; + } + + return -1; +} + +int +myaddr_getsport(addr) + struct sockaddr *addr; +{ + struct myaddr *my; + int port = 0, wport; + + LIST_FOREACH(my, &opened, chain) { + switch (cmpsaddr((struct sockaddr *) &my->addr, addr)) { + case CMPSADDR_MATCH: + return extract_port((struct sockaddr *) &my->addr); + case CMPSADDR_WILDPORT_MATCH: + wport = extract_port((struct sockaddr *) &my->addr); + if (port == 0 || wport < port) + port = wport; + break; + } + } + + if (port == 0) + port = PORT_ISAKMP; + + return port; +} + +void +myaddr_init_lists() +{ + LIST_INIT(&configured); + LIST_INIT(&opened); +} + +int +myaddr_init() +{ + if (!lcconf->strict_address) { + lcconf->rtsock = kernel_open_socket(); + if (lcconf->rtsock < 0) + return -1; + monitor_fd(lcconf->rtsock, kernel_receive, NULL, 0); + } else { + lcconf->rtsock = -1; + if (!myaddr_open_all_configured(NULL)) + return -1; + } + return 0; +} + +void +myaddr_close() +{ + myaddr_flush_list(&configured); + myaddr_flush_list(&opened); + if (lcconf->rtsock != -1) { + unmonitor_fd(lcconf->rtsock); + close(lcconf->rtsock); + } +} + +#if defined(USE_NETLINK) + +static int netlink_fd = -1; + +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) + +static void +parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) +{ + memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); + while (RTA_OK(rta, len)) { + if (rta->rta_type <= max) + tb[rta->rta_type] = rta; + rta = RTA_NEXT(rta,len); + } +} + +static int +netlink_add_rtattr_l(struct nlmsghdr *n, int maxlen, int type, + const void *data, int alen) +{ + int len = RTA_LENGTH(alen); + struct rtattr *rta; + + if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) + return FALSE; + + rta = NLMSG_TAIL(n); + rta->rta_type = type; + rta->rta_len = len; + memcpy(RTA_DATA(rta), data, alen); + n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); + return TRUE; +} + +static int +netlink_enumerate(fd, family, type) + int fd; + int family; + int type; +{ + struct { + struct nlmsghdr nlh; + struct rtgenmsg g; + } req; + struct sockaddr_nl addr; + static __u32 seq = 0; + + memset(&addr, 0, sizeof(addr)); + addr.nl_family = AF_NETLINK; + + memset(&req, 0, sizeof(req)); + req.nlh.nlmsg_len = sizeof(req); + req.nlh.nlmsg_type = type; + req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; + req.nlh.nlmsg_pid = 0; + req.nlh.nlmsg_seq = ++seq; + req.g.rtgen_family = family; + + return sendto(fd, (void *) &req, sizeof(req), 0, + (struct sockaddr *) &addr, sizeof(addr)) >= 0; +} + +static void +netlink_add_del_address(int add, struct sockaddr *saddr) +{ + plog(LLV_DEBUG, LOCATION, NULL, + "Netlink: address %s %s\n", + saddrwop2str((struct sockaddr *) saddr), + add ? "added" : "deleted"); + + if (add) + myaddr_open_all_configured(saddr); + else + myaddr_close_all_open(saddr); +} + +#ifdef INET6 +static int +netlink_process_addr(struct nlmsghdr *h) +{ + struct sockaddr_storage addr; + struct ifaddrmsg *ifa; + struct rtattr *rta[IFA_MAX+1]; + struct sockaddr_in6 *sin6; + + ifa = NLMSG_DATA(h); + parse_rtattr(rta, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(h)); + + if (ifa->ifa_family != AF_INET6) + return 0; + if (ifa->ifa_flags & IFA_F_TENTATIVE) + return 0; + if (rta[IFA_LOCAL] == NULL) + rta[IFA_LOCAL] = rta[IFA_ADDRESS]; + if (rta[IFA_LOCAL] == NULL) + return 0; + + memset(&addr, 0, sizeof(addr)); + addr.ss_family = ifa->ifa_family; + sin6 = (struct sockaddr_in6 *) &addr; + memcpy(&sin6->sin6_addr, RTA_DATA(rta[IFA_LOCAL]), + sizeof(sin6->sin6_addr)); + if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + return 0; + sin6->sin6_scope_id = ifa->ifa_index; + + netlink_add_del_address(h->nlmsg_type == RTM_NEWADDR, + (struct sockaddr *) &addr); + + return 0; +} +#endif + +static int +netlink_route_is_local(int family, const unsigned char *addr, size_t addr_len) +{ + struct { + struct nlmsghdr n; + struct rtmsg r; + char buf[1024]; + } req; + struct rtmsg *r = NLMSG_DATA(&req.n); + struct rtattr *rta[RTA_MAX+1]; + struct sockaddr_nl nladdr; + ssize_t rlen; + + memset(&req, 0, sizeof(req)); + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); + req.n.nlmsg_flags = NLM_F_REQUEST; + req.n.nlmsg_type = RTM_GETROUTE; + req.r.rtm_family = family; + netlink_add_rtattr_l(&req.n, sizeof(req), RTA_DST, + addr, addr_len); + req.r.rtm_dst_len = addr_len * 8; + + memset(&nladdr, 0, sizeof(nladdr)); + nladdr.nl_family = AF_NETLINK; + + if (sendto(netlink_fd, &req, sizeof(req), 0, + (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) + return 0; + rlen = recv(netlink_fd, &req, sizeof(req), 0); + if (rlen < 0) + return 0; + + return req.n.nlmsg_type == RTM_NEWROUTE && + req.r.rtm_type == RTN_LOCAL; +} + +static int +netlink_process_route(struct nlmsghdr *h) +{ + struct sockaddr_storage addr; + struct rtmsg *rtm; + struct rtattr *rta[RTA_MAX+1]; + struct sockaddr_in *sin; +#ifdef INET6 + struct sockaddr_in6 *sin6; +#endif + + rtm = NLMSG_DATA(h); + + /* local IP addresses get local route in the local table */ + if (rtm->rtm_type != RTN_LOCAL || + rtm->rtm_table != RT_TABLE_LOCAL) + return 0; + + parse_rtattr(rta, IFA_MAX, RTM_RTA(rtm), IFA_PAYLOAD(h)); + if (rta[RTA_DST] == NULL) + return 0; + + /* setup the socket address */ + memset(&addr, 0, sizeof(addr)); + addr.ss_family = rtm->rtm_family; + switch (rtm->rtm_family) { + case AF_INET: + sin = (struct sockaddr_in *) &addr; + memcpy(&sin->sin_addr, RTA_DATA(rta[RTA_DST]), + sizeof(sin->sin_addr)); + break; +#ifdef INET6 + case AF_INET6: + sin6 = (struct sockaddr_in6 *) &addr; + memcpy(&sin6->sin6_addr, RTA_DATA(rta[RTA_DST]), + sizeof(sin6->sin6_addr)); + /* Link-local addresses are handled with RTM_NEWADDR + * notifications */ + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + return 0; + break; +#endif + default: + return 0; + } + + /* If local route was deleted, check if there is still local + * route for the same IP on another interface */ + if (h->nlmsg_type == RTM_DELROUTE && + netlink_route_is_local(rtm->rtm_family, + RTA_DATA(rta[RTA_DST]), + RTA_PAYLOAD(rta[RTA_DST]))) { + plog(LLV_DEBUG, LOCATION, NULL, + "Netlink: not deleting %s yet, it exists still\n", + saddrwop2str((struct sockaddr *) &addr)); + return 0; + } + + netlink_add_del_address(h->nlmsg_type == RTM_NEWROUTE, + (struct sockaddr *) &addr); + return 0; +} + +static int +netlink_process(struct nlmsghdr *h) +{ + switch (h->nlmsg_type) { +#ifdef INET6 + case RTM_NEWADDR: + case RTM_DELADDR: + return netlink_process_addr(h); +#endif + case RTM_NEWROUTE: + case RTM_DELROUTE: + return netlink_process_route(h); + } + return 0; +} + +static int +kernel_receive(ctx, fd) + void *ctx; + int fd; +{ + struct sockaddr_nl nladdr; + struct iovec iov; + struct msghdr msg = { + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, + }; + struct nlmsghdr *h; + int len, status; + char buf[16*1024]; + + iov.iov_base = buf; + while (1) { + iov.iov_len = sizeof(buf); + status = recvmsg(fd, &msg, MSG_DONTWAIT); + if (status < 0) { + if (errno == EINTR) + continue; + if (errno == EAGAIN) + return FALSE; + continue; + } + if (status == 0) + return FALSE; + + h = (struct nlmsghdr *) buf; + while (NLMSG_OK(h, status)) { + netlink_process(h); + h = NLMSG_NEXT(h, status); + } + } + + return TRUE; +} + +static int +netlink_open_socket() +{ + int fd; + + fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (fd < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "socket(PF_NETLINK) failed: %s", + strerror(errno)); + return -1; + } + close_on_exec(fd); + if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) + plog(LLV_WARNING, LOCATION, NULL, + "failed to put socket in non-blocking mode\n"); + + return fd; +} + +static int +kernel_open_socket() +{ + struct sockaddr_nl nl; + int fd; + + if (netlink_fd < 0) { + netlink_fd = netlink_open_socket(); + if (netlink_fd < 0) + return -1; + } + + fd = netlink_open_socket(); + if (fd < 0) + return fd; + + /* We monitor IPv4 addresses using RTMGRP_IPV4_ROUTE group + * the get the RTN_LOCAL routes which are automatically added + * by kernel. This is because: + * - Linux kernel has a bug that calling bind() immediately + * after IPv4 RTM_NEWADDR event can fail + * - if IP is configured in multiple interfaces, we get + * RTM_DELADDR for each of them. RTN_LOCAL gets deleted only + * after the last IP address is deconfigured. + * The latter reason is also why I chose to use route + * notifications for IPv6. However, we do need to use RTM_NEWADDR + * for the link-local IPv6 addresses to get the interface index + * that is needed in bind(). + */ + memset(&nl, 0, sizeof(nl)); + nl.nl_family = AF_NETLINK; + nl.nl_groups = RTMGRP_IPV4_ROUTE +#ifdef INET6 + | RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE +#endif + ; + if (bind(fd, (struct sockaddr*) &nl, sizeof(nl)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "bind(PF_NETLINK) failed: %s\n", + strerror(errno)); + close(fd); + return -1; + } + return fd; +} + +static void +kernel_sync() +{ + int fd = lcconf->rtsock; + + /* refresh addresses */ + if (!netlink_enumerate(fd, PF_UNSPEC, RTM_GETROUTE)) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to enumerate addresses: %s\n", + strerror(errno)); + } + while (kernel_receive(NULL, fd) == TRUE); + +#ifdef INET6 + if (!netlink_enumerate(fd, PF_INET6, RTM_GETADDR)) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to enumerate addresses: %s\n", + strerror(errno)); + } + while (kernel_receive(NULL, fd) == TRUE); +#endif +} + +#elif defined(USE_ROUTE) + +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) + +#define SAROUNDUP(X) ROUNDUP(((struct sockaddr *)(X))->sa_len) + +static size_t +parse_address(start, end, dest) + caddr_t start; + caddr_t end; + struct sockaddr_storage *dest; +{ + int len; + + if (start >= end) + return 0; + + len = SAROUNDUP(start); + if (start + len > end) + return end - start; + + if (dest != NULL && len <= sizeof(struct sockaddr_storage)) + memcpy(dest, start, len); + + return len; +} + +static void +parse_addresses(start, end, flags, addr) + caddr_t start; + caddr_t end; + int flags; + struct sockaddr_storage *addr; +{ + memset(addr, 0, sizeof(*addr)); + if (flags & RTA_DST) + start += parse_address(start, end, NULL); + if (flags & RTA_GATEWAY) + start += parse_address(start, end, NULL); + if (flags & RTA_NETMASK) + start += parse_address(start, end, NULL); + if (flags & RTA_GENMASK) + start += parse_address(start, end, NULL); + if (flags & RTA_IFP) + start += parse_address(start, end, NULL); + if (flags & RTA_IFA) + start += parse_address(start, end, addr); + if (flags & RTA_AUTHOR) + start += parse_address(start, end, NULL); + if (flags & RTA_BRD) + start += parse_address(start, end, NULL); +} + +static void +kernel_handle_message(msg) + caddr_t msg; +{ + struct rt_msghdr *rtm = (struct rt_msghdr *) msg; + struct ifa_msghdr *ifa = (struct ifa_msghdr *) msg; + struct sockaddr_storage addr; + + switch (rtm->rtm_type) { + case RTM_NEWADDR: + parse_addresses(ifa + 1, msg + ifa->ifam_msglen, + ifa->ifam_addrs, &addr); + myaddr_open_all_configured((struct sockaddr *) &addr); + break; + case RTM_DELADDR: + parse_addresses(ifa + 1, msg + ifa->ifam_msglen, + ifa->ifam_addrs, &addr); + myaddr_close_all_open((struct sockaddr *) &addr); + break; + case RTM_ADD: + case RTM_DELETE: + case RTM_CHANGE: + case RTM_GET: + case RTM_MISS: + case RTM_IFINFO: +#ifdef RTM_OIFINFO + case RTM_OIFINFO: +#endif +#ifdef RTM_NEWMADDR + case RTM_NEWMADDR: + case RTM_DELMADDR: +#endif +#ifdef RTM_IFANNOUNCE + case RTM_IFANNOUNCE: +#endif + break; + default: + plog(LLV_WARNING, LOCATION, NULL, + "unrecognized route message with rtm_type: %d\n", + rtm->rtm_type); + break; + } +} + +static int +kernel_receive(ctx, fd) + void *ctx; + int fd; +{ + char buf[16*1024]; + struct rt_msghdr *rtm = (struct rt_msghdr *) buf; + int len; + + len = read(fd, &buf, sizeof(buf)); + if (len <= 0) { + if (len < 0 && errno != EWOULDBLOCK && errno != EAGAIN) + plog(LLV_WARNING, LOCATION, NULL, + "routing socket error: %s", strerror(errno)); + return FALSE; + } + + if (rtm->rtm_msglen != len) { + plog(LLV_WARNING, LOCATION, NULL, + "kernel_receive: rtm->rtm_msglen %d, len %d, type %d\n", + rtm->rtm_msglen, len, rtm->rtm_type); + return FALSE; + } + + kernel_handle_message(buf); + return TRUE; +} + +static int +kernel_open_socket() +{ + int fd; + + fd = socket(PF_ROUTE, SOCK_RAW, 0); + if (fd < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "socket(PF_ROUTE) failed: %s", + strerror(errno)); + return -1; + } + close_on_exec(fd); + if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) + plog(LLV_WARNING, LOCATION, NULL, + "failed to put socket in non-blocking mode\n"); + + return fd; +} + +static void +kernel_sync() +{ + caddr_t ref, buf, end; + size_t bufsiz; + struct if_msghdr *ifm; + struct interface *ifp; + +#define MIBSIZ 6 + int mib[MIBSIZ] = { + CTL_NET, + PF_ROUTE, + 0, + 0, /* AF_INET & AF_INET6 */ + NET_RT_IFLIST, + 0 + }; + + if (sysctl(mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0) { + plog(LLV_WARNING, LOCATION, NULL, + "sysctl() error: %s", strerror(errno)); + return; + } + + ref = buf = racoon_malloc(bufsiz); + + if (sysctl(mib, MIBSIZ, buf, &bufsiz, NULL, 0) >= 0) { + /* Parse both interfaces and addresses. */ + for (end = buf + bufsiz; buf < end; buf += ifm->ifm_msglen) { + ifm = (struct if_msghdr *) buf; + kernel_handle_message(buf); + } + } else { + plog(LLV_WARNING, LOCATION, NULL, + "sysctl() error: %s", strerror(errno)); + } + + racoon_free(ref); +} + +#else + +#error No supported interface to monitor local addresses. + +#endif diff --git a/ipsec-tools/src/racoon/grabmyaddr.h b/ipsec-tools/src/racoon/grabmyaddr.h new file mode 100644 index 00000000..a105d8ff --- /dev/null +++ b/ipsec-tools/src/racoon/grabmyaddr.h @@ -0,0 +1,48 @@ +/* $NetBSD: grabmyaddr.h,v 1.6 2009/04/21 18:38:32 tteras Exp $ */ + +/* Id: grabmyaddr.h,v 1.5 2004/06/11 16:00:16 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _GRABMYADDR_H +#define _GRABMYADDR_H + +extern void myaddr_init_lists __P((void)); +extern int myaddr_init __P((void)); +extern void myaddr_close __P((void)); + +extern void myaddr_flush __P((void)); +extern int myaddr_listen __P((struct sockaddr *, int)); +extern void myaddr_sync __P((void)); + +extern int myaddr_getfd __P((struct sockaddr *)); +extern int myaddr_getsport __P((struct sockaddr *)); + +#endif /* _GRABMYADDR_H */ diff --git a/ipsec-tools/src/racoon/gssapi.c b/ipsec-tools/src/racoon/gssapi.c new file mode 100644 index 00000000..e64b2015 --- /dev/null +++ b/ipsec-tools/src/racoon/gssapi.c @@ -0,0 +1,749 @@ +/* $NetBSD: gssapi.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* $KAME: gssapi.c,v 1.19 2001/04/03 15:51:55 thorpej Exp $ */ + +/* + * Copyright 2000 Wasabi Systems, Inc. + * All rights reserved. + * + * This software was written by Frank van der Linden of Wasabi Systems + * for Zembu Labs, Inc. http://www.zembu.com/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#ifdef HAVE_GSSAPI + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "schedule.h" +#include "debug.h" + +#include "localconf.h" +#include "remoteconf.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "oakley.h" +#include "handler.h" +#include "ipsec_doi.h" +#include "crypto_openssl.h" +#include "pfkey.h" +#include "isakmp_ident.h" +#include "isakmp_inf.h" +#include "vendorid.h" +#include "gcmalloc.h" + +#include "gssapi.h" + +static void +gssapi_error(OM_uint32 status_code, const char *where, + const char *fmt, ...) +{ + OM_uint32 message_context, maj_stat, min_stat; + gss_buffer_desc status_string; + va_list ap; + + va_start(ap, fmt); + plogv(LLV_ERROR, where, NULL, fmt, ap); + va_end(ap); + + message_context = 0; + + do { + maj_stat = gss_display_status(&min_stat, status_code, + GSS_C_MECH_CODE, GSS_C_NO_OID, &message_context, + &status_string); + if (GSS_ERROR(maj_stat)) + plog(LLV_ERROR, LOCATION, NULL, + "UNABLE TO GET GSSAPI ERROR CODE\n"); + else { + plog(LLV_ERROR, where, NULL, + "%s\n", (char *)status_string.value); + gss_release_buffer(&min_stat, &status_string); + } + } while (message_context != 0); +} + +/* + * vmbufs and gss_buffer_descs are really just the same on NetBSD, but + * this is to be portable. + */ +static int +gssapi_vm2gssbuf(vchar_t *vmbuf, gss_buffer_t gsstoken) +{ + + gsstoken->value = racoon_malloc(vmbuf->l); + if (gsstoken->value == NULL) + return -1; + memcpy(gsstoken->value, vmbuf->v, vmbuf->l); + gsstoken->length = vmbuf->l; + + return 0; +} + +static int +gssapi_gss2vmbuf(gss_buffer_t gsstoken, vchar_t **vmbuf) +{ + + *vmbuf = vmalloc(gsstoken->length); + if (*vmbuf == NULL) + return -1; + memcpy((*vmbuf)->v, gsstoken->value, gsstoken->length); + (*vmbuf)->l = gsstoken->length; + + return 0; +} + +vchar_t * +gssapi_get_default_gss_id(void) +{ + char name[NI_MAXHOST]; + vchar_t *gssid; + + if (gethostname(name, sizeof(name)) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "gethostname failed: %s\n", + strerror(errno)); + return (NULL); + } + name[sizeof(name) - 1] = '\0'; + + gssid = racoon_malloc(sizeof(*gssid)); + gssid->l = asprintf(&gssid->v, "%s/%s", GSSAPI_DEF_NAME, name); + + return (gssid); +} + +static int +gssapi_get_default_name(struct ph1handle *iph1, int remote, gss_name_t *service) +{ + char name[NI_MAXHOST]; + struct sockaddr *sa; + char* buf = NULL; + gss_buffer_desc name_token; + OM_uint32 min_stat, maj_stat; + + sa = remote ? iph1->remote : iph1->local; + + if (getnameinfo(sa, sysdep_sa_len(sa), name, NI_MAXHOST, NULL, 0, 0) != 0) + return -1; + + name_token.length = asprintf(&buf, "%s@%s", GSSAPI_DEF_NAME, name); + name_token.value = buf; + + maj_stat = gss_import_name(&min_stat, &name_token, + GSS_C_NT_HOSTBASED_SERVICE, service); + if (GSS_ERROR(maj_stat)) { + gssapi_error(min_stat, LOCATION, "import name\n"); + maj_stat = gss_release_buffer(&min_stat, &name_token); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release name_token"); + return -1; + } + maj_stat = gss_release_buffer(&min_stat, &name_token); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release name_token"); + + return 0; +} + +static int +gssapi_init(struct ph1handle *iph1) +{ + struct gssapi_ph1_state *gps; + gss_buffer_desc id_token, cred_token; + gss_buffer_t cred = &cred_token; + gss_name_t princ, canon_princ; + OM_uint32 maj_stat, min_stat; + + gps = racoon_calloc(1, sizeof (struct gssapi_ph1_state)); + if (gps == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "racoon_calloc failed\n"); + return -1; + } + gps->gss_context = GSS_C_NO_CONTEXT; + gps->gss_cred = GSS_C_NO_CREDENTIAL; + + gssapi_set_state(iph1, gps); + + if (iph1->rmconf->proposal->gssid != NULL) { + id_token.length = iph1->rmconf->proposal->gssid->l; + id_token.value = iph1->rmconf->proposal->gssid->v; + maj_stat = gss_import_name(&min_stat, &id_token, GSS_C_NO_OID, + &princ); + if (GSS_ERROR(maj_stat)) { + gssapi_error(min_stat, LOCATION, "import name\n"); + gssapi_free_state(iph1); + return -1; + } + } else + gssapi_get_default_name(iph1, 0, &princ); + + maj_stat = gss_canonicalize_name(&min_stat, princ, GSS_C_NO_OID, + &canon_princ); + if (GSS_ERROR(maj_stat)) { + gssapi_error(min_stat, LOCATION, "canonicalize name\n"); + maj_stat = gss_release_name(&min_stat, &princ); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release princ\n"); + gssapi_free_state(iph1); + return -1; + } + maj_stat = gss_release_name(&min_stat, &princ); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release princ\n"); + + maj_stat = gss_export_name(&min_stat, canon_princ, cred); + if (GSS_ERROR(maj_stat)) { + gssapi_error(min_stat, LOCATION, "export name\n"); + maj_stat = gss_release_name(&min_stat, &canon_princ); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, + "release canon_princ\n"); + gssapi_free_state(iph1); + return -1; + } + +#if 0 + /* + * XXXJRT Did this debug message ever work? This is a GSS name + * blob at this point. + */ + plog(LLV_DEBUG, LOCATION, NULL, "will try to acquire '%.*s' creds\n", + cred->length, cred->value); +#endif + + maj_stat = gss_release_buffer(&min_stat, cred); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release cred buffer\n"); + + maj_stat = gss_acquire_cred(&min_stat, canon_princ, GSS_C_INDEFINITE, + GSS_C_NO_OID_SET, GSS_C_BOTH, &gps->gss_cred, NULL, NULL); + if (GSS_ERROR(maj_stat)) { + gssapi_error(min_stat, LOCATION, "acquire cred\n"); + maj_stat = gss_release_name(&min_stat, &canon_princ); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, + "release canon_princ\n"); + gssapi_free_state(iph1); + return -1; + } + maj_stat = gss_release_name(&min_stat, &canon_princ); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release canon_princ\n"); + + return 0; +} + +int +gssapi_get_itoken(struct ph1handle *iph1, int *lenp) +{ + struct gssapi_ph1_state *gps; + gss_buffer_desc empty, name_token; + gss_buffer_t itoken, rtoken, dummy; + OM_uint32 maj_stat, min_stat; + gss_name_t partner; + + if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0) + return -1; + + gps = gssapi_get_state(iph1); + + empty.length = 0; + empty.value = NULL; + dummy = ∅ + + if (iph1->approval != NULL && iph1->approval->gssid != NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "using provided service '%.*s'\n", + (int)iph1->approval->gssid->l, iph1->approval->gssid->v); + name_token.length = iph1->approval->gssid->l; + name_token.value = iph1->approval->gssid->v; + maj_stat = gss_import_name(&min_stat, &name_token, + GSS_C_NO_OID, &partner); + if (GSS_ERROR(maj_stat)) { + gssapi_error(min_stat, LOCATION, "import of %.*s\n", + name_token.length, name_token.value); + return -1; + } + } else + if (gssapi_get_default_name(iph1, 1, &partner) < 0) + return -1; + + rtoken = gps->gsscnt_p == 0 ? dummy : &gps->gss_p[gps->gsscnt_p - 1]; + itoken = &gps->gss[gps->gsscnt]; + + gps->gss_status = gss_init_sec_context(&min_stat, gps->gss_cred, + &gps->gss_context, partner, GSS_C_NO_OID, + GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG | + GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG, + 0, GSS_C_NO_CHANNEL_BINDINGS, rtoken, NULL, + itoken, NULL, NULL); + + if (GSS_ERROR(gps->gss_status)) { + gssapi_error(min_stat, LOCATION, "init_sec_context\n"); + maj_stat = gss_release_name(&min_stat, &partner); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release name\n"); + return -1; + } + maj_stat = gss_release_name(&min_stat, &partner); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release name\n"); + + plog(LLV_DEBUG, LOCATION, NULL, "gss_init_sec_context status %x\n", + gps->gss_status); + + if (lenp) + *lenp = itoken->length; + + if (itoken->length != 0) + gps->gsscnt++; + + return 0; +} + +/* + * Call gss_accept_context, with token just read from the wire. + */ +int +gssapi_get_rtoken(struct ph1handle *iph1, int *lenp) +{ + struct gssapi_ph1_state *gps; + gss_buffer_desc name_token; + gss_buffer_t itoken, rtoken; + OM_uint32 min_stat, maj_stat; + gss_name_t client_name; + + if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0) + return -1; + + gps = gssapi_get_state(iph1); + + rtoken = &gps->gss_p[gps->gsscnt_p - 1]; + itoken = &gps->gss[gps->gsscnt]; + + gps->gss_status = gss_accept_sec_context(&min_stat, &gps->gss_context, + gps->gss_cred, rtoken, GSS_C_NO_CHANNEL_BINDINGS, &client_name, + NULL, itoken, NULL, NULL, NULL); + + if (GSS_ERROR(gps->gss_status)) { + gssapi_error(min_stat, LOCATION, "accept_sec_context\n"); + return -1; + } + + maj_stat = gss_display_name(&min_stat, client_name, &name_token, NULL); + if (GSS_ERROR(maj_stat)) { + gssapi_error(min_stat, LOCATION, "gss_display_name\n"); + maj_stat = gss_release_name(&min_stat, &client_name); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, + "release client_name\n"); + return -1; + } + maj_stat = gss_release_name(&min_stat, &client_name); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release client_name\n"); + + plog(LLV_DEBUG, LOCATION, NULL, + "gss_accept_sec_context: other side is %s\n", + (char *)name_token.value); + maj_stat = gss_release_buffer(&min_stat, &name_token); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release name buffer\n"); + + if (itoken->length != 0) + gps->gsscnt++; + + if (lenp) + *lenp = itoken->length; + + return 0; +} + +int +gssapi_save_received_token(struct ph1handle *iph1, vchar_t *token) +{ + struct gssapi_ph1_state *gps; + gss_buffer_t gsstoken; + int ret; + + if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0) + return -1; + + gps = gssapi_get_state(iph1); + + gsstoken = &gps->gss_p[gps->gsscnt_p]; + + ret = gssapi_vm2gssbuf(token, gsstoken); + if (ret < 0) + return ret; + gps->gsscnt_p++; + + return 0; +} + +int +gssapi_get_token_to_send(struct ph1handle *iph1, vchar_t **token) +{ + struct gssapi_ph1_state *gps; + gss_buffer_t gsstoken; + int ret; + + gps = gssapi_get_state(iph1); + if (gps == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "gssapi not yet initialized?\n"); + return -1; + } + gsstoken = &gps->gss[gps->gsscnt - 1]; + ret = gssapi_gss2vmbuf(gsstoken, token); + if (ret < 0) + return ret; + + return 0; +} + +int +gssapi_get_itokens(struct ph1handle *iph1, vchar_t **tokens) +{ + struct gssapi_ph1_state *gps; + int len, i; + vchar_t *toks; + char *p; + + gps = gssapi_get_state(iph1); + if (gps == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "gssapi not yet initialized?\n"); + return -1; + } + + for (i = len = 0; i < gps->gsscnt; i++) + len += gps->gss[i].length; + + toks = vmalloc(len); + if (toks == 0) + return -1; + p = (char *)toks->v; + for (i = 0; i < gps->gsscnt; i++) { + memcpy(p, gps->gss[i].value, gps->gss[i].length); + p += gps->gss[i].length; + } + + *tokens = toks; + + plog(LLV_DEBUG, LOCATION, NULL, + "%d itokens of length %zu\n", gps->gsscnt, (*tokens)->l); + + return 0; +} + +int +gssapi_get_rtokens(struct ph1handle *iph1, vchar_t **tokens) +{ + struct gssapi_ph1_state *gps; + int len, i; + vchar_t *toks; + char *p; + + gps = gssapi_get_state(iph1); + if (gps == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "gssapi not yet initialized?\n"); + return -1; + } + + if (gssapi_more_tokens(iph1)) { + plog(LLV_ERROR, LOCATION, NULL, + "gssapi roundtrips not complete\n"); + return -1; + } + + for (i = len = 0; i < gps->gsscnt_p; i++) + len += gps->gss_p[i].length; + + toks = vmalloc(len); + if (toks == 0) + return -1; + p = (char *)toks->v; + for (i = 0; i < gps->gsscnt_p; i++) { + memcpy(p, gps->gss_p[i].value, gps->gss_p[i].length); + p += gps->gss_p[i].length; + } + + *tokens = toks; + + return 0; +} + +vchar_t * +gssapi_wraphash(struct ph1handle *iph1) +{ + struct gssapi_ph1_state *gps; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc hash_in_buf, hash_out_buf; + gss_buffer_t hash_in = &hash_in_buf, hash_out = &hash_out_buf; + vchar_t *outbuf; + + gps = gssapi_get_state(iph1); + if (gps == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "gssapi not yet initialized?\n"); + return NULL; + } + + if (gssapi_more_tokens(iph1)) { + plog(LLV_ERROR, LOCATION, NULL, + "gssapi roundtrips not complete\n"); + return NULL; + } + + if (gssapi_vm2gssbuf(iph1->hash, hash_in) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "vm2gssbuf failed\n"); + return NULL; + } + + maj_stat = gss_wrap(&min_stat, gps->gss_context, 1, GSS_C_QOP_DEFAULT, + hash_in, NULL, hash_out); + if (GSS_ERROR(maj_stat)) { + gssapi_error(min_stat, LOCATION, "wrapping hash value\n"); + maj_stat = gss_release_buffer(&min_stat, hash_in); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, + "release hash_in buffer\n"); + return NULL; + } + + plog(LLV_DEBUG, LOCATION, NULL, "wrapped HASH, ilen %zu olen %zu\n", + hash_in->length, hash_out->length); + + maj_stat = gss_release_buffer(&min_stat, hash_in); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release hash_in buffer\n"); + + if (gssapi_gss2vmbuf(hash_out, &outbuf) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n"); + maj_stat = gss_release_buffer(&min_stat, hash_out); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, + "release hash_out buffer\n"); + return NULL; + } + maj_stat = gss_release_buffer(&min_stat, hash_out); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release hash_out buffer\n"); + + return outbuf; +} + +vchar_t * +gssapi_unwraphash(struct ph1handle *iph1) +{ + struct gssapi_ph1_state *gps; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc hashbuf, hash_outbuf; + gss_buffer_t hash_in = &hashbuf, hash_out = &hash_outbuf; + vchar_t *outbuf; + + gps = gssapi_get_state(iph1); + if (gps == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "gssapi not yet initialized?\n"); + return NULL; + } + + + hashbuf.length = ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash); + hashbuf.value = (char *)(iph1->pl_hash + 1); + + plog(LLV_DEBUG, LOCATION, NULL, "unwrapping HASH of len %zu\n", + hashbuf.length); + + maj_stat = gss_unwrap(&min_stat, gps->gss_context, hash_in, hash_out, + NULL, NULL); + if (GSS_ERROR(maj_stat)) { + gssapi_error(min_stat, LOCATION, "unwrapping hash value\n"); + return NULL; + } + + if (gssapi_gss2vmbuf(hash_out, &outbuf) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n"); + maj_stat = gss_release_buffer(&min_stat, hash_out); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, + "release hash_out buffer\n"); + return NULL; + } + maj_stat = gss_release_buffer(&min_stat, hash_out); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release hash_out buffer\n"); + + return outbuf; +} + +void +gssapi_set_id_sent(struct ph1handle *iph1) +{ + struct gssapi_ph1_state *gps; + + gps = gssapi_get_state(iph1); + + gps->gss_flags |= GSSFLAG_ID_SENT; +} + +int +gssapi_id_sent(struct ph1handle *iph1) +{ + struct gssapi_ph1_state *gps; + + gps = gssapi_get_state(iph1); + + return (gps->gss_flags & GSSFLAG_ID_SENT) != 0; +} + +void +gssapi_set_id_rcvd(struct ph1handle *iph1) +{ + struct gssapi_ph1_state *gps; + + gps = gssapi_get_state(iph1); + + gps->gss_flags |= GSSFLAG_ID_RCVD; +} + +int +gssapi_id_rcvd(struct ph1handle *iph1) +{ + struct gssapi_ph1_state *gps; + + gps = gssapi_get_state(iph1); + + return (gps->gss_flags & GSSFLAG_ID_RCVD) != 0; +} + +void +gssapi_free_state(struct ph1handle *iph1) +{ + struct gssapi_ph1_state *gps; + OM_uint32 maj_stat, min_stat; + + gps = gssapi_get_state(iph1); + + if (gps == NULL) + return; + + gssapi_set_state(iph1, NULL); + + if (gps->gss_cred != GSS_C_NO_CREDENTIAL) { + maj_stat = gss_release_cred(&min_stat, &gps->gss_cred); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, + "releasing credentials\n"); + } + racoon_free(gps); +} + +vchar_t * +gssapi_get_id(struct ph1handle *iph1) +{ + gss_buffer_desc id_buffer; + gss_buffer_t id = &id_buffer; + gss_name_t defname, canon_name; + OM_uint32 min_stat, maj_stat; + vchar_t *vmbuf; + + if (iph1->rmconf->proposal->gssid != NULL) + return (vdup(iph1->rmconf->proposal->gssid)); + + if (gssapi_get_default_name(iph1, 0, &defname) < 0) + return NULL; + + maj_stat = gss_canonicalize_name(&min_stat, defname, GSS_C_NO_OID, + &canon_name); + if (GSS_ERROR(maj_stat)) { + gssapi_error(min_stat, LOCATION, "canonicalize name\n"); + maj_stat = gss_release_name(&min_stat, &defname); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, + "release default name\n"); + return NULL; + } + maj_stat = gss_release_name(&min_stat, &defname); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release default name\n"); + + maj_stat = gss_export_name(&min_stat, canon_name, id); + if (GSS_ERROR(maj_stat)) { + gssapi_error(min_stat, LOCATION, "export name\n"); + maj_stat = gss_release_name(&min_stat, &canon_name); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, + "release canonical name\n"); + return NULL; + } + maj_stat = gss_release_name(&min_stat, &canon_name); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release canonical name\n"); + +#if 0 + /* + * XXXJRT Did this debug message ever work? This is a GSS name + * blob at this point. + */ + plog(LLV_DEBUG, LOCATION, NULL, "will try to acquire '%.*s' creds\n", + id->length, id->value); +#endif + + if (gssapi_gss2vmbuf(id, &vmbuf) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n"); + maj_stat = gss_release_buffer(&min_stat, id); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release id buffer\n"); + return NULL; + } + maj_stat = gss_release_buffer(&min_stat, id); + if (GSS_ERROR(maj_stat)) + gssapi_error(min_stat, LOCATION, "release id buffer\n"); + + return vmbuf; +} +#else +int __gssapi_dUmMy; +#endif diff --git a/ipsec-tools/src/racoon/gssapi.h b/ipsec-tools/src/racoon/gssapi.h new file mode 100644 index 00000000..25c6c48f --- /dev/null +++ b/ipsec-tools/src/racoon/gssapi.h @@ -0,0 +1,91 @@ +/* $NetBSD: gssapi.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: gssapi.h,v 1.5 2005/02/11 06:59:01 manubsd Exp */ + +/* + * Copyright 2000 Wasabi Systems, Inc. + * All rights reserved. + * + * This software was written by Frank van der Linden of Wasabi Systems + * for Zembu Labs, Inc. http://www.zembu.com/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef __FreeBSD__ +#include "/usr/include/gssapi.h" +#else +#include +#endif + +#define GSSAPI_DEF_NAME "host" + +struct ph1handle; +struct isakmpsa; + +struct gssapi_ph1_state { + int gsscnt; /* # of token we're working on */ + int gsscnt_p; /* # of token we're working on */ + + gss_buffer_desc gss[3]; /* gss-api tokens. */ + /* NOTE: XXX this restricts the max # */ + /* to 3. More should never happen */ + + gss_buffer_desc gss_p[3]; + + gss_ctx_id_t gss_context; /* context for gss_init_sec_context */ + + OM_uint32 gss_status; /* retval from gss_init_sec_context */ + gss_cred_id_t gss_cred; /* acquired credentials */ + + int gss_flags; +#define GSSFLAG_ID_SENT 0x0001 +#define GSSFLAG_ID_RCVD 0x0001 +}; + +#define gssapi_get_state(ph) \ + ((struct gssapi_ph1_state *)((ph)->gssapi_state)) + +#define gssapi_set_state(ph, st) \ + (ph)->gssapi_state = (st) + +#define gssapi_more_tokens(ph) \ + ((gssapi_get_state(ph)->gss_status & GSS_S_CONTINUE_NEEDED) != 0) + +int gssapi_get_itoken __P((struct ph1handle *, int *)); +int gssapi_get_rtoken __P((struct ph1handle *, int *)); +int gssapi_save_received_token __P((struct ph1handle *, vchar_t *)); +int gssapi_get_token_to_send __P((struct ph1handle *, vchar_t **)); +int gssapi_get_itokens __P((struct ph1handle *, vchar_t **)); +int gssapi_get_rtokens __P((struct ph1handle *, vchar_t **)); +vchar_t *gssapi_wraphash __P((struct ph1handle *)); +vchar_t *gssapi_unwraphash __P((struct ph1handle *)); +void gssapi_set_id_sent __P((struct ph1handle *)); +int gssapi_id_sent __P((struct ph1handle *)); +void gssapi_set_id_rcvd __P((struct ph1handle *)); +int gssapi_id_rcvd __P((struct ph1handle *)); +void gssapi_free_state __P((struct ph1handle *)); +vchar_t *gssapi_get_id __P((struct ph1handle *)); +vchar_t *gssapi_get_default_gss_id __P((void)); diff --git a/ipsec-tools/src/racoon/handler.c b/ipsec-tools/src/racoon/handler.c new file mode 100644 index 00000000..9d456b78 --- /dev/null +++ b/ipsec-tools/src/racoon/handler.c @@ -0,0 +1,1583 @@ +/* $NetBSD: handler.c,v 1.39.2.1 2011/11/17 14:46:31 vanhu Exp $ */ + +/* Id: handler.c,v 1.28 2006/05/26 12:17:29 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "debug.h" + +#ifdef ENABLE_HYBRID +#include +#endif + +#include "schedule.h" +#include "grabmyaddr.h" +#include "algorithm.h" +#include "crypto_openssl.h" +#include "policy.h" +#include "proposal.h" +#include "isakmp_var.h" +#include "evt.h" +#include "isakmp.h" +#ifdef ENABLE_HYBRID +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif +#include "isakmp_inf.h" +#include "oakley.h" +#include "remoteconf.h" +#include "localconf.h" +#include "handler.h" +#include "gcmalloc.h" +#include "nattraversal.h" + +#include "sainfo.h" + +#ifdef HAVE_GSSAPI +#include "gssapi.h" +#endif + +static LIST_HEAD(_ph1tree_, ph1handle) ph1tree; +static LIST_HEAD(_ph2tree_, ph2handle) ph2tree; +static LIST_HEAD(_ctdtree_, contacted) ctdtree; +static LIST_HEAD(_rcptree_, recvdpkt) rcptree; +static struct sched sc_sweep = SCHED_INITIALIZER(); + +static void del_recvdpkt __P((struct recvdpkt *)); +static void rem_recvdpkt __P((struct recvdpkt *)); + +/* + * functions about management of the isakmp status table + */ +/* %%% management phase 1 handler */ +/* + * search for isakmpsa handler with isakmp index. + */ + +extern caddr_t val2str(const char *, size_t); + +/* + * Enumerate the Phase 1 tree. + * If enum_func() internally return a non-zero value, this specific + * error value is returned. 0 is returned if everything went right. + * + * Note that it is ok for enum_func() to call insph1(). Those inserted + * Phase 1 will not interfere with current enumeration process. + */ +int +enumph1(sel, enum_func, enum_arg) + struct ph1selector *sel; + int (* enum_func)(struct ph1handle *iph1, void *arg); + void *enum_arg; +{ + struct ph1handle *p; + int ret; + + LIST_FOREACH(p, &ph1tree, chain) { + if (sel != NULL) { + if (sel->local != NULL && + cmpsaddr(sel->local, p->local) > CMPSADDR_WILDPORT_MATCH) + continue; + + if (sel->remote != NULL && + cmpsaddr(sel->remote, p->remote) > CMPSADDR_WILDPORT_MATCH) + continue; + } + + if ((ret = enum_func(p, enum_arg)) != 0) + return ret; + } + + return 0; +} + +struct ph1handle * +getph1byindex(index) + isakmp_index *index; +{ + struct ph1handle *p; + + LIST_FOREACH(p, &ph1tree, chain) { + if (p->status >= PHASE1ST_EXPIRED) + continue; + if (memcmp(&p->index, index, sizeof(*index)) == 0) + return p; + } + + return NULL; +} + + +/* + * search for isakmp handler by i_ck in index. + */ +struct ph1handle * +getph1byindex0(index) + isakmp_index *index; +{ + struct ph1handle *p; + + LIST_FOREACH(p, &ph1tree, chain) { + if (p->status >= PHASE1ST_EXPIRED) + continue; + if (memcmp(&p->index, index, sizeof(cookie_t)) == 0) + return p; + } + + return NULL; +} + +/* + * search for isakmpsa handler by source and remote address. + * don't use port number to search because this function search + * with phase 2's destinaion. + */ +struct ph1handle * +getph1(ph1hint, local, remote, flags) + struct ph1handle *ph1hint; + struct sockaddr *local, *remote; + int flags; +{ + struct ph1handle *p; + + plog(LLV_DEBUG2, LOCATION, NULL, "getph1: start\n"); + plog(LLV_DEBUG2, LOCATION, NULL, "local: %s\n", saddr2str(local)); + plog(LLV_DEBUG2, LOCATION, NULL, "remote: %s\n", saddr2str(remote)); + + LIST_FOREACH(p, &ph1tree, chain) { + if (p->status >= PHASE1ST_DYING) + continue; + + plog(LLV_DEBUG2, LOCATION, NULL, "p->local: %s\n", saddr2str(p->local)); + plog(LLV_DEBUG2, LOCATION, NULL, "p->remote: %s\n", saddr2str(p->remote)); + + if ((flags & GETPH1_F_ESTABLISHED) && + (p->status != PHASE1ST_ESTABLISHED)) { + plog(LLV_DEBUG2, LOCATION, NULL, + "status %d, skipping\n", p->status); + continue; + } + + if (local != NULL && cmpsaddr(local, p->local) == CMPSADDR_MISMATCH) + continue; + + if (remote != NULL && cmpsaddr(remote, p->remote) == CMPSADDR_MISMATCH) + continue; + + if (ph1hint != NULL) { + if (ph1hint->id && ph1hint->id->l && p->id && p->id->l && + (ph1hint->id->l != p->id->l || + memcmp(ph1hint->id->v, p->id->v, p->id->l) != 0)) { + plog(LLV_DEBUG2, LOCATION, NULL, + "local identity does match hint\n"); + continue; + } + if (ph1hint->id_p && ph1hint->id_p->l && + p->id_p && p->id_p->l && + (ph1hint->id_p->l != p->id_p->l || + memcmp(ph1hint->id_p->v, p->id_p->v, p->id_p->l) != 0)) { + plog(LLV_DEBUG2, LOCATION, NULL, + "remote identity does match hint\n"); + continue; + } + } + + plog(LLV_DEBUG2, LOCATION, NULL, "matched\n"); + return p; + } + + plog(LLV_DEBUG2, LOCATION, NULL, "no match\n"); + + return NULL; +} + +int +resolveph1rmconf(iph1) + struct ph1handle *iph1; +{ + struct remoteconf *rmconf; + + /* INITIATOR is always expected to know the exact rmconf. */ + if (iph1->side == INITIATOR) + return 0; + + rmconf = getrmconf_by_ph1(iph1); + if (rmconf == NULL) + return -1; + if (rmconf == RMCONF_ERR_MULTIPLE) + return 1; + + if (iph1->rmconf != NULL) { + if (rmconf != iph1->rmconf) { + plog(LLV_ERROR, LOCATION, NULL, + "unexpected rmconf switch; killing ph1\n"); + return -1; + } + } else { + iph1->rmconf = rmconf; + } + + return 0; +} + + +/* + * move phase2s from old_iph1 to new_iph1 + */ +void +migrate_ph12(old_iph1, new_iph1) + struct ph1handle *old_iph1, *new_iph1; +{ + struct ph2handle *p, *next; + + /* Relocate phase2s to better phase1s or request a new phase1. */ + for (p = LIST_FIRST(&old_iph1->ph2tree); p; p = next) { + next = LIST_NEXT(p, ph1bind); + + if (p->status != PHASE2ST_ESTABLISHED) + continue; + + unbindph12(p); + bindph12(new_iph1, p); + } +} + +/* + * the iph1 is new, migrate all phase2s that belong to a dying or dead ph1 + */ +void migrate_dying_ph12(iph1) + struct ph1handle *iph1; +{ + struct ph1handle *p; + + LIST_FOREACH(p, &ph1tree, chain) { + if (p == iph1) + continue; + if (p->status < PHASE1ST_DYING) + continue; + + if (cmpsaddr(iph1->local, p->local) == CMPSADDR_MATCH + && cmpsaddr(iph1->remote, p->remote) == CMPSADDR_MATCH) + migrate_ph12(p, iph1); + } +} + + +/* + * dump isakmp-sa + */ +vchar_t * +dumpph1() +{ + struct ph1handle *iph1; + struct ph1dump *pd; + int cnt = 0; + vchar_t *buf; + + /* get length of buffer */ + LIST_FOREACH(iph1, &ph1tree, chain) + cnt++; + + buf = vmalloc(cnt * sizeof(struct ph1dump)); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer\n"); + return NULL; + } + pd = (struct ph1dump *)buf->v; + + LIST_FOREACH(iph1, &ph1tree, chain) { + memcpy(&pd->index, &iph1->index, sizeof(iph1->index)); + pd->status = iph1->status; + pd->side = iph1->side; + memcpy(&pd->remote, iph1->remote, sysdep_sa_len(iph1->remote)); + memcpy(&pd->local, iph1->local, sysdep_sa_len(iph1->local)); + pd->version = iph1->version; + pd->etype = iph1->etype; + pd->created = iph1->created; + pd->ph2cnt = iph1->ph2cnt; + pd++; + } + + return buf; +} + +/* + * create new isakmp Phase 1 status record to handle isakmp in Phase1 + */ +struct ph1handle * +newph1() +{ + struct ph1handle *iph1; + + /* create new iph1 */ + iph1 = racoon_calloc(1, sizeof(*iph1)); + if (iph1 == NULL) + return NULL; + + iph1->status = PHASE1ST_SPAWN; + +#ifdef ENABLE_DPD + iph1->dpd_support = 0; + iph1->dpd_seq = 0; + iph1->dpd_fails = 0; +#endif + evt_list_init(&iph1->evt_listeners); + + return iph1; +} + +/* + * delete new isakmp Phase 1 status record to handle isakmp in Phase1 + */ +void +delph1(iph1) + struct ph1handle *iph1; +{ + if (iph1 == NULL) + return; + + /* SA down shell script hook */ + script_hook(iph1, SCRIPT_PHASE1_DOWN); + evt_list_cleanup(&iph1->evt_listeners); + +#ifdef ENABLE_NATT + if (iph1->natt_flags & NAT_KA_QUEUED) + natt_keepalive_remove (iph1->local, iph1->remote); + + if (iph1->natt_options) { + racoon_free(iph1->natt_options); + iph1->natt_options = NULL; + } +#endif + +#ifdef ENABLE_HYBRID + if (iph1->mode_cfg) + isakmp_cfg_rmstate(iph1); +#endif + +#ifdef ENABLE_DPD + sched_cancel(&iph1->dpd_r_u); +#endif + sched_cancel(&iph1->sce); + sched_cancel(&iph1->scr); + + if (iph1->remote) { + racoon_free(iph1->remote); + iph1->remote = NULL; + } + if (iph1->local) { + racoon_free(iph1->local); + iph1->local = NULL; + } + if (iph1->approval) { + delisakmpsa(iph1->approval); + iph1->approval = NULL; + } + + VPTRINIT(iph1->authstr); + VPTRINIT(iph1->sendbuf); + VPTRINIT(iph1->dhpriv); + VPTRINIT(iph1->dhpub); + VPTRINIT(iph1->dhpub_p); + VPTRINIT(iph1->dhgxy); + VPTRINIT(iph1->nonce); + VPTRINIT(iph1->nonce_p); + VPTRINIT(iph1->skeyid); + VPTRINIT(iph1->skeyid_d); + VPTRINIT(iph1->skeyid_a); + VPTRINIT(iph1->skeyid_e); + VPTRINIT(iph1->key); + VPTRINIT(iph1->hash); + VPTRINIT(iph1->sig); + VPTRINIT(iph1->sig_p); + VPTRINIT(iph1->cert); + VPTRINIT(iph1->cert_p); + VPTRINIT(iph1->crl_p); + VPTRINIT(iph1->cr_p); + VPTRINIT(iph1->id); + VPTRINIT(iph1->id_p); + + if(iph1->approval != NULL) + delisakmpsa(iph1->approval); + + if (iph1->ivm) { + oakley_delivm(iph1->ivm); + iph1->ivm = NULL; + } + + VPTRINIT(iph1->sa); + VPTRINIT(iph1->sa_ret); + +#ifdef HAVE_GSSAPI + VPTRINIT(iph1->gi_i); + VPTRINIT(iph1->gi_r); + + gssapi_free_state(iph1); +#endif + + racoon_free(iph1); +} + +/* + * create new isakmp Phase 1 status record to handle isakmp in Phase1 + */ +int +insph1(iph1) + struct ph1handle *iph1; +{ + /* validity check */ + if (iph1->remote == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid isakmp SA handler. no remote address.\n"); + return -1; + } + LIST_INSERT_HEAD(&ph1tree, iph1, chain); + + return 0; +} + +void +remph1(iph1) + struct ph1handle *iph1; +{ + LIST_REMOVE(iph1, chain); +} + +/* + * flush isakmp-sa + */ +void +flushph1() +{ + struct ph1handle *p, *next; + + for (p = LIST_FIRST(&ph1tree); p; p = next) { + next = LIST_NEXT(p, chain); + + /* send delete information */ + if (p->status >= PHASE1ST_ESTABLISHED) + isakmp_info_send_d1(p); + + remph1(p); + delph1(p); + } +} + +void +initph1tree() +{ + LIST_INIT(&ph1tree); +} + +int +ph1_rekey_enabled(iph1) + struct ph1handle *iph1; +{ + if (iph1->rmconf == NULL) + return 0; + if (iph1->rmconf->rekey == REKEY_FORCE) + return 1; +#ifdef ENABLE_DPD + if (iph1->rmconf->rekey == REKEY_ON && iph1->dpd_support && + iph1->rmconf->dpd_interval) + return 1; +#endif + return 0; +} + +/* %%% management phase 2 handler */ + +int +enumph2(sel, enum_func, enum_arg) + struct ph2selector *sel; + int (*enum_func)(struct ph2handle *ph2, void *arg); + void *enum_arg; +{ + struct ph2handle *p; + int ret; + + LIST_FOREACH(p, &ph2tree, chain) { + if (sel != NULL) { + if (sel->spid != 0 && sel->spid != p->spid) + continue; + + if (sel->src != NULL && + cmpsaddr(sel->src, p->src) != CMPSADDR_MATCH) + continue; + + if (sel->dst != NULL && + cmpsaddr(sel->dst, p->dst) != CMPSADDR_MATCH) + continue; + } + + if ((ret = enum_func(p, enum_arg)) != 0) + return ret; + } + + return 0; +} + +/* + * search ph2handle with sequence number. + */ +struct ph2handle * +getph2byseq(seq) + u_int32_t seq; +{ + struct ph2handle *p; + + LIST_FOREACH(p, &ph2tree, chain) { + if (p->seq == seq) + return p; + } + + return NULL; +} + +/* + * search ph2handle with message id. + */ +struct ph2handle * +getph2bymsgid(iph1, msgid) + struct ph1handle *iph1; + u_int32_t msgid; +{ + struct ph2handle *p; + + LIST_FOREACH(p, &iph1->ph2tree, ph1bind) { + if (p->msgid == msgid && p->ph1 == iph1) + return p; + } + + return NULL; +} + +/* Note that src and dst are not the selectors of the SP + * but the source and destination addresses used for + * for SA negotiation (best example is tunnel mode SA + * where src and dst are the endpoints). There is at most + * a unique match because racoon does not support bundles + * which makes that there is at most a single established + * SA for a given spid. One could say that src and dst + * are in fact useless ... + */ +struct ph2handle * +getph2byid(src, dst, spid) + struct sockaddr *src, *dst; + u_int32_t spid; +{ + struct ph2handle *p, *next; + + for (p = LIST_FIRST(&ph2tree); p; p = next) { + next = LIST_NEXT(p, chain); + + if (spid == p->spid && + cmpsaddr(src, p->src) <= CMPSADDR_WILDPORT_MATCH && + cmpsaddr(dst, p->dst) <= CMPSADDR_WILDPORT_MATCH){ + /* Sanity check to detect zombie handlers + * XXX Sould be done "somewhere" more interesting, + * because we have lots of getph2byxxxx(), but this one + * is called by pk_recvacquire(), so is the most important. + */ + if(p->status < PHASE2ST_ESTABLISHED && + p->retry_counter == 0 + && p->sce.func == NULL && p->scr.func == NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "Zombie ph2 found, expiring it\n"); + isakmp_ph2expire(p); + }else + return p; + } + } + + return NULL; +} + +struct ph2handle * +getph2bysaddr(src, dst) + struct sockaddr *src, *dst; +{ + struct ph2handle *p; + + LIST_FOREACH(p, &ph2tree, chain) { + if (cmpsaddr(src, p->src) <= CMPSADDR_WILDPORT_MATCH && + cmpsaddr(dst, p->dst) <= CMPSADDR_WILDPORT_MATCH) + return p; + } + + return NULL; +} + +/* + * call by pk_recvexpire(). + */ +struct ph2handle * +getph2bysaidx(src, dst, proto_id, spi) + struct sockaddr *src, *dst; + u_int proto_id; + u_int32_t spi; +{ + struct ph2handle *iph2; + struct saproto *pr; + + LIST_FOREACH(iph2, &ph2tree, chain) { + if (iph2->proposal == NULL && iph2->approval == NULL) + continue; + if (iph2->approval != NULL) { + for (pr = iph2->approval->head; pr != NULL; + pr = pr->next) { + if (proto_id != pr->proto_id) + break; + if (spi == pr->spi || spi == pr->spi_p) + return iph2; + } + } else if (iph2->proposal != NULL) { + for (pr = iph2->proposal->head; pr != NULL; + pr = pr->next) { + if (proto_id != pr->proto_id) + break; + if (spi == pr->spi) + return iph2; + } + } + } + + return NULL; +} + +/* + * create new isakmp Phase 2 status record to handle isakmp in Phase2 + */ +struct ph2handle * +newph2() +{ + struct ph2handle *iph2 = NULL; + + /* create new iph2 */ + iph2 = racoon_calloc(1, sizeof(*iph2)); + if (iph2 == NULL) + return NULL; + + iph2->status = PHASE1ST_SPAWN; + evt_list_init(&iph2->evt_listeners); + + return iph2; +} + +/* + * initialize ph2handle + * NOTE: don't initialize src/dst. + * SPI in the proposal is cleared. + */ +void +initph2(iph2) + struct ph2handle *iph2; +{ + evt_list_cleanup(&iph2->evt_listeners); + unbindph12(iph2); + + sched_cancel(&iph2->sce); + sched_cancel(&iph2->scr); + + VPTRINIT(iph2->sendbuf); + VPTRINIT(iph2->msg1); + + /* clear spi, keep variables in the proposal */ + if (iph2->proposal) { + struct saproto *pr; + for (pr = iph2->proposal->head; pr != NULL; pr = pr->next) + pr->spi = 0; + } + + /* clear approval */ + if (iph2->approval) { + flushsaprop(iph2->approval); + iph2->approval = NULL; + } + + /* clear the generated policy */ + if (iph2->spidx_gen) { + delsp_bothdir((struct policyindex *)iph2->spidx_gen); + racoon_free(iph2->spidx_gen); + iph2->spidx_gen = NULL; + } + + if (iph2->pfsgrp) { + oakley_dhgrp_free(iph2->pfsgrp); + iph2->pfsgrp = NULL; + } + + VPTRINIT(iph2->dhpriv); + VPTRINIT(iph2->dhpub); + VPTRINIT(iph2->dhpub_p); + VPTRINIT(iph2->dhgxy); + VPTRINIT(iph2->id); + VPTRINIT(iph2->id_p); + VPTRINIT(iph2->nonce); + VPTRINIT(iph2->nonce_p); + VPTRINIT(iph2->sa); + VPTRINIT(iph2->sa_ret); + + if (iph2->ivm) { + oakley_delivm(iph2->ivm); + iph2->ivm = NULL; + } + +#ifdef ENABLE_NATT + if (iph2->natoa_src) { + racoon_free(iph2->natoa_src); + iph2->natoa_src = NULL; + } + if (iph2->natoa_dst) { + racoon_free(iph2->natoa_dst); + iph2->natoa_dst = NULL; + } +#endif +} + +/* + * delete new isakmp Phase 2 status record to handle isakmp in Phase2 + */ +void +delph2(iph2) + struct ph2handle *iph2; +{ + initph2(iph2); + + if (iph2->src) { + racoon_free(iph2->src); + iph2->src = NULL; + } + if (iph2->dst) { + racoon_free(iph2->dst); + iph2->dst = NULL; + } + if (iph2->sa_src) { + racoon_free(iph2->sa_src); + iph2->sa_src = NULL; + } + if (iph2->sa_dst) { + racoon_free(iph2->sa_dst); + iph2->sa_dst = NULL; + } +#ifdef ENABLE_NATT + if (iph2->natoa_src) { + racoon_free(iph2->natoa_src); + iph2->natoa_src = NULL; + } + if (iph2->natoa_dst) { + racoon_free(iph2->natoa_dst); + iph2->natoa_dst = NULL; + } +#endif + + if (iph2->proposal) { + flushsaprop(iph2->proposal); + iph2->proposal = NULL; + } + + racoon_free(iph2); +} + +/* + * create new isakmp Phase 2 status record to handle isakmp in Phase2 + */ +int +insph2(iph2) + struct ph2handle *iph2; +{ + LIST_INSERT_HEAD(&ph2tree, iph2, chain); + + return 0; +} + +void +remph2(iph2) + struct ph2handle *iph2; +{ + unbindph12(iph2); + LIST_REMOVE(iph2, chain); +} + +void +initph2tree() +{ + LIST_INIT(&ph2tree); +} + +void +flushph2() +{ + struct ph2handle *p, *next; + + plog(LLV_DEBUG2, LOCATION, NULL, + "flushing all ph2 handlers...\n"); + + for (p = LIST_FIRST(&ph2tree); p; p = next) { + next = LIST_NEXT(p, chain); + + /* send delete information */ + if (p->status == PHASE2ST_ESTABLISHED){ + plog(LLV_DEBUG2, LOCATION, NULL, + "got a ph2 handler to flush...\n"); + isakmp_info_send_d2(p); + }else{ + plog(LLV_DEBUG2, LOCATION, NULL, + "skipping ph2 handler (state %d)\n", p->status); + } + + delete_spd(p, 0); + remph2(p); + delph2(p); + } +} + +/* + * Delete all Phase 2 handlers for this src/dst/proto. This + * is used during INITIAL-CONTACT processing (so no need to + * send a message to the peer). + */ +void +deleteallph2(src, dst, proto_id) + struct sockaddr *src, *dst; + u_int proto_id; +{ + struct ph2handle *iph2, *next; + struct saproto *pr; + + for (iph2 = LIST_FIRST(&ph2tree); iph2 != NULL; iph2 = next) { + next = LIST_NEXT(iph2, chain); + if (iph2->proposal == NULL && iph2->approval == NULL) + continue; + if (iph2->approval != NULL) { + for (pr = iph2->approval->head; pr != NULL; + pr = pr->next) { + if (proto_id == pr->proto_id) + goto zap_it; + } + } else if (iph2->proposal != NULL) { + for (pr = iph2->proposal->head; pr != NULL; + pr = pr->next) { + if (proto_id == pr->proto_id) + goto zap_it; + } + } + continue; + zap_it: + remph2(iph2); + delph2(iph2); + } +} + +/* %%% */ +void +bindph12(iph1, iph2) + struct ph1handle *iph1; + struct ph2handle *iph2; +{ + unbindph12(iph2); + + iph2->ph1 = iph1; + iph1->ph2cnt++; + LIST_INSERT_HEAD(&iph1->ph2tree, iph2, ph1bind); +} + +void +unbindph12(iph2) + struct ph2handle *iph2; +{ + if (iph2->ph1 != NULL) { + LIST_REMOVE(iph2, ph1bind); + iph2->ph1->ph2cnt--; + iph2->ph1 = NULL; + } +} + +/* %%% management contacted list */ +/* + * search contacted list. + */ +struct contacted * +getcontacted(remote) + struct sockaddr *remote; +{ + struct contacted *p; + + LIST_FOREACH(p, &ctdtree, chain) { + if (cmpsaddr(remote, p->remote) <= CMPSADDR_WILDPORT_MATCH) + return p; + } + + return NULL; +} + +/* + * create new isakmp Phase 2 status record to handle isakmp in Phase2 + */ +int +inscontacted(remote) + struct sockaddr *remote; +{ + struct contacted *new; + + /* create new iph2 */ + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) + return -1; + + new->remote = dupsaddr(remote); + if (new->remote == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer.\n"); + racoon_free(new); + return -1; + } + + LIST_INSERT_HEAD(&ctdtree, new, chain); + + return 0; +} + +void +remcontacted(remote) + struct sockaddr *remote; +{ + struct contacted *p, *next; + + for (p = LIST_FIRST(&ctdtree); p; p = next) { + next = LIST_NEXT(p, chain); + + if (cmpsaddr(remote, p->remote) <= CMPSADDR_WILDPORT_MATCH) { + LIST_REMOVE(p, chain); + racoon_free(p->remote); + racoon_free(p); + break; + } + } +} + +void +initctdtree() +{ + LIST_INIT(&ctdtree); +} + +/* + * check the response has been sent to the peer. when not, simply reply + * the buffered packet to the peer. + * OUT: + * 0: the packet is received at the first time. + * 1: the packet was processed before. + * 2: the packet was processed before, but the address mismatches. + * -1: error happened. + */ +int +check_recvdpkt(remote, local, rbuf) + struct sockaddr *remote, *local; + vchar_t *rbuf; +{ + vchar_t *hash; + struct recvdpkt *r; + struct timeval now, diff; + int len, s; + + hash = eay_md5_one(rbuf); + if (!hash) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer.\n"); + return -1; + } + + LIST_FOREACH(r, &rcptree, chain) { + if (memcmp(hash->v, r->hash->v, r->hash->l) == 0) + break; + } + vfree(hash); + + /* this is the first time to receive the packet */ + if (r == NULL) + return 0; + + /* + * the packet was processed before, but the remote address mismatches. + */ + if (cmpsaddr(remote, r->remote) != CMPSADDR_MATCH) + return 2; + + /* + * it should not check the local address because the packet + * may arrive at other interface. + */ + + /* check the previous time to send */ + sched_get_monotonic_time(&now); + timersub(&now, &r->time_send, &diff); + if (diff.tv_sec == 0) { + plog(LLV_WARNING, LOCATION, NULL, + "the packet retransmitted in a short time from %s\n", + saddr2str(remote)); + /*XXX should it be error ? */ + } + + /* select the socket to be sent */ + s = myaddr_getfd(r->local); + if (s == -1) + return -1; + + /* resend the packet if needed */ + len = sendfromto(s, r->sendbuf->v, r->sendbuf->l, + r->local, r->remote, lcconf->count_persend); + if (len == -1) { + plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n"); + return -1; + } + + /* check the retry counter */ + r->retry_counter--; + if (r->retry_counter <= 0) { + rem_recvdpkt(r); + del_recvdpkt(r); + plog(LLV_DEBUG, LOCATION, NULL, + "deleted the retransmission packet to %s.\n", + saddr2str(remote)); + } else + r->time_send = now; + + return 1; +} + +/* + * adding a hash of received packet into the received list. + */ +int +add_recvdpkt(remote, local, sbuf, rbuf) + struct sockaddr *remote, *local; + vchar_t *sbuf, *rbuf; +{ + struct recvdpkt *new = NULL; + + if (lcconf->retry_counter == 0) { + /* no need to add it */ + return 0; + } + + new = racoon_calloc(1, sizeof(*new)); + if (!new) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer.\n"); + return -1; + } + + new->hash = eay_md5_one(rbuf); + if (!new->hash) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer.\n"); + del_recvdpkt(new); + return -1; + } + new->remote = dupsaddr(remote); + if (new->remote == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer.\n"); + del_recvdpkt(new); + return -1; + } + new->local = dupsaddr(local); + if (new->local == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer.\n"); + del_recvdpkt(new); + return -1; + } + new->sendbuf = vdup(sbuf); + if (new->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer.\n"); + del_recvdpkt(new); + return -1; + } + + new->retry_counter = lcconf->retry_counter; + sched_get_monotonic_time(&new->time_send); + + LIST_INSERT_HEAD(&rcptree, new, chain); + + return 0; +} + +void +del_recvdpkt(r) + struct recvdpkt *r; +{ + if (r->remote) + racoon_free(r->remote); + if (r->local) + racoon_free(r->local); + if (r->hash) + vfree(r->hash); + if (r->sendbuf) + vfree(r->sendbuf); + racoon_free(r); +} + +void +rem_recvdpkt(r) + struct recvdpkt *r; +{ + LIST_REMOVE(r, chain); +} + +static void +sweep_recvdpkt(dummy) + struct sched *dummy; +{ + struct recvdpkt *r, *next; + struct timeval now, diff, sweep; + + sched_get_monotonic_time(&now); + + /* calculate sweep time; delete entries older than this */ + diff.tv_sec = lcconf->retry_counter * lcconf->retry_interval; + diff.tv_usec = 0; + timersub(&now, &diff, &sweep); + + for (r = LIST_FIRST(&rcptree); r; r = next) { + next = LIST_NEXT(r, chain); + + if (timercmp(&r->time_send, &sweep, <)) { + rem_recvdpkt(r); + del_recvdpkt(r); + } + } + + sched_schedule(&sc_sweep, diff.tv_sec, sweep_recvdpkt); +} + +void +init_recvdpkt() +{ + time_t lt = lcconf->retry_counter * lcconf->retry_interval; + + LIST_INIT(&rcptree); + + sched_schedule(&sc_sweep, lt, sweep_recvdpkt); +} + +#ifdef ENABLE_HYBRID +/* + * Retruns 0 if the address was obtained by ISAKMP mode config, 1 otherwise + * This should be in isakmp_cfg.c but ph1tree being private, it must be there + */ +int +exclude_cfg_addr(addr) + const struct sockaddr *addr; +{ + struct ph1handle *p; + struct sockaddr_in *sin; + + LIST_FOREACH(p, &ph1tree, chain) { + if ((p->mode_cfg != NULL) && + (p->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) && + (addr->sa_family == AF_INET)) { + sin = (struct sockaddr_in *)addr; + if (sin->sin_addr.s_addr == p->mode_cfg->addr4.s_addr) + return 0; + } + } + + return 1; +} +#endif + + + +/* + * Reload conf code + */ +static int revalidate_ph2(struct ph2handle *iph2){ + struct sainfoalg *alg; + int found, check_level; + struct sainfo *sainfo; + struct saprop *approval; + struct ph1handle *iph1; + + /* + * Get the new sainfo using values of the old one + */ + if (iph2->sainfo != NULL) { + iph2->sainfo = getsainfo(iph2->sainfo->idsrc, + iph2->sainfo->iddst, iph2->sainfo->id_i, + NULL, iph2->sainfo->remoteid); + } + approval = iph2->approval; + sainfo = iph2->sainfo; + + if (sainfo == NULL) { + /* + * Sainfo has been removed + */ + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: No sainfo for ph2\n"); + return 0; + } + + if (approval == NULL) { + /* + * XXX why do we have a NULL approval sometimes ??? + */ + plog(LLV_DEBUG, LOCATION, NULL, + "No approval found !\n"); + return 0; + } + + /* + * Don't care about proposals, should we do something ? + * We have to keep iph2->proposal valid at least for initiator, + * for pk_sendgetspi() + */ + + plog(LLV_DEBUG, LOCATION, NULL, "active single bundle:\n"); + printsaprop0(LLV_DEBUG, approval); + + /* + * Validate approval against sainfo + * Note: we must have an updated ph1->rmconf before doing that, + * we'll set check_level to EXACT if we don't have a ph1 + * XXX try tu find the new remote section to get the new check level ? + * XXX lifebyte + */ + if (iph2->ph1 != NULL) + iph1=iph2->ph1; + else + iph1=getph1byaddr(iph2->src, iph2->dst, 0); + + if(iph1 != NULL && iph1->rmconf != NULL) { + check_level = iph1->rmconf->pcheck_level; + } else { + if(iph1 != NULL) + plog(LLV_DEBUG, LOCATION, NULL, "No phase1 rmconf found !\n"); + else + plog(LLV_DEBUG, LOCATION, NULL, "No phase1 found !\n"); + check_level = PROP_CHECK_EXACT; + } + + switch (check_level) { + case PROP_CHECK_OBEY: + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: OBEY for ph2, ok\n"); + return 1; + break; + + case PROP_CHECK_STRICT: + /* FALLTHROUGH */ + case PROP_CHECK_CLAIM: + if (sainfo->lifetime < approval->lifetime) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: lifetime mismatch\n"); + return 0; + } + +#if 0 + /* Lifebyte is deprecated, just ignore it + */ + if (sainfo->lifebyte < approval->lifebyte) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: lifebyte mismatch\n"); + return 0; + } +#endif + + if (sainfo->pfs_group && + sainfo->pfs_group != approval->pfs_group) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: PFS group mismatch\n"); + return 0; + } + break; + + case PROP_CHECK_EXACT: + if (sainfo->lifetime != approval->lifetime || +#if 0 + /* Lifebyte is deprecated, just ignore it + */ + sainfo->lifebyte != approval->lifebyte || +#endif + sainfo->pfs_group != iph2->approval->pfs_group) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: lifetime | pfs mismatch\n"); + return 0; + } + break; + + default: + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: Shouldn't be here !\n"); + return 0; + break; + } + + for (alg = sainfo->algs[algclass_ipsec_auth]; alg; alg = alg->next) { + if (alg->alg == approval->head->head->authtype) + break; + } + if (alg == NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: alg == NULL (auth)\n"); + return 0; + } + + found = 0; + for (alg = sainfo->algs[algclass_ipsec_enc]; + (found == 0 && alg != NULL); alg = alg->next) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: next ph2 enc alg...\n"); + + if (alg->alg != approval->head->head->trns_id){ + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: encmode mismatch (%d / %d)\n", + alg->alg, approval->head->head->trns_id); + continue; + } + + switch (check_level){ + /* PROP_CHECK_STRICT cannot happen here */ + case PROP_CHECK_EXACT: + if (alg->encklen != approval->head->head->encklen) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: enclen mismatch\n"); + continue; + } + break; + + case PROP_CHECK_CLAIM: + /* FALLTHROUGH */ + case PROP_CHECK_STRICT: + if (alg->encklen > approval->head->head->encklen) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: enclen mismatch\n"); + continue; + } + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "unexpected check_level\n"); + continue; + break; + } + found = 1; + } + + if (!found){ + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: No valid enc\n"); + return 0; + } + + /* + * XXX comp + */ + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: ph2 check ok\n"); + + return 1; +} + + +static void +remove_ph2(struct ph2handle *iph2) +{ + u_int32_t spis[2]; + + if(iph2 == NULL) + return; + + plog(LLV_DEBUG, LOCATION, NULL, + "Deleting a Ph2...\n"); + + if (iph2->status == PHASE2ST_ESTABLISHED) + isakmp_info_send_d2(iph2); + + if(iph2->approval != NULL && iph2->approval->head != NULL){ + spis[0]=iph2->approval->head->spi; + spis[1]=iph2->approval->head->spi_p; + + /* purge_ipsec_spi() will do all the work: + * - delete SPIs in kernel + * - delete generated SPD + * - unbind / rem / del ph2 + */ + purge_ipsec_spi(iph2->dst, iph2->approval->head->proto_id, + spis, 2); + }else{ + remph2(iph2); + delph2(iph2); + } +} + +static void remove_ph1(struct ph1handle *iph1){ + struct ph2handle *iph2, *iph2_next; + + if(iph1 == NULL) + return; + + plog(LLV_DEBUG, LOCATION, NULL, + "Removing PH1...\n"); + + if (iph1->status == PHASE1ST_ESTABLISHED || + iph1->status == PHASE1ST_DYING) { + for (iph2 = LIST_FIRST(&iph1->ph2tree); iph2; iph2 = iph2_next) { + iph2_next = LIST_NEXT(iph2, ph1bind); + remove_ph2(iph2); + } + isakmp_info_send_d1(iph1); + } + iph1->status = PHASE1ST_EXPIRED; + /* directly call isakmp_ph1delete to avoid as possible a race + * condition where we'll try to access iph1->rmconf after it has + * freed + */ + isakmp_ph1delete(iph1); +} + + +static int revalidate_ph1tree_rmconf(void) +{ + struct ph1handle *p, *next; + struct remoteconf *rmconf; + + for (p = LIST_FIRST(&ph1tree); p; p = next) { + next = LIST_NEXT(p, chain); + + if (p->status >= PHASE1ST_EXPIRED) + continue; + if (p->rmconf == NULL) + continue; + + rmconf = getrmconf_by_ph1(p); + if (rmconf == NULL || rmconf == RMCONF_ERR_MULTIPLE) + remove_ph1(p); + else + p->rmconf = rmconf; + } + + return 1; +} + +static int revalidate_ph2tree(void){ + struct ph2handle *p, *next; + + for (p = LIST_FIRST(&ph2tree); p; p = next) { + next = LIST_NEXT(p, chain); + + if (p->status == PHASE2ST_EXPIRED) + continue; + + if(!revalidate_ph2(p)){ + plog(LLV_DEBUG, LOCATION, NULL, + "PH2 not validated, removing it\n"); + remove_ph2(p); + } + } + + return 1; +} + +int +revalidate_ph12(void) +{ + + revalidate_ph1tree_rmconf(); + revalidate_ph2tree(); + + return 1; +} + +#ifdef ENABLE_HYBRID +struct ph1handle * +getph1bylogin(login) + char *login; +{ + struct ph1handle *p; + + LIST_FOREACH(p, &ph1tree, chain) { + if (p->mode_cfg == NULL) + continue; + if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0) + return p; + } + + return NULL; +} + +int +purgeph1bylogin(login) + char *login; +{ + struct ph1handle *p, *next; + int found = 0; + + for (p = LIST_FIRST(&ph1tree); p; p = next) { + next = LIST_NEXT(p, chain); + + if (p->mode_cfg == NULL) + continue; + if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0) { + if (p->status >= PHASE1ST_EXPIRED) + continue; + + if (p->status >= PHASE1ST_ESTABLISHED) + isakmp_info_send_d1(p); + purge_remote(p); + found++; + } + } + + return found; +} +#endif diff --git a/ipsec-tools/src/racoon/handler.h b/ipsec-tools/src/racoon/handler.h new file mode 100644 index 00000000..45d596e2 --- /dev/null +++ b/ipsec-tools/src/racoon/handler.h @@ -0,0 +1,538 @@ +/* $NetBSD: handler.h,v 1.25 2010/11/17 10:40:41 tteras Exp $ */ + +/* Id: handler.h,v 1.19 2006/02/25 08:25:12 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _HANDLER_H +#define _HANDLER_H + +#include +#include + +#include + +#include "isakmp_var.h" +#include "oakley.h" +#include "schedule.h" +#include "evt.h" + +/* Phase 1 handler */ +/* + * main mode: + * initiator responder + * 0 (---) (---) + * 1 start start (1st msg received) + * 2 (---) 1st valid msg received + * 3 1st msg sent 1st msg sent + * 4 1st valid msg received 2st valid msg received + * 5 2nd msg sent 2nd msg sent + * 6 2nd valid msg received 3rd valid msg received + * 7 3rd msg sent 3rd msg sent + * 8 3rd valid msg received (---) + * 9 SA established SA established + * + * aggressive mode: + * initiator responder + * 0 (---) (---) + * 1 start start (1st msg received) + * 2 (---) 1st valid msg received + * 3 1st msg sent 1st msg sent + * 4 1st valid msg received 2st valid msg received + * 5 (---) (---) + * 6 (---) (---) + * 7 (---) (---) + * 8 (---) (---) + * 9 SA established SA established + * + * base mode: + * initiator responder + * 0 (---) (---) + * 1 start start (1st msg received) + * 2 (---) 1st valid msg received + * 3 1st msg sent 1st msg sent + * 4 1st valid msg received 2st valid msg received + * 5 2nd msg sent (---) + * 6 (---) (---) + * 7 (---) (---) + * 8 (---) (---) + * 9 SA established SA established + */ +#define PHASE1ST_SPAWN 0 +#define PHASE1ST_START 1 +#define PHASE1ST_MSG1RECEIVED 2 +#define PHASE1ST_MSG1SENT 3 +#define PHASE1ST_MSG2RECEIVED 4 +#define PHASE1ST_MSG2SENT 5 +#define PHASE1ST_MSG3RECEIVED 6 +#define PHASE1ST_MSG3SENT 7 +#define PHASE1ST_MSG4RECEIVED 8 +#define PHASE1ST_ESTABLISHED 9 +#define PHASE1ST_DYING 10 +#define PHASE1ST_EXPIRED 11 +#define PHASE1ST_MAX 12 + +/* About address semantics in each case. + * initiator(addr=I) responder(addr=R) + * src dst src dst + * (local) (remote) (local) (remote) + * phase 1 handler I R R I + * phase 2 handler I R R I + * getspi msg R I I R + * acquire msg I R + * ID payload I R I R + */ +#ifdef ENABLE_HYBRID +struct isakmp_cfg_state; +#endif +struct ph1handle { + isakmp_index index; + + int status; /* status of this SA */ + int side; /* INITIATOR or RESPONDER */ + + struct sockaddr *remote; /* remote address to negosiate ph1 */ + struct sockaddr *local; /* local address to negosiate ph1 */ + /* XXX copy from rmconf due to anonymous configuration. + * If anonymous will be forbidden, we do delete them. */ + + struct remoteconf *rmconf; /* pointer to remote configuration */ + + struct isakmpsa *approval; /* pointer to SA(s) approved. */ + vchar_t *authstr; /* place holder of string for auth. */ + /* for example pre-shared key */ + + u_int8_t version; /* ISAKMP version */ + u_int8_t etype; /* Exchange type actually for use */ + u_int8_t flags; /* Flags */ + u_int32_t msgid; /* message id */ + + u_int32_t vendorid_mask; /* bitmask of received supported vendor ids*/ +#ifdef ENABLE_NATT + struct ph1natt_options *natt_options; /* Selected NAT-T IKE version */ + u_int32_t natt_flags; /* NAT-T related flags */ +#endif +#ifdef ENABLE_FRAG + int frag; /* IKE phase 1 fragmentation */ + struct isakmp_frag_item *frag_chain; /* Received fragments */ +#endif + + struct sched sce; /* schedule for expire */ + + struct sched scr; /* schedule for resend */ + int retry_counter; /* for resend. */ + vchar_t *sendbuf; /* buffer for re-sending */ + + vchar_t *dhpriv; /* DH; private value */ + vchar_t *dhpub; /* DH; public value */ + vchar_t *dhpub_p; /* DH; partner's public value */ + vchar_t *dhgxy; /* DH; shared secret */ + vchar_t *nonce; /* nonce value */ + vchar_t *nonce_p; /* partner's nonce value */ + vchar_t *skeyid; /* SKEYID */ + vchar_t *skeyid_d; /* SKEYID_d */ + vchar_t *skeyid_a; /* SKEYID_a, i.e. hash */ + vchar_t *skeyid_e; /* SKEYID_e, i.e. encryption */ + vchar_t *key; /* cipher key */ + vchar_t *hash; /* HASH minus general header */ + vchar_t *sig; /* SIG minus general header */ + vchar_t *sig_p; /* peer's SIG minus general header */ + vchar_t *cert; /* CERT minus general header */ + vchar_t *cert_p; /* peer's CERT minus general header */ + vchar_t *crl_p; /* peer's CRL minus general header */ + vchar_t *cr_p; /* peer's CR not including general */ + RSA *rsa; /* my RSA key */ + RSA *rsa_p; /* peer's RSA key */ + struct genlist *rsa_candidates; /* possible candidates for peer's RSA key */ + vchar_t *id; /* ID minus gen header */ + vchar_t *id_p; /* partner's ID minus general header */ + /* i.e. struct ipsecdoi_id_b*. */ + struct isakmp_ivm *ivm; /* IVs */ + + vchar_t *sa; /* whole SA payload to send/to be sent*/ + /* to calculate HASH */ + /* NOT INCLUDING general header. */ + + vchar_t *sa_ret; /* SA payload to reply/to be replyed */ + /* NOT INCLUDING general header. */ + /* NOTE: Should be release after use. */ + +#ifdef HAVE_GSSAPI + void *gssapi_state; /* GSS-API specific state. */ + /* Allocated when needed */ + vchar_t *gi_i; /* optional initiator GSS id */ + vchar_t *gi_r; /* optional responder GSS id */ +#endif + + struct isakmp_pl_hash *pl_hash; /* pointer to hash payload */ + + time_t created; /* timestamp for establish */ + int initial_contact_received; /* set if initial contact received */ +#ifdef ENABLE_STATS + struct timeval start; + struct timeval end; +#endif + +#ifdef ENABLE_DPD + int dpd_support; /* Does remote supports DPD ? */ + u_int32_t dpd_last_ack; + u_int32_t dpd_seq; /* DPD seq number to receive */ + u_int8_t dpd_fails; /* number of failures */ + struct sched dpd_r_u; +#endif + + u_int32_t msgid2; /* msgid counter for Phase 2 */ + int ph2cnt; /* the number which is negotiated by this phase 1 */ + LIST_HEAD(_ph2ofph1_, ph2handle) ph2tree; + + LIST_ENTRY(ph1handle) chain; +#ifdef ENABLE_HYBRID + struct isakmp_cfg_state *mode_cfg; /* ISAKMP mode config state */ +#endif + EVT_LISTENER_LIST(evt_listeners); +}; + +/* For limiting enumeration of ph1 tree */ +struct ph1selector { + struct sockaddr *local; + struct sockaddr *remote; +}; + +/* Phase 2 handler */ +/* allocated per a SA or SA bundles of a pair of peer's IP addresses. */ +/* + * initiator responder + * 0 (---) (---) + * 1 start start (1st msg received) + * 2 acquire msg get 1st valid msg received + * 3 getspi request sent getspi request sent + * 4 getspi done getspi done + * 5 1st msg sent 1st msg sent + * 6 1st valid msg received 2nd valid msg received + * 7 (commit bit) (commit bit) + * 8 SAs added SAs added + * 9 SAs established SAs established + * 10 SAs expired SAs expired + */ +#define PHASE2ST_SPAWN 0 +#define PHASE2ST_START 1 +#define PHASE2ST_STATUS2 2 +#define PHASE2ST_GETSPISENT 3 +#define PHASE2ST_GETSPIDONE 4 +#define PHASE2ST_MSG1SENT 5 +#define PHASE2ST_STATUS6 6 +#define PHASE2ST_COMMIT 7 +#define PHASE2ST_ADDSA 8 +#define PHASE2ST_ESTABLISHED 9 +#define PHASE2ST_EXPIRED 10 +#define PHASE2ST_MAX 11 + +struct ph2handle { + /* source and destination addresses used for IKE exchange. Might + * differ from source and destination of SA. On the initiator, + * they are tweaked if a hint is available in the SPD (set by + * MIGRATE for instance). Otherwise they are the source and + * destination of SA for transport mode and the tunnel endpoints + * for tunnel mode */ + struct sockaddr *src; + struct sockaddr *dst; + + /* source and destination addresses of the SA in the case addresses + * used for IKE exchanges (src and dst) do differ. On the initiator, + * they are set (if needed) in pk_recvacquire(). On the responder, + * they are _derived_ from the local and remote parameters of the + * SP, if available. */ + struct sockaddr *sa_src; + struct sockaddr *sa_dst; + + /* Store our Phase 2 ID and the peer ID (ID minus general header). + * On the initiator, they are set during ACQUIRE processing. + * On the responder, they are set from the content of ID payload + * in quick_r1recv(). Then, if they are of type address or + * tunnel, they are compared to sainfo selectors. + */ + vchar_t *id; /* ID minus gen header */ + vchar_t *id_p; /* peer's ID minus general header */ + +#ifdef ENABLE_NATT + struct sockaddr *natoa_src; /* peer's view of my address */ + struct sockaddr *natoa_dst; /* peer's view of his address */ +#endif + + u_int32_t spid; /* policy id by kernel */ + + int status; /* ipsec sa status */ + u_int8_t side; /* INITIATOR or RESPONDER */ + + struct sched sce; /* schedule for expire */ + struct sched scr; /* schedule for resend */ + int retry_counter; /* for resend. */ + vchar_t *sendbuf; /* buffer for re-sending */ + vchar_t *msg1; /* buffer for re-sending */ + /* used for responder's first message */ + + int retry_checkph1; /* counter to wait phase 1 finished. */ + /* NOTE: actually it's timer. */ + + u_int32_t seq; /* sequence number used by PF_KEY */ + /* + * NOTE: In responder side, we can't identify each SAs + * with same destination address for example, when + * socket based SA is required. So we set a identifier + * number to "seq", and sent kernel by pfkey. + */ + u_int8_t satype; /* satype in PF_KEY */ + /* + * saved satype in the original PF_KEY request from + * the kernel in order to reply a error. + */ + + u_int8_t flags; /* Flags for phase 2 */ + u_int32_t msgid; /* msgid for phase 2 */ + + struct sainfo *sainfo; /* place holder of sainfo */ + struct saprop *proposal; /* SA(s) proposal. */ + struct saprop *approval; /* SA(s) approved. */ + u_int32_t lifetime_secs; /* responder lifetime (seconds) */ + u_int32_t lifetime_kb; /* responder lifetime (kbytes) */ + caddr_t spidx_gen; /* policy from peer's proposal */ + + struct dhgroup *pfsgrp; /* DH; prime number */ + vchar_t *dhpriv; /* DH; private value */ + vchar_t *dhpub; /* DH; public value */ + vchar_t *dhpub_p; /* DH; partner's public value */ + vchar_t *dhgxy; /* DH; shared secret */ + vchar_t *nonce; /* nonce value in phase 2 */ + vchar_t *nonce_p; /* partner's nonce value in phase 2 */ + + vchar_t *sa; /* whole SA payload to send/to be sent*/ + /* to calculate HASH */ + /* NOT INCLUDING general header. */ + + vchar_t *sa_ret; /* SA payload to reply/to be replyed */ + /* NOT INCLUDING general header. */ + /* NOTE: Should be release after use. */ + + struct isakmp_ivm *ivm; /* IVs */ + + int generated_spidx; /* mark handlers whith generated policy */ + +#ifdef ENABLE_STATS + struct timeval start; + struct timeval end; +#endif + struct ph1handle *ph1; /* back pointer to isakmp status */ + + LIST_ENTRY(ph2handle) chain; + LIST_ENTRY(ph2handle) ph1bind; /* chain to ph1handle */ + EVT_LISTENER_LIST(evt_listeners); +}; + +/* For limiting enumeration of ph2 tree */ +struct ph2selector { + u_int32_t spid; + struct sockaddr *src; + struct sockaddr *dst; +}; + +/* + * for handling initial contact. + */ +struct contacted { + struct sockaddr *remote; /* remote address to negosiate ph1 */ + LIST_ENTRY(contacted) chain; +}; + +/* + * for checking a packet retransmited. + */ +struct recvdpkt { + struct sockaddr *remote; /* the remote address */ + struct sockaddr *local; /* the local address */ + vchar_t *hash; /* hash of the received packet */ + vchar_t *sendbuf; /* buffer for the response */ + int retry_counter; /* how many times to send */ + struct timeval time_send; /* timestamp of previous send */ + + LIST_ENTRY(recvdpkt) chain; +}; + +/* for parsing ISAKMP header. */ +struct isakmp_parse_t { + u_char type; /* payload type of mine */ + int len; /* ntohs(ptr->len) */ + struct isakmp_gen *ptr; +}; + +/* + * for IV management. + * + * - normal case + * initiator responder + * ------------------------- -------------------------- + * initialize iv(A), ive(A). initialize iv(A), ive(A). + * encode by ive(A). + * save to iv(B). ---[packet(B)]--> save to ive(B). + * decode by iv(A). + * packet consistency. + * sync iv(B) with ive(B). + * check auth, integrity. + * encode by ive(B). + * save to ive(C). <--[packet(C)]--- save to iv(C). + * decoded by iv(B). + * : + * + * - In the case that a error is found while cipher processing, + * initiator responder + * ------------------------- -------------------------- + * initialize iv(A), ive(A). initialize iv(A), ive(A). + * encode by ive(A). + * save to iv(B). ---[packet(B)]--> save to ive(B). + * decode by iv(A). + * packet consistency. + * sync iv(B) with ive(B). + * check auth, integrity. + * error found. + * create notify. + * get ive2(X) from iv(B). + * encode by ive2(X). + * get iv2(X) from iv(B). <--[packet(Y)]--- save to iv2(Y). + * save to ive2(Y). + * decoded by iv2(X). + * : + * + * The reason why the responder synchronizes iv with ive after checking the + * packet consistency is that it is required to leave the IV for decoding + * packet. Because there is a potential of error while checking the packet + * consistency. Also the reason why that is before authentication and + * integirty check is that the IV for informational exchange has to be made + * by the IV which is after packet decoded and checking the packet consistency. + * Otherwise IV mismatched happens between the intitiator and the responder. + */ +struct isakmp_ivm { + vchar_t *iv; /* for decoding packet */ + /* if phase 1, it's for computing phase2 iv */ + vchar_t *ive; /* for encoding packet */ +}; + +/* for dumping */ +struct ph1dump { + isakmp_index index; + int status; + int side; + struct sockaddr_storage remote; + struct sockaddr_storage local; + u_int8_t version; + u_int8_t etype; + time_t created; + int ph2cnt; +}; + +struct sockaddr; +struct ph1handle; +struct ph2handle; +struct policyindex; + +extern struct ph1handle *getph1byindex __P((isakmp_index *)); +extern struct ph1handle *getph1byindex0 __P((isakmp_index *)); + +extern int enumph1 __P((struct ph1selector *ph1sel, + int (* enum_func)(struct ph1handle *iph1, void *arg), + void *enum_arg)); + +#define GETPH1_F_ESTABLISHED 0x0001 + +extern struct ph1handle *getph1 __P((struct ph1handle *ph1hint, + struct sockaddr *local, + struct sockaddr *remote, + int flags)); + +#define getph1byaddr(local, remote, est) \ + getph1(NULL, local, remote, est ? GETPH1_F_ESTABLISHED : 0) +#define getph1bydstaddr(remote) \ + getph1(NULL, NULL, remote, 0) + +#ifdef ENABLE_HYBRID +struct ph1handle *getph1bylogin __P((char *)); +int purgeph1bylogin __P((char *)); +#endif +extern void migrate_ph12 __P((struct ph1handle *old_iph1, struct ph1handle *new_iph1)); +extern void migrate_dying_ph12 __P((struct ph1handle *iph1)); +extern vchar_t *dumpph1 __P((void)); +extern struct ph1handle *newph1 __P((void)); +extern void delph1 __P((struct ph1handle *)); +extern int insph1 __P((struct ph1handle *)); +extern void remph1 __P((struct ph1handle *)); +extern int resolveph1rmconf __P((struct ph1handle *)); +extern void flushph1 __P((void)); +extern void initph1tree __P((void)); +extern int ph1_rekey_enabled __P((struct ph1handle *)); + +extern int enumph2 __P((struct ph2selector *ph2sel, + int (* enum_func)(struct ph2handle *iph2, void *arg), + void *enum_arg)); +extern struct ph2handle *getph2byseq __P((u_int32_t)); +extern struct ph2handle *getph2bysaddr __P((struct sockaddr *, + struct sockaddr *)); +extern struct ph2handle *getph2bymsgid __P((struct ph1handle *, u_int32_t)); +extern struct ph2handle *getph2byid __P((struct sockaddr *, + struct sockaddr *, u_int32_t)); +extern struct ph2handle *getph2bysaidx __P((struct sockaddr *, + struct sockaddr *, u_int, u_int32_t)); +extern struct ph2handle *newph2 __P((void)); +extern void initph2 __P((struct ph2handle *)); +extern void delph2 __P((struct ph2handle *)); +extern int insph2 __P((struct ph2handle *)); +extern void remph2 __P((struct ph2handle *)); +extern void flushph2 __P((void)); +extern void deleteallph2 __P((struct sockaddr *, struct sockaddr *, u_int)); +extern void initph2tree __P((void)); + +extern void bindph12 __P((struct ph1handle *, struct ph2handle *)); +extern void unbindph12 __P((struct ph2handle *)); + +extern struct contacted *getcontacted __P((struct sockaddr *)); +extern int inscontacted __P((struct sockaddr *)); +extern void remcontacted __P((struct sockaddr *)); +extern void initctdtree __P((void)); + +extern int check_recvdpkt __P((struct sockaddr *, + struct sockaddr *, vchar_t *)); +extern int add_recvdpkt __P((struct sockaddr *, struct sockaddr *, + vchar_t *, vchar_t *)); +extern void init_recvdpkt __P((void)); + +#ifdef ENABLE_HYBRID +extern int exclude_cfg_addr __P((const struct sockaddr *)); +#endif + +extern int revalidate_ph12(void); + +#endif /* _HANDLER_H */ diff --git a/ipsec-tools/src/racoon/ipsec_doi.c b/ipsec-tools/src/racoon/ipsec_doi.c new file mode 100644 index 00000000..84a4c715 --- /dev/null +++ b/ipsec-tools/src/racoon/ipsec_doi.c @@ -0,0 +1,4796 @@ +/* $NetBSD: ipsec_doi.c,v 1.46.4.1 2013/06/18 05:40:36 tteras Exp $ */ + +/* Id: ipsec_doi.c,v 1.55 2006/08/17 09:20:41 vanhu Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include + +#include + +#include PATH_IPSEC_H + +#include +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include "var.h" +#include "vmbuf.h" +#include "misc.h" +#include "plog.h" +#include "debug.h" + +#include "cfparse_proto.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "ipsec_doi.h" +#include "oakley.h" +#include "remoteconf.h" +#include "localconf.h" +#include "sockmisc.h" +#include "handler.h" +#include "policy.h" +#include "algorithm.h" +#include "sainfo.h" +#include "proposal.h" +#include "crypto_openssl.h" +#include "strnames.h" +#include "gcmalloc.h" + +#ifdef ENABLE_NATT +#include "nattraversal.h" +#endif + +#ifdef HAVE_GSSAPI +#include +#include "gssapi.h" +#ifdef HAVE_ICONV_2ND_CONST +#define __iconv_const const +#else +#define __iconv_const +#endif +#endif + +static vchar_t *get_ph1approval __P((struct ph1handle *, u_int32_t, u_int32_t, + struct prop_pair **)); +static int get_ph1approvalx __P((struct remoteconf *, void *)); + +static int t2isakmpsa __P((struct isakmp_pl_t *, struct isakmpsa *, u_int32_t)); +static int cmp_aproppair_i __P((struct prop_pair *, struct prop_pair *)); +static struct prop_pair *get_ph2approval __P((struct ph2handle *, + struct prop_pair **)); +static struct prop_pair *get_ph2approvalx __P((struct ph2handle *, + struct prop_pair *)); +static void free_proppair0 __P((struct prop_pair *)); +static struct prop_pair ** get_proppair_and_doi_sit __P((vchar_t *, int, + u_int32_t *, u_int32_t *)); + +static int get_transform + __P((struct isakmp_pl_p *, struct prop_pair **, int *)); +static u_int32_t ipsecdoi_set_ld __P((vchar_t *)); + +static int check_doi __P((u_int32_t)); +static int check_situation __P((u_int32_t)); + +static int check_prot_main __P((int)); +static int check_prot_quick __P((int)); +static int (*check_protocol[]) __P((int)) = { + check_prot_main, /* IPSECDOI_TYPE_PH1 */ + check_prot_quick, /* IPSECDOI_TYPE_PH2 */ +}; + +static int check_spi_size __P((int, int)); + +static int check_trns_isakmp __P((int)); +static int check_trns_ah __P((int)); +static int check_trns_esp __P((int)); +static int check_trns_ipcomp __P((int)); +static int (*check_transform[]) __P((int)) = { + 0, + check_trns_isakmp, /* IPSECDOI_PROTO_ISAKMP */ + check_trns_ah, /* IPSECDOI_PROTO_IPSEC_AH */ + check_trns_esp, /* IPSECDOI_PROTO_IPSEC_ESP */ + check_trns_ipcomp, /* IPSECDOI_PROTO_IPCOMP */ +}; + +static int check_attr_isakmp __P((struct isakmp_pl_t *)); +static int check_attr_ah __P((struct isakmp_pl_t *)); +static int check_attr_esp __P((struct isakmp_pl_t *)); +static int check_attr_ipsec __P((int, struct isakmp_pl_t *)); +static int check_attr_ipcomp __P((struct isakmp_pl_t *)); +static int (*check_attributes[]) __P((struct isakmp_pl_t *)) = { + 0, + check_attr_isakmp, /* IPSECDOI_PROTO_ISAKMP */ + check_attr_ah, /* IPSECDOI_PROTO_IPSEC_AH */ + check_attr_esp, /* IPSECDOI_PROTO_IPSEC_ESP */ + check_attr_ipcomp, /* IPSECDOI_PROTO_IPCOMP */ +}; + +static int setph1prop __P((struct isakmpsa *, caddr_t)); +static int setph1trns __P((struct isakmpsa *, caddr_t)); +static int setph1attr __P((struct isakmpsa *, caddr_t)); +static vchar_t *setph2proposal0 __P((const struct ph2handle *, + const struct saprop *, const struct saproto *)); + +struct ph1approvalx_ctx { + struct prop_pair *p; + struct isakmpsa *sa; +}; + +/*%%%*/ +/* + * check phase 1 SA payload. + * make new SA payload to be replyed not including general header. + * the pointer to one of isakmpsa in proposal is set into iph1->approval. + * OUT: + * positive: the pointer to new buffer of SA payload. + * network byte order. + * NULL : error occurd. + */ +int +ipsecdoi_checkph1proposal(sa, iph1) + vchar_t *sa; + struct ph1handle *iph1; +{ + vchar_t *newsa; /* new SA payload approved. */ + struct prop_pair **pair; + u_int32_t doitype, sittype; + + /* get proposal pair */ + pair = get_proppair_and_doi_sit(sa, IPSECDOI_TYPE_PH1, + &doitype, &sittype); + if (pair == NULL) + return -1; + + /* check and get one SA for use */ + newsa = get_ph1approval(iph1, doitype, sittype, pair); + free_proppair(pair); + + if (newsa == NULL) + return -1; + + iph1->sa_ret = newsa; + return 0; +} + +static void +print_ph1proposal(pair, s) + struct prop_pair *pair; + struct isakmpsa *s; +{ + struct isakmp_pl_p *prop = pair->prop; + struct isakmp_pl_t *trns = pair->trns; + + plog(LLV_DEBUG, LOCATION, NULL, + "prop#=%d, prot-id=%s, spi-size=%d, #trns=%d\n", + prop->p_no, s_ipsecdoi_proto(prop->proto_id), + prop->spi_size, prop->num_t); + plog(LLV_DEBUG, LOCATION, NULL, + "trns#=%d, trns-id=%s\n", + trns->t_no, s_ipsecdoi_trns(prop->proto_id, trns->t_id)); + plog(LLV_DEBUG, LOCATION, NULL, + " lifetime = %ld\n", (long) s->lifetime); + plog(LLV_DEBUG, LOCATION, NULL, + " lifebyte = %zu\n", s->lifebyte); + plog(LLV_DEBUG, LOCATION, NULL, + " enctype = %s\n", + s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG, s->enctype)); + plog(LLV_DEBUG, LOCATION, NULL, + " encklen = %d\n", s->encklen); + plog(LLV_DEBUG, LOCATION, NULL, + " hashtype = %s\n", + s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG, s->hashtype)); + plog(LLV_DEBUG, LOCATION, NULL, + " authmethod = %s\n", + s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD, s->authmethod)); + plog(LLV_DEBUG, LOCATION, NULL, + " dh_group = %s\n", + s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC, s->dh_group)); +} + + +/* + * acceptable check for remote configuration. + * return a new SA payload to be reply to peer. + */ + +static vchar_t * +get_ph1approval(iph1, doitype, sittype, pair) + struct ph1handle *iph1; + u_int32_t doitype, sittype; + struct prop_pair **pair; +{ + vchar_t *newsa; + struct ph1approvalx_ctx ctx; + struct prop_pair *s, *p; + struct rmconfselector rmsel; + struct isakmpsa *sa; + int i; + + memset(&rmsel, 0, sizeof(rmsel)); + rmsel.remote = iph1->remote; + + if (iph1->approval) { + delisakmpsa(iph1->approval); + iph1->approval = NULL; + } + + for (i = 0; i < MAXPROPPAIRLEN; i++) { + if (pair[i] == NULL) + continue; + for (s = pair[i]; s; s = s->next) { + /* compare proposal and select one */ + for (p = s; p; p = p->tnext) { + struct isakmp_pl_p *prop = p->prop; + + sa = newisakmpsa(); + ctx.p = p; + ctx.sa = sa; + if (t2isakmpsa(p->trns, sa, + iph1->vendorid_mask) < 0) + continue; + print_ph1proposal(p, sa); + if (iph1->rmconf != NULL) { + if (get_ph1approvalx(iph1->rmconf, &ctx)) + goto found; + } else { + if (enumrmconf(&rmsel, get_ph1approvalx, &ctx)) + goto found; + } + delisakmpsa(sa); + } + } + } + + plog(LLV_ERROR, LOCATION, NULL, "no suitable proposal found.\n"); + + return NULL; + +found: + sa = ctx.sa; + plog(LLV_DEBUG, LOCATION, NULL, "an acceptable proposal found.\n"); + + /* check DH group settings */ + if (sa->dhgrp) { + if (sa->dhgrp->prime && sa->dhgrp->gen1) { + /* it's ok */ + goto saok; + } + plog(LLV_WARNING, LOCATION, NULL, + "invalid DH parameter found, use default.\n"); + oakley_dhgrp_free(sa->dhgrp); + sa->dhgrp=NULL; + } + + if (oakley_setdhgroup(sa->dh_group, &sa->dhgrp) == -1) { + sa->dhgrp = NULL; + delisakmpsa(sa); + return NULL; + } + +saok: +#ifdef HAVE_GSSAPI + if (sa->gssid != NULL) + plog(LLV_DEBUG, LOCATION, NULL, "gss id in new sa '%.*s'\n", + (int)sa->gssid->l, sa->gssid->v); + if (iph1->side == INITIATOR) { + if (iph1->rmconf->proposal->gssid != NULL) + iph1->gi_i = vdup(iph1->rmconf->proposal->gssid); + if (sa->gssid != NULL) + iph1->gi_r = vdup(sa->gssid); + } else { + if (sa->gssid != NULL) { + iph1->gi_r = vdup(sa->gssid); + iph1->gi_i = gssapi_get_id(iph1); + } + } + if (iph1->gi_i != NULL) + plog(LLV_DEBUG, LOCATION, NULL, "GIi is %.*s\n", + (int)iph1->gi_i->l, iph1->gi_i->v); + if (iph1->gi_r != NULL) + plog(LLV_DEBUG, LOCATION, NULL, "GIr is %.*s\n", + (int)iph1->gi_r->l, iph1->gi_r->v); +#endif + plog(LLV_DEBUG, LOCATION, NULL, "agreed on %s auth.\n", + s_oakley_attr_method(sa->authmethod)); + + newsa = get_sabyproppair(doitype, sittype, p); + if (newsa == NULL) + delisakmpsa(sa); + else + iph1->approval = sa; + + return newsa; +} + +/* + * compare peer's single proposal and all of my proposal. + * and select one if suiatable. + */ +static int +get_ph1approvalx(rmconf, ctx) + struct remoteconf *rmconf; + void *ctx; +{ + struct ph1approvalx_ctx *pctx = (struct ph1approvalx_ctx *) ctx; + struct isakmpsa *sa; + + /* do the hard work */ + sa = checkisakmpsa(rmconf->pcheck_level, pctx->sa, rmconf->proposal); + if (sa == NULL) + return 0; + + /* duplicate and modify the found SA to match proposal */ + sa = dupisakmpsa(sa); + + switch (rmconf->pcheck_level) { + case PROP_CHECK_OBEY: + sa->lifetime = pctx->sa->lifetime; + sa->lifebyte = pctx->sa->lifebyte; + sa->encklen = pctx->sa->encklen; + break; + case PROP_CHECK_CLAIM: + case PROP_CHECK_STRICT: + if (pctx->sa->lifetime < sa->lifetime) + sa->lifetime = pctx->sa->lifetime; + if (pctx->sa->lifebyte < sa->lifebyte) + sa->lifebyte = pctx->sa->lifebyte; + if (pctx->sa->encklen > sa->encklen) + sa->encklen = pctx->sa->encklen; + break; + default: + break; + } + + /* replace the proposal with our approval sa */ + delisakmpsa(pctx->sa); + pctx->sa = sa; + + return 1; +} + +/* + * get ISAKMP data attributes + */ +static int +t2isakmpsa(trns, sa, vendorid_mask) + struct isakmp_pl_t *trns; + struct isakmpsa *sa; + u_int32_t vendorid_mask; +{ + struct isakmp_data *d, *prev; + int flag, type; + int error = -1; + int life_t; + int keylen = 0; + vchar_t *val = NULL; + int len, tlen; + u_char *p; + + tlen = ntohs(trns->h.len) - sizeof(*trns); + prev = (struct isakmp_data *)NULL; + d = (struct isakmp_data *)(trns + 1); + + /* default */ + life_t = OAKLEY_ATTR_SA_LD_TYPE_DEFAULT; + sa->lifetime = OAKLEY_ATTR_SA_LD_SEC_DEFAULT; + sa->lifebyte = 0; + sa->dhgrp = racoon_calloc(1, sizeof(struct dhgroup)); + if (!sa->dhgrp) + goto err; + + while (tlen > 0) { + + type = ntohs(d->type) & ~ISAKMP_GEN_MASK; + flag = ntohs(d->type) & ISAKMP_GEN_MASK; + + plog(LLV_DEBUG, LOCATION, NULL, + "type=%s, flag=0x%04x, lorv=%s\n", + s_oakley_attr(type), flag, + s_oakley_attr_v(type, ntohs(d->lorv))); + + /* get variable-sized item */ + switch (type) { + case OAKLEY_ATTR_GRP_PI: + case OAKLEY_ATTR_GRP_GEN_ONE: + case OAKLEY_ATTR_GRP_GEN_TWO: + case OAKLEY_ATTR_GRP_CURVE_A: + case OAKLEY_ATTR_GRP_CURVE_B: + case OAKLEY_ATTR_SA_LD: + case OAKLEY_ATTR_GRP_ORDER: + if (flag) { /*TV*/ + len = 2; + p = (u_char *)&d->lorv; + } else { /*TLV*/ + len = ntohs(d->lorv); + p = (u_char *)(d + 1); + } + val = vmalloc(len); + if (!val) + return -1; + memcpy(val->v, p, len); + break; + + default: + break; + } + + switch (type) { + case OAKLEY_ATTR_ENC_ALG: + sa->enctype = (u_int16_t)ntohs(d->lorv); + break; + + case OAKLEY_ATTR_HASH_ALG: + sa->hashtype = (u_int16_t)ntohs(d->lorv); + break; + + case OAKLEY_ATTR_AUTH_METHOD: + sa->authmethod = ntohs(d->lorv); +#ifdef HAVE_GSSAPI + if (sa->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB_REAL && + (vendorid_mask & VENDORID_GSSAPI_MASK)) + sa->authmethod = OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB; +#endif + break; + + case OAKLEY_ATTR_GRP_DESC: + sa->dh_group = (u_int16_t)ntohs(d->lorv); + break; + + case OAKLEY_ATTR_GRP_TYPE: + { + int type = (int)ntohs(d->lorv); + if (type == OAKLEY_ATTR_GRP_TYPE_MODP) + sa->dhgrp->type = type; + else + return -1; + break; + } + case OAKLEY_ATTR_GRP_PI: + sa->dhgrp->prime = val; + break; + + case OAKLEY_ATTR_GRP_GEN_ONE: + vfree(val); + if (!flag) + sa->dhgrp->gen1 = ntohs(d->lorv); + else { + int len = ntohs(d->lorv); + sa->dhgrp->gen1 = 0; + if (len > 4) + return -1; + memcpy(&sa->dhgrp->gen1, d + 1, len); + sa->dhgrp->gen1 = ntohl(sa->dhgrp->gen1); + } + break; + + case OAKLEY_ATTR_GRP_GEN_TWO: + vfree(val); + if (!flag) + sa->dhgrp->gen2 = ntohs(d->lorv); + else { + int len = ntohs(d->lorv); + sa->dhgrp->gen2 = 0; + if (len > 4) + return -1; + memcpy(&sa->dhgrp->gen2, d + 1, len); + sa->dhgrp->gen2 = ntohl(sa->dhgrp->gen2); + } + break; + + case OAKLEY_ATTR_GRP_CURVE_A: + sa->dhgrp->curve_a = val; + break; + + case OAKLEY_ATTR_GRP_CURVE_B: + sa->dhgrp->curve_b = val; + break; + + case OAKLEY_ATTR_SA_LD_TYPE: + { + int type = (int)ntohs(d->lorv); + switch (type) { + case OAKLEY_ATTR_SA_LD_TYPE_SEC: + case OAKLEY_ATTR_SA_LD_TYPE_KB: + life_t = type; + break; + default: + life_t = OAKLEY_ATTR_SA_LD_TYPE_DEFAULT; + break; + } + break; + } + case OAKLEY_ATTR_SA_LD: + if (!prev + || (ntohs(prev->type) & ~ISAKMP_GEN_MASK) != + OAKLEY_ATTR_SA_LD_TYPE) { + plog(LLV_ERROR, LOCATION, NULL, + "life duration must follow ltype\n"); + break; + } + + switch (life_t) { + case IPSECDOI_ATTR_SA_LD_TYPE_SEC: + sa->lifetime = ipsecdoi_set_ld(val); + vfree(val); + if (sa->lifetime == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid life duration.\n"); + goto err; + } + break; + case IPSECDOI_ATTR_SA_LD_TYPE_KB: + sa->lifebyte = ipsecdoi_set_ld(val); + vfree(val); + if (sa->lifebyte == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid life duration.\n"); + goto err; + } + break; + default: + vfree(val); + plog(LLV_ERROR, LOCATION, NULL, + "invalid life type: %d\n", life_t); + goto err; + } + break; + + case OAKLEY_ATTR_KEY_LEN: + { + int len = ntohs(d->lorv); + if (len % 8 != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "keylen %d: not multiple of 8\n", + len); + goto err; + } + sa->encklen = (u_int16_t)len; + keylen++; + break; + } + case OAKLEY_ATTR_PRF: + case OAKLEY_ATTR_FIELD_SIZE: + /* unsupported */ + break; + + case OAKLEY_ATTR_GRP_ORDER: + sa->dhgrp->order = val; + break; +#ifdef HAVE_GSSAPI + case OAKLEY_ATTR_GSS_ID: + { + int error = -1; + iconv_t cd = (iconv_t) -1; + size_t srcleft, dstleft, rv; + __iconv_const char *src; + char *dst; + int len = ntohs(d->lorv); + + /* + * Older verions of racoon just placed the + * ISO-Latin-1 string on the wire directly. + * Check to see if we are configured to be + * compatible with this behavior. + */ + if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) { + if ((sa->gssid = vmalloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate memory\n"); + goto out; + } + memcpy(sa->gssid->v, d + 1, len); + plog(LLV_DEBUG, LOCATION, NULL, + "received old-style gss " + "id '%.*s' (len %zu)\n", + (int)sa->gssid->l, sa->gssid->v, + sa->gssid->l); + error = 0; + goto out; + } + + /* + * For Windows 2000 compatibility, we expect + * the GSS ID attribute on the wire to be + * encoded in UTF-16LE. Internally, we work + * in ISO-Latin-1. Therefore, we should need + * 1/2 the specified length, which should always + * be a multiple of 2 octets. + */ + cd = iconv_open("latin1", "utf-16le"); + if (cd == (iconv_t) -1) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to initialize utf-16le -> latin1 " + "conversion descriptor: %s\n", + strerror(errno)); + goto out; + } + + if ((sa->gssid = vmalloc(len / 2)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate memory\n"); + goto out; + } + + src = (__iconv_const char *)(d + 1); + srcleft = len; + + dst = sa->gssid->v; + dstleft = len / 2; + + rv = iconv(cd, (__iconv_const char **)&src, &srcleft, + &dst, &dstleft); + if (rv != 0) { + if (rv == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to convert GSS ID from " + "utf-16le -> latin1: %s\n", + strerror(errno)); + } else { + plog(LLV_ERROR, LOCATION, NULL, + "%zd character%s in GSS ID cannot " + "be represented in latin1\n", + rv, rv == 1 ? "" : "s"); + } + goto out; + } + + /* XXX dstleft should always be 0; assert it? */ + sa->gssid->l = (len / 2) - dstleft; + + plog(LLV_DEBUG, LOCATION, NULL, + "received gss id '%.*s' (len %zu)\n", + (int)sa->gssid->l, sa->gssid->v, sa->gssid->l); + + error = 0; +out: + if (cd != (iconv_t)-1) + (void)iconv_close(cd); + + if ((error != 0) && (sa->gssid != NULL)) { + vfree(sa->gssid); + sa->gssid = NULL; + } + break; + } +#endif /* HAVE_GSSAPI */ + + default: + break; + } + + prev = d; + if (flag) { + tlen -= sizeof(*d); + d = (struct isakmp_data *)((char *)d + sizeof(*d)); + } else { + tlen -= (sizeof(*d) + ntohs(d->lorv)); + d = (struct isakmp_data *)((char *)d + sizeof(*d) + ntohs(d->lorv)); + } + } + + /* key length must not be specified on some algorithms */ + if (keylen) { + if (sa->enctype == OAKLEY_ATTR_ENC_ALG_DES +#ifdef HAVE_OPENSSL_IDEA_H + || sa->enctype == OAKLEY_ATTR_ENC_ALG_IDEA +#endif + || sa->enctype == OAKLEY_ATTR_ENC_ALG_3DES) { + plog(LLV_ERROR, LOCATION, NULL, + "keylen must not be specified " + "for encryption algorithm %d\n", + sa->enctype); + return -1; + } + } + + return 0; +err: + return error; +} + +/*%%%*/ +/* + * check phase 2 SA payload and select single proposal. + * make new SA payload to be replyed not including general header. + * This function is called by responder only. + * OUT: + * 0: succeed. + * -1: error occured. + */ +int +ipsecdoi_selectph2proposal(iph2) + struct ph2handle *iph2; +{ + struct prop_pair **pair; + struct prop_pair *ret; + u_int32_t doitype, sittype; + + /* get proposal pair */ + pair = get_proppair_and_doi_sit(iph2->sa, IPSECDOI_TYPE_PH2, + &doitype, &sittype); + if (pair == NULL) + return -1; + + /* check and select a proposal. */ + ret = get_ph2approval(iph2, pair); + free_proppair(pair); + if (ret == NULL) + return -1; + + /* make a SA to be replayed. */ + /* SPI must be updated later. */ + iph2->sa_ret = get_sabyproppair(doitype, sittype, ret); + free_proppair0(ret); + if (iph2->sa_ret == NULL) + return -1; + + return 0; +} + +/* + * check phase 2 SA payload returned from responder. + * This function is called by initiator only. + * OUT: + * 0: valid. + * -1: invalid. + */ +int +ipsecdoi_checkph2proposal(iph2) + struct ph2handle *iph2; +{ + struct prop_pair **rpair = NULL, **spair = NULL; + struct prop_pair *p; + int i, n, num; + int error = -1; + vchar_t *sa_ret = NULL; + u_int32_t doitype, sittype; + + /* get proposal pair of SA sent. */ + spair = get_proppair_and_doi_sit(iph2->sa, IPSECDOI_TYPE_PH2, + &doitype, &sittype); + if (spair == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get prop pair.\n"); + goto end; + } + + /* XXX should check the number of transform */ + + /* get proposal pair of SA replayed */ + rpair = get_proppair(iph2->sa_ret, IPSECDOI_TYPE_PH2); + if (rpair == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get prop pair.\n"); + goto end; + } + + /* check proposal is only one ? */ + n = 0; + num = 0; + for (i = 0; i < MAXPROPPAIRLEN; i++) { + if (rpair[i]) { + n = i; + num++; + } + } + if (num == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "no proposal received.\n"); + goto end; + } + if (num != 1) { + plog(LLV_ERROR, LOCATION, NULL, + "some proposals received.\n"); + goto end; + } + + if (spair[n] == NULL) { + plog(LLV_WARNING, LOCATION, NULL, + "invalid proposal number:%d received.\n", i); + } + + + if (rpair[n]->tnext != NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "multi transforms replyed.\n"); + goto end; + } + + if (cmp_aproppair_i(rpair[n], spair[n])) { + plog(LLV_ERROR, LOCATION, NULL, + "proposal mismathed.\n"); + goto end; + } + + /* + * check and select a proposal. + * ensure that there is no modification of the proposal by + * cmp_aproppair_i() + */ + p = get_ph2approval(iph2, rpair); + if (p == NULL) + goto end; + + /* make a SA to be replayed. */ + sa_ret = iph2->sa_ret; + iph2->sa_ret = get_sabyproppair(doitype, sittype, p); + free_proppair0(p); + if (iph2->sa_ret == NULL) + goto end; + + error = 0; + +end: + if (rpair) + free_proppair(rpair); + if (spair) + free_proppair(spair); + if (sa_ret) + vfree(sa_ret); + + return error; +} + +/* + * compare two prop_pair which is assumed to have same proposal number. + * the case of bundle or single SA, NOT multi transforms. + * a: a proposal that is multi protocols and single transform, usually replyed. + * b: a proposal that is multi protocols and multi transform, usually sent. + * NOTE: this function is for initiator. + * OUT + * 0: equal + * 1: not equal + * XXX cannot understand the comment! + */ +static int +cmp_aproppair_i(a, b) + struct prop_pair *a, *b; +{ + struct prop_pair *p, *q, *r; + int len; + + for (p = a, q = b; p && q; p = p->next, q = q->next) { + for (r = q; r; r = r->tnext) { + /* compare trns */ + if (p->trns->t_no == r->trns->t_no) + break; + } + if (!r) { + /* no suitable transform found */ + plog(LLV_ERROR, LOCATION, NULL, + "no suitable transform found.\n"); + return -1; + } + + /* compare prop */ + if (p->prop->p_no != r->prop->p_no) { + plog(LLV_WARNING, LOCATION, NULL, + "proposal #%d mismatched, " + "expected #%d.\n", + r->prop->p_no, p->prop->p_no); + /*FALLTHROUGH*/ + } + + if (p->prop->proto_id != r->prop->proto_id) { + plog(LLV_ERROR, LOCATION, NULL, + "proto_id mismathed: my:%d peer:%d\n", + r->prop->proto_id, p->prop->proto_id); + return -1; + } + + if (p->prop->spi_size != r->prop->spi_size) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid spi size: %d.\n", + p->prop->spi_size); + return -1; + } + + /* check #of transforms */ + if (p->prop->num_t != 1) { + plog(LLV_WARNING, LOCATION, NULL, + "#of transform is %d, " + "but expected 1.\n", p->prop->num_t); + /*FALLTHROUGH*/ + } + + if (p->trns->t_id != r->trns->t_id) { + plog(LLV_WARNING, LOCATION, NULL, + "transform number has been modified.\n"); + /*FALLTHROUGH*/ + } + if (p->trns->reserved != r->trns->reserved) { + plog(LLV_WARNING, LOCATION, NULL, + "reserved field should be zero.\n"); + /*FALLTHROUGH*/ + } + + /* compare attribute */ + len = ntohs(r->trns->h.len) - sizeof(*p->trns); + if (memcmp(p->trns + 1, r->trns + 1, len) != 0) { + plog(LLV_WARNING, LOCATION, NULL, + "attribute has been modified.\n"); + /*FALLTHROUGH*/ + } + } + if ((p && !q) || (!p && q)) { + /* # of protocols mismatched */ + plog(LLV_ERROR, LOCATION, NULL, + "#of protocols mismatched.\n"); + return -1; + } + + return 0; +} + +/* + * acceptable check for policy configuration. + * return a new SA payload to be reply to peer. + */ +static struct prop_pair * +get_ph2approval(iph2, pair) + struct ph2handle *iph2; + struct prop_pair **pair; +{ + struct prop_pair *ret; + int i; + + iph2->approval = NULL; + + plog(LLV_DEBUG, LOCATION, NULL, + "begin compare proposals.\n"); + + for (i = 0; i < MAXPROPPAIRLEN; i++) { + if (pair[i] == NULL) + continue; + plog(LLV_DEBUG, LOCATION, NULL, + "pair[%d]: %p\n", i, pair[i]); + print_proppair(LLV_DEBUG, pair[i]);; + + /* compare proposal and select one */ + ret = get_ph2approvalx(iph2, pair[i]); + if (ret != NULL) { + /* found */ + return ret; + } + } + + plog(LLV_ERROR, LOCATION, NULL, "no suitable policy found.\n"); + + return NULL; +} + +/* + * compare my proposal and peers just one proposal. + * set a approval. + */ +static struct prop_pair * +get_ph2approvalx(iph2, pp) + struct ph2handle *iph2; + struct prop_pair *pp; +{ + struct prop_pair *ret = NULL; + struct saprop *pr0, *pr = NULL; + struct saprop *q1, *q2; + + pr0 = aproppair2saprop(pp); + if (pr0 == NULL) + return NULL; + + for (q1 = pr0; q1; q1 = q1->next) { + for (q2 = iph2->proposal; q2; q2 = q2->next) { + plog(LLV_DEBUG, LOCATION, NULL, + "peer's single bundle:\n"); + printsaprop0(LLV_DEBUG, q1); + plog(LLV_DEBUG, LOCATION, NULL, + "my single bundle:\n"); + printsaprop0(LLV_DEBUG, q2); + + pr = cmpsaprop_alloc(iph2->ph1, q1, q2, iph2->side); + if (pr != NULL) + goto found; + + plog(LLV_ERROR, LOCATION, NULL, + "not matched\n"); + } + } + /* no proposal matching */ +err: + flushsaprop(pr0); + return NULL; + +found: + flushsaprop(pr0); + plog(LLV_DEBUG, LOCATION, NULL, "matched\n"); + iph2->approval = pr; + + { + struct saproto *sp; + struct prop_pair *p, *x; + struct prop_pair *n = NULL; + + ret = NULL; + + for (p = pp; p; p = p->next) { + /* + * find a proposal with matching proto_id. + * we have analyzed validity already, in cmpsaprop_alloc(). + */ + for (sp = pr->head; sp; sp = sp->next) { + if (sp->proto_id == p->prop->proto_id) + break; + } + if (!sp) + goto err; + if (sp->head->next) + goto err; /* XXX */ + + for (x = p; x; x = x->tnext) + if (sp->head->trns_no == x->trns->t_no) + break; + if (!x) + goto err; /* XXX */ + + n = racoon_calloc(1, sizeof(struct prop_pair)); + if (n == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer.\n"); + goto err; + } + + n->prop = x->prop; + n->trns = x->trns; + + /* need to preserve the order */ + for (x = ret; x && x->next; x = x->next) + ; + if (x && x->prop == n->prop) { + for (/*nothing*/; x && x->tnext; x = x->tnext) + ; + x->tnext = n; + } else { + if (x) + x->next = n; + else { + ret = n; + } + } + + /* #of transforms should be updated ? */ + } + } + + return ret; +} + +void +free_proppair(pair) + struct prop_pair **pair; +{ + int i; + + for (i = 0; i < MAXPROPPAIRLEN; i++) { + free_proppair0(pair[i]); + pair[i] = NULL; + } + racoon_free(pair); +} + +static void +free_proppair0(pair) + struct prop_pair *pair; +{ + struct prop_pair *p, *q, *r, *s; + + p = pair; + while (p) { + q = p->next; + r = p; + while (r) { + s = r->tnext; + racoon_free(r); + r = s; + } + p = q; + } +} + +/* + * get proposal pairs from SA payload. + * tiny check for proposal payload. + */ +static struct prop_pair ** +get_proppair_and_doi_sit(sa, mode, doitype, sittype) + vchar_t *sa; + int mode; + u_int32_t *doitype, *sittype; +{ + struct prop_pair **pair = NULL; + int num_p = 0; /* number of proposal for use */ + int tlen; + caddr_t bp; + int i; + struct ipsecdoi_sa_b *sab = (struct ipsecdoi_sa_b *)sa->v; + + plog(LLV_DEBUG, LOCATION, NULL, "total SA len=%zu\n", sa->l); + plogdump(LLV_DEBUG, sa->v, sa->l); + + /* check SA payload size */ + if (sa->l < sizeof(*sab)) { + plog(LLV_ERROR, LOCATION, NULL, + "Invalid SA length = %zu.\n", sa->l); + goto bad; + } + + /* check DOI */ + if (check_doi(ntohl(sab->doi)) < 0) + goto bad; + if (doitype != NULL) + *doitype = ntohl(sab->doi); + + /* check SITUATION */ + if (check_situation(ntohl(sab->sit)) < 0) + goto bad; + if (sittype != NULL) + *sittype = ntohl(sab->sit); + + pair = racoon_calloc(1, MAXPROPPAIRLEN * sizeof(*pair)); + if (pair == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer.\n"); + goto bad; + } + + bp = (caddr_t)(sab + 1); + tlen = sa->l - sizeof(*sab); + + { + struct isakmp_pl_p *prop; + int proplen; + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + + pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_P, (struct isakmp_gen *)bp, tlen); + if (pbuf == NULL) + goto bad; + + for (pa = (struct isakmp_parse_t *)pbuf->v; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + /* check the value of next payload */ + if (pa->type != ISAKMP_NPTYPE_P) { + plog(LLV_ERROR, LOCATION, NULL, + "Invalid payload type=%u\n", pa->type); + vfree(pbuf); + goto bad; + } + + prop = (struct isakmp_pl_p *)pa->ptr; + proplen = pa->len; + + plog(LLV_DEBUG, LOCATION, NULL, + "proposal #%u len=%d\n", prop->p_no, proplen); + + if (proplen == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid proposal with length %d\n", proplen); + vfree(pbuf); + goto bad; + } + + /* check Protocol ID */ + if (!check_protocol[mode]) { + plog(LLV_ERROR, LOCATION, NULL, + "unsupported mode %d\n", mode); + continue; + } + + if (check_protocol[mode](prop->proto_id) < 0) + continue; + + /* check SPI length when IKE. */ + if (check_spi_size(prop->proto_id, prop->spi_size) < 0) + continue; + + /* get transform */ + if (get_transform(prop, pair, &num_p) < 0) { + vfree(pbuf); + goto bad; + } + } + vfree(pbuf); + pbuf = NULL; + } + + { + int notrans, nprop; + struct prop_pair *p, *q; + + /* check for proposals with no transforms */ + for (i = 0; i < MAXPROPPAIRLEN; i++) { + if (!pair[i]) + continue; + + plog(LLV_DEBUG, LOCATION, NULL, "pair %d:\n", i); + print_proppair(LLV_DEBUG, pair[i]); + + notrans = nprop = 0; + for (p = pair[i]; p; p = p->next) { + if (p->trns == NULL) { + notrans++; + break; + } + for (q = p; q; q = q->tnext) + nprop++; + } + +#if 0 + /* + * XXX at this moment, we cannot accept proposal group + * with multiple proposals. this should be fixed. + */ + if (pair[i]->next) { + plog(LLV_WARNING, LOCATION, NULL, + "proposal #%u ignored " + "(multiple proposal not supported)\n", + pair[i]->prop->p_no); + notrans++; + } +#endif + + if (notrans) { + for (p = pair[i]; p; p = q) { + q = p->next; + racoon_free(p); + } + pair[i] = NULL; + num_p--; + } else { + plog(LLV_DEBUG, LOCATION, NULL, + "proposal #%u: %d transform\n", + pair[i]->prop->p_no, nprop); + } + } + } + + /* bark if no proposal is found. */ + if (num_p <= 0) { + plog(LLV_ERROR, LOCATION, NULL, + "no Proposal found.\n"); + goto bad; + } + + return pair; +bad: + if (pair != NULL) + racoon_free(pair); + return NULL; +} + +struct prop_pair ** +get_proppair(sa, mode) + vchar_t *sa; + int mode; +{ + return get_proppair_and_doi_sit(sa, mode, NULL, NULL); +} + + +/* + * check transform payload. + * OUT: + * positive: return the pointer to the payload of valid transform. + * 0 : No valid transform found. + */ +static int +get_transform(prop, pair, num_p) + struct isakmp_pl_p *prop; + struct prop_pair **pair; + int *num_p; +{ + int tlen; /* total length of all transform in a proposal */ + caddr_t bp; + struct isakmp_pl_t *trns; + int trnslen; + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + struct prop_pair *p = NULL, *q; + int num_t; + + bp = (caddr_t)prop + sizeof(struct isakmp_pl_p) + prop->spi_size; + tlen = ntohs(prop->h.len) + - (sizeof(struct isakmp_pl_p) + prop->spi_size); + pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_T, (struct isakmp_gen *)bp, tlen); + if (pbuf == NULL) + return -1; + + /* check and get transform for use */ + num_t = 0; + for (pa = (struct isakmp_parse_t *)pbuf->v; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + num_t++; + + /* check the value of next payload */ + if (pa->type != ISAKMP_NPTYPE_T) { + plog(LLV_ERROR, LOCATION, NULL, + "Invalid payload type=%u\n", pa->type); + break; + } + + trns = (struct isakmp_pl_t *)pa->ptr; + trnslen = pa->len; + + plog(LLV_DEBUG, LOCATION, NULL, + "transform #%u len=%u\n", trns->t_no, trnslen); + + /* check transform ID */ + if (prop->proto_id >= ARRAYLEN(check_transform)) { + plog(LLV_WARNING, LOCATION, NULL, + "unsupported proto_id %u\n", + prop->proto_id); + continue; + } + if (prop->proto_id >= ARRAYLEN(check_attributes)) { + plog(LLV_WARNING, LOCATION, NULL, + "unsupported proto_id %u\n", + prop->proto_id); + continue; + } + + if (!check_transform[prop->proto_id] + || !check_attributes[prop->proto_id]) { + plog(LLV_WARNING, LOCATION, NULL, + "unsupported proto_id %u\n", + prop->proto_id); + continue; + } + if (check_transform[prop->proto_id](trns->t_id) < 0) + continue; + + /* check data attributes */ + if (check_attributes[prop->proto_id](trns) != 0) + continue; + + p = racoon_calloc(1, sizeof(*p)); + if (p == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer.\n"); + vfree(pbuf); + return -1; + } + p->prop = prop; + p->trns = trns; + + /* need to preserve the order */ + for (q = pair[prop->p_no]; q && q->next; q = q->next) + ; + if (q && q->prop == p->prop) { + for (/*nothing*/; q && q->tnext; q = q->tnext) + ; + q->tnext = p; + } else { + if (q) + q->next = p; + else { + pair[prop->p_no] = p; + (*num_p)++; + } + } + } + + vfree(pbuf); + + return 0; +} + +/* + * make a new SA payload from prop_pair. + * NOTE: this function make spi value clear. + */ +vchar_t * +get_sabyproppair(doitype, sittype, pair) + u_int32_t doitype, sittype; + struct prop_pair *pair; +{ + vchar_t *newsa; + int newtlen; + u_int8_t *np_p = NULL; + struct prop_pair *p; + int prophlen, trnslen; + caddr_t bp; + + newtlen = sizeof(struct ipsecdoi_sa_b); + for (p = pair; p; p = p->next) { + newtlen += sizeof(struct isakmp_pl_p); + newtlen += p->prop->spi_size; + newtlen += ntohs(p->trns->h.len); + } + + newsa = vmalloc(newtlen); + if (newsa == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "failed to get newsa.\n"); + return NULL; + } + bp = newsa->v; + + ((struct isakmp_gen *)bp)->len = htons(newtlen); + + /* update some of values in SA header */ + ((struct ipsecdoi_sa_b *)bp)->doi = htonl(doitype); + ((struct ipsecdoi_sa_b *)bp)->sit = htonl(sittype); + bp += sizeof(struct ipsecdoi_sa_b); + + /* create proposal payloads */ + for (p = pair; p; p = p->next) { + prophlen = sizeof(struct isakmp_pl_p) + + p->prop->spi_size; + trnslen = ntohs(p->trns->h.len); + + if (np_p) + *np_p = ISAKMP_NPTYPE_P; + + /* create proposal */ + + memcpy(bp, p->prop, prophlen); + ((struct isakmp_pl_p *)bp)->h.np = ISAKMP_NPTYPE_NONE; + ((struct isakmp_pl_p *)bp)->h.len = htons(prophlen + trnslen); + ((struct isakmp_pl_p *)bp)->num_t = 1; + np_p = &((struct isakmp_pl_p *)bp)->h.np; + memset(bp + sizeof(struct isakmp_pl_p), 0, p->prop->spi_size); + bp += prophlen; + + /* create transform */ + memcpy(bp, p->trns, trnslen); + ((struct isakmp_pl_t *)bp)->h.np = ISAKMP_NPTYPE_NONE; + ((struct isakmp_pl_t *)bp)->h.len = htons(trnslen); + bp += trnslen; + } + + return newsa; +} + +/* + * update responder's spi + */ +int +ipsecdoi_updatespi(iph2) + struct ph2handle *iph2; +{ + struct prop_pair **pair, *p; + struct saprop *pp; + struct saproto *pr; + int i; + int error = -1; + u_int8_t *spi; + + pair = get_proppair(iph2->sa_ret, IPSECDOI_TYPE_PH2); + if (pair == NULL) + return -1; + for (i = 0; i < MAXPROPPAIRLEN; i++) { + if (pair[i]) + break; + } + if (i == MAXPROPPAIRLEN || pair[i]->tnext) { + /* multiple transform must be filtered by selectph2proposal.*/ + goto end; + } + + pp = iph2->approval; + + /* create proposal payloads */ + for (p = pair[i]; p; p = p->next) { + /* + * find a proposal/transform with matching proto_id/t_id. + * we have analyzed validity already, in cmpsaprop_alloc(). + */ + for (pr = pp->head; pr; pr = pr->next) { + if (p->prop->proto_id == pr->proto_id && + p->trns->t_id == pr->head->trns_id) { + break; + } + } + if (!pr) + goto end; + + /* + * XXX SPI bits are left-filled, for use with IPComp. + * we should be switching to variable-length spi field... + */ + spi = (u_int8_t *)&pr->spi; + spi += sizeof(pr->spi); + spi -= pr->spisize; + memcpy((caddr_t)p->prop + sizeof(*p->prop), spi, pr->spisize); + } + + error = 0; +end: + free_proppair(pair); + return error; +} + +/* + * make a new SA payload from prop_pair. + */ +vchar_t * +get_sabysaprop(pp0, sa0) + struct saprop *pp0; + vchar_t *sa0; +{ + struct prop_pair **pair = NULL; + vchar_t *newsa = NULL; + int newtlen; + u_int8_t *np_p = NULL; + struct prop_pair *p = NULL; + struct saprop *pp; + struct saproto *pr; + struct satrns *tr; + int prophlen, trnslen; + caddr_t bp; + int error = -1; + + /* get proposal pair */ + pair = get_proppair(sa0, IPSECDOI_TYPE_PH2); + if (pair == NULL) + goto out; + + newtlen = sizeof(struct ipsecdoi_sa_b); + for (pp = pp0; pp; pp = pp->next) { + + if (pair[pp->prop_no] == NULL) + goto out; + + for (pr = pp->head; pr; pr = pr->next) { + newtlen += (sizeof(struct isakmp_pl_p) + + pr->spisize); + + for (tr = pr->head; tr; tr = tr->next) { + for (p = pair[pp->prop_no]; p; p = p->tnext) { + if (tr->trns_no == p->trns->t_no) + break; + } + if (p == NULL) + goto out; + + newtlen += ntohs(p->trns->h.len); + } + } + } + + newsa = vmalloc(newtlen); + if (newsa == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "failed to get newsa.\n"); + goto out; + } + bp = newsa->v; + + /* some of values of SA must be updated in the out of this function */ + ((struct isakmp_gen *)bp)->len = htons(newtlen); + bp += sizeof(struct ipsecdoi_sa_b); + + /* create proposal payloads */ + for (pp = pp0; pp; pp = pp->next) { + + for (pr = pp->head; pr; pr = pr->next) { + prophlen = sizeof(struct isakmp_pl_p) + + p->prop->spi_size; + + for (tr = pr->head; tr; tr = tr->next) { + for (p = pair[pp->prop_no]; p; p = p->tnext) { + if (tr->trns_no == p->trns->t_no) + break; + } + if (p == NULL) + goto out; + + trnslen = ntohs(p->trns->h.len); + + if (np_p) + *np_p = ISAKMP_NPTYPE_P; + + /* create proposal */ + + memcpy(bp, p->prop, prophlen); + ((struct isakmp_pl_p *)bp)->h.np = ISAKMP_NPTYPE_NONE; + ((struct isakmp_pl_p *)bp)->h.len = htons(prophlen + trnslen); + ((struct isakmp_pl_p *)bp)->num_t = 1; + np_p = &((struct isakmp_pl_p *)bp)->h.np; + bp += prophlen; + + /* create transform */ + memcpy(bp, p->trns, trnslen); + ((struct isakmp_pl_t *)bp)->h.np = ISAKMP_NPTYPE_NONE; + ((struct isakmp_pl_t *)bp)->h.len = htons(trnslen); + bp += trnslen; + } + } + } + + error = 0; +out: + if (pair != NULL) + racoon_free(pair); + + if (error != 0) { + if (newsa != NULL) { + vfree(newsa); + newsa = NULL; + } + } + + return newsa; +} + +/* + * If some error happens then return 0. Although 0 means that lifetime is zero, + * such a value should not be accepted. + * Also 0 of lifebyte should not be included in a packet although 0 means not + * to care of it. + */ +static u_int32_t +ipsecdoi_set_ld(buf) + vchar_t *buf; +{ + u_int32_t ld; + + if (buf == 0) + return 0; + + switch (buf->l) { + case 2: + ld = ntohs(*(u_int16_t *)buf->v); + break; + case 4: + ld = ntohl(*(u_int32_t *)buf->v); + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "length %zu of life duration " + "isn't supported.\n", buf->l); + return 0; + } + + return ld; +} + +/* + * parse responder-lifetime attributes from payload + */ +int +ipsecdoi_parse_responder_lifetime(notify, lifetime_sec, lifetime_kb) + struct isakmp_pl_n *notify; + u_int32_t *lifetime_sec; + u_int32_t *lifetime_kb; +{ + struct isakmp_data *d; + int flag, type, tlen, ld_type = -1; + u_int16_t lorv; + u_int32_t value; + + tlen = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size; + d = (struct isakmp_data *)((char *)(notify + 1) + + notify->spi_size); + + while (tlen >= sizeof(struct isakmp_data)) { + type = ntohs(d->type) & ~ISAKMP_GEN_MASK; + flag = ntohs(d->type) & ISAKMP_GEN_MASK; + lorv = ntohs(d->lorv); + + plog(LLV_DEBUG, LOCATION, NULL, + "type=%s, flag=0x%04x, lorv=%s\n", + s_ipsecdoi_attr(type), flag, + s_ipsecdoi_attr_v(type, lorv)); + + switch (type) { + case IPSECDOI_ATTR_SA_LD_TYPE: + if (! flag) { + plog(LLV_ERROR, LOCATION, NULL, + "must be TV when LD_TYPE.\n"); + return -1; + } + ld_type = lorv; + break; + case IPSECDOI_ATTR_SA_LD: + if (flag) + value = lorv; + else if (lorv == 2) + value = ntohs(*(u_int16_t *)(d + 1)); + else if (lorv == 4) + value = ntohl(*(u_int32_t *)(d + 1)); + else { + plog(LLV_ERROR, LOCATION, NULL, + "payload length %d for lifetime " + "data length is unsupported.\n", lorv); + return -1; + } + + switch (ld_type) { + case IPSECDOI_ATTR_SA_LD_TYPE_SEC: + if (lifetime_sec != NULL) + *lifetime_sec = value; + plog(LLV_INFO, LOCATION, NULL, + "received RESPONDER-LIFETIME: %d " + "seconds\n", value); + break; + case IPSECDOI_ATTR_SA_LD_TYPE_KB: + if (lifetime_kb != NULL) + *lifetime_kb = value; + plog(LLV_INFO, LOCATION, NULL, + "received RESPONDER-LIFETIME: %d " + "kbytes\n", value); + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "lifetime data received without " + "lifetime data type.\n"); + return -1; + } + break; + } + + if (flag) { + tlen -= sizeof(*d); + d = (struct isakmp_data *)((char *)d + + sizeof(*d)); + } else { + tlen -= (sizeof(*d) + lorv); + d = (struct isakmp_data *)((char *)d + + sizeof(*d) + lorv); + } + } + + return 0; +} + + +/*%%%*/ +/* + * check DOI + */ +static int +check_doi(doi) + u_int32_t doi; +{ + switch (doi) { + case IPSEC_DOI: + return 0; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid value of DOI 0x%08x.\n", doi); + return -1; + } + /* NOT REACHED */ +} + +/* + * check situation + */ +static int +check_situation(sit) + u_int32_t sit; +{ + switch (sit) { + case IPSECDOI_SIT_IDENTITY_ONLY: + return 0; + + case IPSECDOI_SIT_SECRECY: + case IPSECDOI_SIT_INTEGRITY: + plog(LLV_ERROR, LOCATION, NULL, + "situation 0x%08x unsupported yet.\n", sit); + return -1; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid situation 0x%08x.\n", sit); + return -1; + } + /* NOT REACHED */ +} + +/* + * check protocol id in main mode + */ +static int +check_prot_main(proto_id) + int proto_id; +{ + switch (proto_id) { + case IPSECDOI_PROTO_ISAKMP: + return 0; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "Illegal protocol id=%u.\n", proto_id); + return -1; + } + /* NOT REACHED */ +} + +/* + * check protocol id in quick mode + */ +static int +check_prot_quick(proto_id) + int proto_id; +{ + switch (proto_id) { + case IPSECDOI_PROTO_IPSEC_AH: + case IPSECDOI_PROTO_IPSEC_ESP: + return 0; + + case IPSECDOI_PROTO_IPCOMP: + return 0; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid protocol id %d.\n", proto_id); + return -1; + } + /* NOT REACHED */ +} + +static int +check_spi_size(proto_id, size) + int proto_id, size; +{ + switch (proto_id) { + case IPSECDOI_PROTO_ISAKMP: + if (size != 0) { + /* WARNING */ + plog(LLV_WARNING, LOCATION, NULL, + "SPI size isn't zero, but IKE proposal.\n"); + } + return 0; + + case IPSECDOI_PROTO_IPSEC_AH: + case IPSECDOI_PROTO_IPSEC_ESP: + if (size != 4) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid SPI size=%d for IPSEC proposal.\n", + size); + return -1; + } + return 0; + + case IPSECDOI_PROTO_IPCOMP: + if (size != 2 && size != 4) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid SPI size=%d for IPCOMP proposal.\n", + size); + return -1; + } + return 0; + + default: + /* ??? */ + return -1; + } + /* NOT REACHED */ +} + +/* + * check transform ID in ISAKMP. + */ +static int +check_trns_isakmp(t_id) + int t_id; +{ + switch (t_id) { + case IPSECDOI_KEY_IKE: + return 0; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid transform-id=%u in proto_id=%u.\n", + t_id, IPSECDOI_KEY_IKE); + return -1; + } + /* NOT REACHED */ +} + +/* + * check transform ID in AH. + */ +static int +check_trns_ah(t_id) + int t_id; +{ + switch (t_id) { + case IPSECDOI_AH_MD5: + case IPSECDOI_AH_SHA: + case IPSECDOI_AH_SHA256: + case IPSECDOI_AH_SHA384: + case IPSECDOI_AH_SHA512: + return 0; + case IPSECDOI_AH_DES: + plog(LLV_ERROR, LOCATION, NULL, + "not support transform-id=%u in AH.\n", t_id); + return -1; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid transform-id=%u in AH.\n", t_id); + return -1; + } + /* NOT REACHED */ +} + +/* + * check transform ID in ESP. + */ +static int +check_trns_esp(t_id) + int t_id; +{ + switch (t_id) { + case IPSECDOI_ESP_DES: + case IPSECDOI_ESP_3DES: + case IPSECDOI_ESP_NULL: + case IPSECDOI_ESP_RC5: + case IPSECDOI_ESP_CAST: + case IPSECDOI_ESP_BLOWFISH: + case IPSECDOI_ESP_AES: + case IPSECDOI_ESP_TWOFISH: + case IPSECDOI_ESP_CAMELLIA: + return 0; + case IPSECDOI_ESP_DES_IV32: + case IPSECDOI_ESP_DES_IV64: + case IPSECDOI_ESP_IDEA: + case IPSECDOI_ESP_3IDEA: + case IPSECDOI_ESP_RC4: + plog(LLV_ERROR, LOCATION, NULL, + "not support transform-id=%u in ESP.\n", t_id); + return -1; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid transform-id=%u in ESP.\n", t_id); + return -1; + } + /* NOT REACHED */ +} + +/* + * check transform ID in IPCOMP. + */ +static int +check_trns_ipcomp(t_id) + int t_id; +{ + switch (t_id) { + case IPSECDOI_IPCOMP_OUI: + case IPSECDOI_IPCOMP_DEFLATE: + case IPSECDOI_IPCOMP_LZS: + return 0; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid transform-id=%u in IPCOMP.\n", t_id); + return -1; + } + /* NOT REACHED */ +} + +/* + * check data attributes in IKE. + */ +static int +check_attr_isakmp(trns) + struct isakmp_pl_t *trns; +{ + struct isakmp_data *d; + int tlen; + int flag, type; + u_int16_t lorv; + + tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t); + d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t)); + + while (tlen > 0) { + type = ntohs(d->type) & ~ISAKMP_GEN_MASK; + flag = ntohs(d->type) & ISAKMP_GEN_MASK; + lorv = ntohs(d->lorv); + + plog(LLV_DEBUG, LOCATION, NULL, + "type=%s, flag=0x%04x, lorv=%s\n", + s_oakley_attr(type), flag, + s_oakley_attr_v(type, lorv)); + + /* + * some of the attributes must be encoded in TV. + * see RFC2409 Appendix A "Attribute Classes". + */ + switch (type) { + case OAKLEY_ATTR_ENC_ALG: + case OAKLEY_ATTR_HASH_ALG: + case OAKLEY_ATTR_AUTH_METHOD: + case OAKLEY_ATTR_GRP_DESC: + case OAKLEY_ATTR_GRP_TYPE: + case OAKLEY_ATTR_SA_LD_TYPE: + case OAKLEY_ATTR_PRF: + case OAKLEY_ATTR_KEY_LEN: + case OAKLEY_ATTR_FIELD_SIZE: + if (!flag) { /* TLV*/ + plog(LLV_ERROR, LOCATION, NULL, + "oakley attribute %d must be TV.\n", + type); + return -1; + } + break; + } + + /* sanity check for TLV. length must be specified. */ + if (!flag && lorv == 0) { /*TLV*/ + plog(LLV_ERROR, LOCATION, NULL, + "invalid length %d for TLV attribute %d.\n", + lorv, type); + return -1; + } + + switch (type) { + case OAKLEY_ATTR_ENC_ALG: + if (!alg_oakley_encdef_ok(lorv)) { + plog(LLV_ERROR, LOCATION, NULL, + "invalied encryption algorithm=%d.\n", + lorv); + return -1; + } + break; + + case OAKLEY_ATTR_HASH_ALG: + if (!alg_oakley_hashdef_ok(lorv)) { + plog(LLV_ERROR, LOCATION, NULL, + "invalied hash algorithm=%d.\n", + lorv); + return -1; + } + break; + + case OAKLEY_ATTR_AUTH_METHOD: + switch (lorv) { + case OAKLEY_ATTR_AUTH_METHOD_PSKEY: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: +#endif +#if defined(ENABLE_HYBRID) || defined(HAVE_GSSAPI) + /* These two authentication method IDs overlap. */ + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + /*case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:*/ +#endif + break; + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif + case OAKLEY_ATTR_AUTH_METHOD_RSAENC: + case OAKLEY_ATTR_AUTH_METHOD_RSAREV: + plog(LLV_ERROR, LOCATION, NULL, + "auth method %s isn't supported.\n", + s_oakley_attr_method(lorv)); + return -1; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid auth method %d.\n", + lorv); + return -1; + } + break; + + case OAKLEY_ATTR_GRP_DESC: + if (!alg_oakley_dhdef_ok(lorv)) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid DH group %d.\n", + lorv); + return -1; + } + break; + + case OAKLEY_ATTR_GRP_TYPE: + switch (lorv) { + case OAKLEY_ATTR_GRP_TYPE_MODP: + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "unsupported DH group type %d.\n", + lorv); + return -1; + } + break; + + case OAKLEY_ATTR_GRP_PI: + case OAKLEY_ATTR_GRP_GEN_ONE: + /* sanity checks? */ + break; + + case OAKLEY_ATTR_GRP_GEN_TWO: + case OAKLEY_ATTR_GRP_CURVE_A: + case OAKLEY_ATTR_GRP_CURVE_B: + plog(LLV_ERROR, LOCATION, NULL, + "attr type=%u isn't supported.\n", type); + return -1; + + case OAKLEY_ATTR_SA_LD_TYPE: + switch (lorv) { + case OAKLEY_ATTR_SA_LD_TYPE_SEC: + case OAKLEY_ATTR_SA_LD_TYPE_KB: + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid life type %d.\n", lorv); + return -1; + } + break; + + case OAKLEY_ATTR_SA_LD: + /* should check the value */ + break; + + case OAKLEY_ATTR_PRF: + case OAKLEY_ATTR_KEY_LEN: + break; + + case OAKLEY_ATTR_FIELD_SIZE: + plog(LLV_ERROR, LOCATION, NULL, + "attr type=%u isn't supported.\n", type); + return -1; + + case OAKLEY_ATTR_GRP_ORDER: + break; + + case OAKLEY_ATTR_GSS_ID: + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid attribute type %d.\n", type); + return -1; + } + + if (flag) { + tlen -= sizeof(*d); + d = (struct isakmp_data *)((char *)d + + sizeof(*d)); + } else { + tlen -= (sizeof(*d) + lorv); + d = (struct isakmp_data *)((char *)d + + sizeof(*d) + lorv); + } + } + + return 0; +} + +/* + * check data attributes in IPSEC AH/ESP. + */ +static int +check_attr_ah(trns) + struct isakmp_pl_t *trns; +{ + return check_attr_ipsec(IPSECDOI_PROTO_IPSEC_AH, trns); +} + +static int +check_attr_esp(trns) + struct isakmp_pl_t *trns; +{ + return check_attr_ipsec(IPSECDOI_PROTO_IPSEC_ESP, trns); +} + +static int +check_attr_ipsec(proto_id, trns) + int proto_id; + struct isakmp_pl_t *trns; +{ + struct isakmp_data *d; + int tlen; + int flag, type = 0; + u_int16_t lorv; + int attrseen[16]; /* XXX magic number */ + + tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t); + d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t)); + memset(attrseen, 0, sizeof(attrseen)); + + while (tlen > 0) { + type = ntohs(d->type) & ~ISAKMP_GEN_MASK; + flag = ntohs(d->type) & ISAKMP_GEN_MASK; + lorv = ntohs(d->lorv); + + plog(LLV_DEBUG, LOCATION, NULL, + "type=%s, flag=0x%04x, lorv=%s\n", + s_ipsecdoi_attr(type), flag, + s_ipsecdoi_attr_v(type, lorv)); + + if (type < sizeof(attrseen)/sizeof(attrseen[0])) + attrseen[type]++; + + switch (type) { + case IPSECDOI_ATTR_ENC_MODE: + if (! flag) { + plog(LLV_ERROR, LOCATION, NULL, + "must be TV when ENC_MODE.\n"); + return -1; + } + + switch (lorv) { + case IPSECDOI_ATTR_ENC_MODE_TUNNEL: + case IPSECDOI_ATTR_ENC_MODE_TRNS: + break; +#ifdef ENABLE_NATT + case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC: + case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC: + case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT: + case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT: + plog(LLV_DEBUG, LOCATION, NULL, + "UDP encapsulation requested\n"); + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid encryption mode=%u.\n", + lorv); + return -1; + } + break; + + case IPSECDOI_ATTR_AUTH: + if (! flag) { + plog(LLV_ERROR, LOCATION, NULL, + "must be TV when AUTH.\n"); + return -1; + } + + switch (lorv) { + case IPSECDOI_ATTR_AUTH_HMAC_MD5: + if (proto_id == IPSECDOI_PROTO_IPSEC_AH && + trns->t_id != IPSECDOI_AH_MD5) { +ahmismatch: + plog(LLV_ERROR, LOCATION, NULL, + "auth algorithm %u conflicts " + "with transform %u.\n", + lorv, trns->t_id); + return -1; + } + break; + case IPSECDOI_ATTR_AUTH_HMAC_SHA1: + if (proto_id == IPSECDOI_PROTO_IPSEC_AH) { + if (trns->t_id != IPSECDOI_AH_SHA) + goto ahmismatch; + } + break; + case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256: + if (proto_id == IPSECDOI_PROTO_IPSEC_AH) { + if (trns->t_id != IPSECDOI_AH_SHA256) + goto ahmismatch; + } + break; + case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384: + if (proto_id == IPSECDOI_PROTO_IPSEC_AH) { + if (trns->t_id != IPSECDOI_AH_SHA384) + goto ahmismatch; + } + break; + case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512: + if (proto_id == IPSECDOI_PROTO_IPSEC_AH) { + if (trns->t_id != IPSECDOI_AH_SHA512) + goto ahmismatch; + } + break; + case IPSECDOI_ATTR_AUTH_DES_MAC: + case IPSECDOI_ATTR_AUTH_KPDK: + plog(LLV_ERROR, LOCATION, NULL, + "auth algorithm %u isn't supported.\n", + lorv); + return -1; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid auth algorithm=%u.\n", + lorv); + return -1; + } + break; + + case IPSECDOI_ATTR_SA_LD_TYPE: + if (! flag) { + plog(LLV_ERROR, LOCATION, NULL, + "must be TV when LD_TYPE.\n"); + return -1; + } + + switch (lorv) { + case IPSECDOI_ATTR_SA_LD_TYPE_SEC: + case IPSECDOI_ATTR_SA_LD_TYPE_KB: + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid life type %d.\n", lorv); + return -1; + } + break; + + case IPSECDOI_ATTR_SA_LD: + if (flag) { + /* i.e. ISAKMP_GEN_TV */ + plog(LLV_DEBUG, LOCATION, NULL, + "life duration was in TLV.\n"); + } else { + /* i.e. ISAKMP_GEN_TLV */ + if (lorv == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid length of LD\n"); + return -1; + } + } + break; + + case IPSECDOI_ATTR_GRP_DESC: + if (! flag) { + plog(LLV_ERROR, LOCATION, NULL, + "must be TV when GRP_DESC.\n"); + return -1; + } + + if (!alg_oakley_dhdef_ok(lorv)) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid group description=%u.\n", + lorv); + return -1; + } + break; + + case IPSECDOI_ATTR_KEY_LENGTH: + if (! flag) { + plog(LLV_ERROR, LOCATION, NULL, + "must be TV when KEY_LENGTH.\n"); + return -1; + } + break; + +#ifdef HAVE_SECCTX + case IPSECDOI_ATTR_SECCTX: + if (flag) { + plog(LLV_ERROR, LOCATION, NULL, + "SECCTX must be in TLV.\n"); + return -1; + } + break; +#endif + + case IPSECDOI_ATTR_KEY_ROUNDS: + case IPSECDOI_ATTR_COMP_DICT_SIZE: + case IPSECDOI_ATTR_COMP_PRIVALG: + plog(LLV_ERROR, LOCATION, NULL, + "attr type=%u isn't supported.\n", type); + return -1; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid attribute type %d.\n", type); + return -1; + } + + if (flag) { + tlen -= sizeof(*d); + d = (struct isakmp_data *)((char *)d + + sizeof(*d)); + } else { + tlen -= (sizeof(*d) + lorv); + d = (struct isakmp_data *)((caddr_t)d + + sizeof(*d) + lorv); + } + } + + if (proto_id == IPSECDOI_PROTO_IPSEC_AH && + !attrseen[IPSECDOI_ATTR_AUTH]) { + plog(LLV_ERROR, LOCATION, NULL, + "attr AUTH must be present for AH.\n"); + return -1; + } + + if (proto_id == IPSECDOI_PROTO_IPSEC_ESP && + trns->t_id == IPSECDOI_ESP_NULL && + !attrseen[IPSECDOI_ATTR_AUTH]) { + plog(LLV_ERROR, LOCATION, NULL, + "attr AUTH must be present for ESP NULL encryption.\n"); + return -1; + } + + return 0; +} + +static int +check_attr_ipcomp(trns) + struct isakmp_pl_t *trns; +{ + struct isakmp_data *d; + int tlen; + int flag, type = 0; + u_int16_t lorv; + int attrseen[16]; /* XXX magic number */ + + tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t); + d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t)); + memset(attrseen, 0, sizeof(attrseen)); + + while (tlen > 0) { + type = ntohs(d->type) & ~ISAKMP_GEN_MASK; + flag = ntohs(d->type) & ISAKMP_GEN_MASK; + lorv = ntohs(d->lorv); + + plog(LLV_DEBUG, LOCATION, NULL, + "type=%d, flag=0x%04x, lorv=0x%04x\n", + type, flag, lorv); + + if (type < sizeof(attrseen)/sizeof(attrseen[0])) + attrseen[type]++; + + switch (type) { + case IPSECDOI_ATTR_ENC_MODE: + if (! flag) { + plog(LLV_ERROR, LOCATION, NULL, + "must be TV when ENC_MODE.\n"); + return -1; + } + + switch (lorv) { + case IPSECDOI_ATTR_ENC_MODE_TUNNEL: + case IPSECDOI_ATTR_ENC_MODE_TRNS: + break; +#ifdef ENABLE_NATT + case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC: + case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC: + case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT: + case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT: + plog(LLV_DEBUG, LOCATION, NULL, + "UDP encapsulation requested\n"); + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid encryption mode=%u.\n", + lorv); + return -1; + } + break; + + case IPSECDOI_ATTR_SA_LD_TYPE: + if (! flag) { + plog(LLV_ERROR, LOCATION, NULL, + "must be TV when LD_TYPE.\n"); + return -1; + } + + switch (lorv) { + case IPSECDOI_ATTR_SA_LD_TYPE_SEC: + case IPSECDOI_ATTR_SA_LD_TYPE_KB: + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid life type %d.\n", lorv); + return -1; + } + break; + + case IPSECDOI_ATTR_SA_LD: + if (flag) { + /* i.e. ISAKMP_GEN_TV */ + plog(LLV_DEBUG, LOCATION, NULL, + "life duration was in TLV.\n"); + } else { + /* i.e. ISAKMP_GEN_TLV */ + if (lorv == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid length of LD\n"); + return -1; + } + } + break; + + case IPSECDOI_ATTR_GRP_DESC: + if (! flag) { + plog(LLV_ERROR, LOCATION, NULL, + "must be TV when GRP_DESC.\n"); + return -1; + } + + if (!alg_oakley_dhdef_ok(lorv)) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid group description=%u.\n", + lorv); + return -1; + } + break; + + case IPSECDOI_ATTR_AUTH: + plog(LLV_ERROR, LOCATION, NULL, + "invalid attr type=%u.\n", type); + return -1; + + case IPSECDOI_ATTR_KEY_LENGTH: + case IPSECDOI_ATTR_KEY_ROUNDS: + case IPSECDOI_ATTR_COMP_DICT_SIZE: + case IPSECDOI_ATTR_COMP_PRIVALG: + plog(LLV_ERROR, LOCATION, NULL, + "attr type=%u isn't supported.\n", type); + return -1; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid attribute type %d.\n", type); + return -1; + } + + if (flag) { + tlen -= sizeof(*d); + d = (struct isakmp_data *)((char *)d + + sizeof(*d)); + } else { + tlen -= (sizeof(*d) + lorv); + d = (struct isakmp_data *)((caddr_t)d + + sizeof(*d) + lorv); + } + } + +#if 0 + if (proto_id == IPSECDOI_PROTO_IPCOMP && + !attrseen[IPSECDOI_ATTR_AUTH]) { + plog(LLV_ERROR, LOCATION, NULL, + "attr AUTH must be present for AH.\n", type); + return -1; + } +#endif + + return 0; +} + +/* %%% */ +/* + * create phase1 proposal from remote configuration. + * NOT INCLUDING isakmp general header of SA payload + */ +vchar_t * +ipsecdoi_setph1proposal(rmconf, props) + struct remoteconf *rmconf; + struct isakmpsa *props; +{ + vchar_t *mysa; + int sablen; + + /* count total size of SA minus isakmp general header */ + /* not including isakmp general header of SA payload */ + sablen = sizeof(struct ipsecdoi_sa_b); + sablen += setph1prop(props, NULL); + + mysa = vmalloc(sablen); + if (mysa == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate my sa buffer\n"); + return NULL; + } + + /* create SA payload */ + /* not including isakmp general header */ + ((struct ipsecdoi_sa_b *)mysa->v)->doi = htonl(rmconf->doitype); + ((struct ipsecdoi_sa_b *)mysa->v)->sit = htonl(rmconf->sittype); + + (void)setph1prop(props, mysa->v + sizeof(struct ipsecdoi_sa_b)); + + return mysa; +} + +static int +setph1prop(props, buf) + struct isakmpsa *props; + caddr_t buf; +{ + struct isakmp_pl_p *prop = NULL; + struct isakmpsa *s = NULL; + int proplen, trnslen; + u_int8_t *np_t; /* pointer next trns type in previous header */ + int trns_num; + caddr_t p = buf; + + proplen = sizeof(*prop); + if (buf) { + /* create proposal */ + prop = (struct isakmp_pl_p *)p; + prop->h.np = ISAKMP_NPTYPE_NONE; + prop->p_no = props->prop_no; + prop->proto_id = IPSECDOI_PROTO_ISAKMP; + prop->spi_size = 0; + p += sizeof(*prop); + } + + np_t = NULL; + trns_num = 0; + + for (s = props; s != NULL; s = s->next) { + if (np_t) + *np_t = ISAKMP_NPTYPE_T; + + trnslen = setph1trns(s, p); + proplen += trnslen; + if (buf) { + /* save buffer to pre-next payload */ + np_t = &((struct isakmp_pl_t *)p)->h.np; + p += trnslen; + + /* count up transform length */ + trns_num++; + } + } + + /* update proposal length */ + if (buf) { + prop->h.len = htons(proplen); + prop->num_t = trns_num; + } + + return proplen; +} + +static int +setph1trns(sa, buf) + struct isakmpsa *sa; + caddr_t buf; +{ + struct isakmp_pl_t *trns = NULL; + int trnslen, attrlen; + caddr_t p = buf; + + trnslen = sizeof(*trns); + if (buf) { + /* create transform */ + trns = (struct isakmp_pl_t *)p; + trns->h.np = ISAKMP_NPTYPE_NONE; + trns->t_no = sa->trns_no; + trns->t_id = IPSECDOI_KEY_IKE; + p += sizeof(*trns); + } + + attrlen = setph1attr(sa, p); + trnslen += attrlen; + if (buf) + p += attrlen; + + if (buf) + trns->h.len = htons(trnslen); + + return trnslen; +} + +static int +setph1attr(sa, buf) + struct isakmpsa *sa; + caddr_t buf; +{ + caddr_t p = buf; + int attrlen = 0; + + if (sa->lifetime) { + u_int32_t lifetime = htonl((u_int32_t)sa->lifetime); + + attrlen += sizeof(struct isakmp_data) + + sizeof(struct isakmp_data); + if (sa->lifetime > 0xffff) + attrlen += sizeof(lifetime); + if (buf) { + p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD_TYPE, + OAKLEY_ATTR_SA_LD_TYPE_SEC); + if (sa->lifetime > 0xffff) { + p = isakmp_set_attr_v(p, OAKLEY_ATTR_SA_LD, + (caddr_t)&lifetime, + sizeof(lifetime)); + } else { + p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD, + sa->lifetime); + } + } + } + + if (sa->lifebyte) { + u_int32_t lifebyte = htonl((u_int32_t)sa->lifebyte); + + attrlen += sizeof(struct isakmp_data) + + sizeof(struct isakmp_data); + if (sa->lifebyte > 0xffff) + attrlen += sizeof(lifebyte); + if (buf) { + p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD_TYPE, + OAKLEY_ATTR_SA_LD_TYPE_KB); + if (sa->lifebyte > 0xffff) { + p = isakmp_set_attr_v(p, OAKLEY_ATTR_SA_LD, + (caddr_t)&lifebyte, + sizeof(lifebyte)); + } else { + p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD, + sa->lifebyte); + } + } + } + + if (sa->enctype) { + attrlen += sizeof(struct isakmp_data); + if (buf) + p = isakmp_set_attr_l(p, OAKLEY_ATTR_ENC_ALG, sa->enctype); + } + if (sa->encklen) { + attrlen += sizeof(struct isakmp_data); + if (buf) + p = isakmp_set_attr_l(p, OAKLEY_ATTR_KEY_LEN, sa->encklen); + } + if (sa->authmethod) { + int authmethod; + + authmethod = isakmpsa_switch_authmethod(sa->authmethod); + authmethod &= 0xffff; + attrlen += sizeof(struct isakmp_data); + if (buf) + p = isakmp_set_attr_l(p, OAKLEY_ATTR_AUTH_METHOD, authmethod); + } + if (sa->hashtype) { + attrlen += sizeof(struct isakmp_data); + if (buf) + p = isakmp_set_attr_l(p, OAKLEY_ATTR_HASH_ALG, sa->hashtype); + } + switch (sa->dh_group) { + case OAKLEY_ATTR_GRP_DESC_MODP768: + case OAKLEY_ATTR_GRP_DESC_MODP1024: + case OAKLEY_ATTR_GRP_DESC_MODP1536: + case OAKLEY_ATTR_GRP_DESC_MODP2048: + case OAKLEY_ATTR_GRP_DESC_MODP3072: + case OAKLEY_ATTR_GRP_DESC_MODP4096: + case OAKLEY_ATTR_GRP_DESC_MODP6144: + case OAKLEY_ATTR_GRP_DESC_MODP8192: + /* don't attach group type for known groups */ + attrlen += sizeof(struct isakmp_data); + if (buf) { + p = isakmp_set_attr_l(p, OAKLEY_ATTR_GRP_DESC, + sa->dh_group); + } + break; + case OAKLEY_ATTR_GRP_DESC_EC2N155: + case OAKLEY_ATTR_GRP_DESC_EC2N185: + /* don't attach group type for known groups */ + attrlen += sizeof(struct isakmp_data); + if (buf) { + p = isakmp_set_attr_l(p, OAKLEY_ATTR_GRP_TYPE, + OAKLEY_ATTR_GRP_TYPE_EC2N); + } + break; + case 0: + default: + break; + } + +#ifdef HAVE_GSSAPI + if (sa->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && + sa->gssid != NULL) { + attrlen += sizeof(struct isakmp_data); + /* + * Older versions of racoon just placed the ISO-Latin-1 + * string on the wire directly. Check to see if we are + * configured to be compatible with this behavior. Otherwise, + * we encode the GSS ID as UTF-16LE for Windows 2000 + * compatibility, which requires twice the number of octets. + */ + if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) + attrlen += sa->gssid->l; + else + attrlen += sa->gssid->l * 2; + if (buf) { + plog(LLV_DEBUG, LOCATION, NULL, "gss id attr: len %zu, " + "val '%.*s'\n", sa->gssid->l, (int)sa->gssid->l, + sa->gssid->v); + if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) { + p = isakmp_set_attr_v(p, OAKLEY_ATTR_GSS_ID, + (caddr_t)sa->gssid->v, + sa->gssid->l); + } else { + size_t dstleft = sa->gssid->l * 2; + size_t srcleft = sa->gssid->l; + const char *src = (const char *)sa->gssid->v; + char *odst, *dst = racoon_malloc(dstleft); + iconv_t cd; + size_t rv; + + cd = iconv_open("utf-16le", "latin1"); + if (cd == (iconv_t) -1) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to initialize " + "latin1 -> utf-16le " + "converstion descriptor: %s\n", + strerror(errno)); + attrlen -= sa->gssid->l * 2; + goto gssid_done; + } + odst = dst; + rv = iconv(cd, (__iconv_const char **)&src, + &srcleft, &dst, &dstleft); + if (rv != 0) { + if (rv == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to convert GSS ID " + "from latin1 -> utf-16le: " + "%s\n", strerror(errno)); + } else { + /* should never happen */ + plog(LLV_ERROR, LOCATION, NULL, + "%zd character%s in GSS ID " + "cannot be represented " + "in utf-16le\n", + rv, rv == 1 ? "" : "s"); + } + (void) iconv_close(cd); + attrlen -= sa->gssid->l * 2; + goto gssid_done; + } + (void) iconv_close(cd); + + /* XXX Check srcleft and dstleft? */ + + p = isakmp_set_attr_v(p, OAKLEY_ATTR_GSS_ID, + odst, sa->gssid->l * 2); + + racoon_free(odst); + } + } + } + gssid_done: +#endif /* HAVE_GSSAPI */ + + return attrlen; +} + +static vchar_t * +setph2proposal0(iph2, pp, pr) + const struct ph2handle *iph2; + const struct saprop *pp; + const struct saproto *pr; +{ + vchar_t *p; + struct isakmp_pl_p *prop; + struct isakmp_pl_t *trns; + struct satrns *tr; + int attrlen; + size_t trnsoff; + caddr_t x0, x; + u_int8_t *np_t; /* pointer next trns type in previous header */ + const u_int8_t *spi; +#ifdef HAVE_SECCTX + int truectxlen = 0; +#endif + + p = vmalloc(sizeof(*prop) + sizeof(pr->spi)); + if (p == NULL) + return NULL; + + /* create proposal */ + prop = (struct isakmp_pl_p *)p->v; + prop->h.np = ISAKMP_NPTYPE_NONE; + prop->p_no = pp->prop_no; + prop->proto_id = pr->proto_id; + prop->num_t = 1; + + spi = (const u_int8_t *)&pr->spi; + switch (pr->proto_id) { + case IPSECDOI_PROTO_IPCOMP: + /* + * draft-shacham-ippcp-rfc2393bis-05.txt: + * construct 16bit SPI (CPI). + * XXX we may need to provide a configuration option to + * generate 32bit SPI. otherwise we cannot interoeprate + * with nodes that uses 32bit SPI, in case we are initiator. + */ + prop->spi_size = sizeof(u_int16_t); + spi += sizeof(pr->spi) - sizeof(u_int16_t); + p->l -= sizeof(pr->spi); + p->l += sizeof(u_int16_t); + break; + default: + prop->spi_size = sizeof(pr->spi); + break; + } + memcpy(prop + 1, spi, prop->spi_size); + + /* create transform */ + trnsoff = sizeof(*prop) + prop->spi_size; + np_t = NULL; + + for (tr = pr->head; tr; tr = tr->next) { + + switch (pr->proto_id) { + case IPSECDOI_PROTO_IPSEC_ESP: + /* + * don't build a null encryption + * with no authentication transform. + */ + if (tr->trns_id == IPSECDOI_ESP_NULL && + tr->authtype == IPSECDOI_ATTR_AUTH_NONE) + continue; + break; + } + + if (np_t) { + *np_t = ISAKMP_NPTYPE_T; + prop->num_t++; + } + + /* get attribute length */ + attrlen = 0; + if (pp->lifetime) { + attrlen += sizeof(struct isakmp_data) + + sizeof(struct isakmp_data); + if (pp->lifetime > 0xffff) + attrlen += sizeof(u_int32_t); + } + if (pp->lifebyte && pp->lifebyte != IPSECDOI_ATTR_SA_LD_KB_MAX) { + attrlen += sizeof(struct isakmp_data) + + sizeof(struct isakmp_data); + if (pp->lifebyte > 0xffff) + attrlen += sizeof(u_int32_t); + } + attrlen += sizeof(struct isakmp_data); /* enc mode */ + if (tr->encklen) + attrlen += sizeof(struct isakmp_data); + + switch (pr->proto_id) { + case IPSECDOI_PROTO_IPSEC_ESP: + /* non authentication mode ? */ + if (tr->authtype != IPSECDOI_ATTR_AUTH_NONE) + attrlen += sizeof(struct isakmp_data); + break; + case IPSECDOI_PROTO_IPSEC_AH: + if (tr->authtype == IPSECDOI_ATTR_AUTH_NONE) { + plog(LLV_ERROR, LOCATION, NULL, + "no authentication algorithm found " + "but protocol is AH.\n"); + vfree(p); + return NULL; + } + attrlen += sizeof(struct isakmp_data); + break; + case IPSECDOI_PROTO_IPCOMP: + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid protocol: %d\n", pr->proto_id); + vfree(p); + return NULL; + } + + if (alg_oakley_dhdef_ok(iph2->sainfo->pfs_group)) + attrlen += sizeof(struct isakmp_data); + +#ifdef HAVE_SECCTX + /* ctx_str is defined as char ctx_str[MAX_CTXSTR_SIZ]. + * The string may be smaller than MAX_CTXSTR_SIZ. + */ + if (*pp->sctx.ctx_str) { + truectxlen = sizeof(struct security_ctx) - + (MAX_CTXSTR_SIZE - pp->sctx.ctx_strlen); + attrlen += sizeof(struct isakmp_data) + truectxlen; + } +#endif /* HAVE_SECCTX */ + + p = vrealloc(p, p->l + sizeof(*trns) + attrlen); + if (p == NULL) + return NULL; + prop = (struct isakmp_pl_p *)p->v; + + /* set transform's values */ + trns = (struct isakmp_pl_t *)(p->v + trnsoff); + trns->h.np = ISAKMP_NPTYPE_NONE; + trns->t_no = tr->trns_no; + trns->t_id = tr->trns_id; + + /* set attributes */ + x = x0 = p->v + trnsoff + sizeof(*trns); + + if (pp->lifetime) { + x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD_TYPE, + IPSECDOI_ATTR_SA_LD_TYPE_SEC); + if (pp->lifetime > 0xffff) { + u_int32_t v = htonl((u_int32_t)pp->lifetime); + x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SA_LD, + (caddr_t)&v, sizeof(v)); + } else { + x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD, + pp->lifetime); + } + } + + if (pp->lifebyte && pp->lifebyte != IPSECDOI_ATTR_SA_LD_KB_MAX) { + x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD_TYPE, + IPSECDOI_ATTR_SA_LD_TYPE_KB); + if (pp->lifebyte > 0xffff) { + u_int32_t v = htonl((u_int32_t)pp->lifebyte); + x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SA_LD, + (caddr_t)&v, sizeof(v)); + } else { + x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD, + pp->lifebyte); + } + } + + x = isakmp_set_attr_l(x, IPSECDOI_ATTR_ENC_MODE, pr->encmode); + + if (tr->encklen) + x = isakmp_set_attr_l(x, IPSECDOI_ATTR_KEY_LENGTH, tr->encklen); + + /* mandatory check has done above. */ + if ((pr->proto_id == IPSECDOI_PROTO_IPSEC_ESP && tr->authtype != IPSECDOI_ATTR_AUTH_NONE) + || pr->proto_id == IPSECDOI_PROTO_IPSEC_AH) + x = isakmp_set_attr_l(x, IPSECDOI_ATTR_AUTH, tr->authtype); + + if (alg_oakley_dhdef_ok(iph2->sainfo->pfs_group)) + x = isakmp_set_attr_l(x, IPSECDOI_ATTR_GRP_DESC, + iph2->sainfo->pfs_group); + +#ifdef HAVE_SECCTX + if (*pp->sctx.ctx_str) { + struct security_ctx secctx; + secctx = pp->sctx; + secctx.ctx_strlen = htons(pp->sctx.ctx_strlen); + x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SECCTX, + (caddr_t)&secctx, truectxlen); + } +#endif + /* update length of this transform. */ + trns = (struct isakmp_pl_t *)(p->v + trnsoff); + trns->h.len = htons(sizeof(*trns) + attrlen); + + /* save buffer to pre-next payload */ + np_t = &trns->h.np; + + trnsoff += (sizeof(*trns) + attrlen); + } + + if (np_t == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no suitable proposal was created.\n"); + return NULL; + } + + /* update length of this protocol. */ + prop->h.len = htons(p->l); + + return p; +} + +/* + * create phase2 proposal from policy configuration. + * NOT INCLUDING isakmp general header of SA payload. + * This function is called by initiator only. + */ +int +ipsecdoi_setph2proposal(iph2) + struct ph2handle *iph2; +{ + struct saprop *proposal, *a; + struct saproto *b = NULL; + vchar_t *q; + struct ipsecdoi_sa_b *sab; + struct isakmp_pl_p *prop; + size_t propoff; /* for previous field of type of next payload. */ + + proposal = iph2->proposal; + + iph2->sa = vmalloc(sizeof(*sab)); + if (iph2->sa == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate my sa buffer\n"); + return -1; + } + + /* create SA payload */ + sab = (struct ipsecdoi_sa_b *)iph2->sa->v; + sab->doi = htonl(IPSEC_DOI); + sab->sit = htonl(IPSECDOI_SIT_IDENTITY_ONLY); /* XXX configurable ? */ + + prop = NULL; + propoff = 0; + for (a = proposal; a; a = a->next) { + for (b = a->head; b; b = b->next) { +#ifdef ENABLE_NATT + if (iph2->ph1->natt_flags & NAT_DETECTED) { + int udp_diff = iph2->ph1->natt_options->mode_udp_diff; + plog (LLV_INFO, LOCATION, NULL, + "NAT detected -> UDP encapsulation " + "(ENC_MODE %d->%d).\n", + b->encmode, + b->encmode+udp_diff); + /* Tunnel -> UDP-Tunnel, Transport -> UDP_Transport */ + b->encmode += udp_diff; + b->udp_encap = 1; + } +#endif + + q = setph2proposal0(iph2, a, b); + if (q == NULL) { + VPTRINIT(iph2->sa); + return -1; + } + + iph2->sa = vrealloc(iph2->sa, iph2->sa->l + q->l); + if (iph2->sa == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate my sa buffer\n"); + if (q) + vfree(q); + return -1; + } + memcpy(iph2->sa->v + iph2->sa->l - q->l, q->v, q->l); + if (propoff != 0) { + prop = (struct isakmp_pl_p *)(iph2->sa->v + + propoff); + prop->h.np = ISAKMP_NPTYPE_P; + } + propoff = iph2->sa->l - q->l; + + vfree(q); + } + } + + return 0; +} + +/* + * return 1 if all of the given protocols are transport mode. + */ +int +ipsecdoi_transportmode(pp) + struct saprop *pp; +{ + struct saproto *pr = NULL; + + for (; pp; pp = pp->next) { + for (pr = pp->head; pr; pr = pr->next) { + if (pr->encmode != IPSECDOI_ATTR_ENC_MODE_TRNS && + pr->encmode != IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC && + pr->encmode != IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT) + return 0; + } + } + + return 1; +} + +int +ipsecdoi_get_defaultlifetime() +{ + return IPSECDOI_ATTR_SA_LD_SEC_DEFAULT; +} + +int +ipsecdoi_checkalgtypes(proto_id, enc, auth, comp) + int proto_id, enc, auth, comp; +{ +#define TMPALGTYPE2STR(n) s_algtype(algclass_ipsec_##n, n) + switch (proto_id) { + case IPSECDOI_PROTO_IPSEC_ESP: + if (enc == 0 || comp != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "illegal algorithm defined " + "ESP enc=%s auth=%s comp=%s.\n", + TMPALGTYPE2STR(enc), + TMPALGTYPE2STR(auth), + TMPALGTYPE2STR(comp)); + return -1; + } + break; + case IPSECDOI_PROTO_IPSEC_AH: + if (enc != 0 || auth == 0 || comp != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "illegal algorithm defined " + "AH enc=%s auth=%s comp=%s.\n", + TMPALGTYPE2STR(enc), + TMPALGTYPE2STR(auth), + TMPALGTYPE2STR(comp)); + return -1; + } + break; + case IPSECDOI_PROTO_IPCOMP: + if (enc != 0 || auth != 0 || comp == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "illegal algorithm defined " + "IPcomp enc=%s auth=%s comp=%s.\n", + TMPALGTYPE2STR(enc), + TMPALGTYPE2STR(auth), + TMPALGTYPE2STR(comp)); + return -1; + } + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid ipsec protocol %d\n", proto_id); + return -1; + } +#undef TMPALGTYPE2STR + return 0; +} + +int +ipproto2doi(proto) + int proto; +{ + switch (proto) { + case IPPROTO_AH: + return IPSECDOI_PROTO_IPSEC_AH; + case IPPROTO_ESP: + return IPSECDOI_PROTO_IPSEC_ESP; + case IPPROTO_IPCOMP: + return IPSECDOI_PROTO_IPCOMP; + } + return -1; /* XXX */ +} + +int +doi2ipproto(proto) + int proto; +{ + switch (proto) { + case IPSECDOI_PROTO_IPSEC_AH: + return IPPROTO_AH; + case IPSECDOI_PROTO_IPSEC_ESP: + return IPPROTO_ESP; + case IPSECDOI_PROTO_IPCOMP: + return IPPROTO_IPCOMP; + } + return -1; /* XXX */ +} + +/* + * Check if a subnet id is valid for comparison + * with an address id ( address length mask ) + * and compare them + * Return value + * = 0 for match + * = 1 for mismatch + */ + +int +ipsecdoi_subnetisaddr_v4( subnet, address ) + const vchar_t *subnet; + const vchar_t *address; +{ + struct in_addr *mask; + + if (address->l != sizeof(struct in_addr)) + return 1; + + if (subnet->l != (sizeof(struct in_addr)*2)) + return 1; + + mask = (struct in_addr*)(subnet->v + sizeof(struct in_addr)); + + if (mask->s_addr!=0xffffffff) + return 1; + + return memcmp(subnet->v,address->v,address->l); +} + +#ifdef INET6 + +int +ipsecdoi_subnetisaddr_v6( subnet, address ) + const vchar_t *subnet; + const vchar_t *address; +{ + struct in6_addr *mask; + int i; + + if (address->l != sizeof(struct in6_addr)) + return 1; + + if (subnet->l != (sizeof(struct in6_addr)*2)) + return 1; + + mask = (struct in6_addr*)(subnet->v + sizeof(struct in6_addr)); + + for (i=0; i<16; i++) + if(mask->s6_addr[i]!=0xff) + return 1; + + return memcmp(subnet->v,address->v,address->l); +} + +#endif + +/* + * Check and Compare two IDs + * - specify 0 for exact if wildcards are allowed + * Return value + * = 0 for match + * = 1 for misatch + * = -1 for integrity error + */ + +int +ipsecdoi_chkcmpids( idt, ids, exact ) + const vchar_t *idt; /* id cmp target */ + const vchar_t *ids; /* id cmp source */ + int exact; +{ + struct ipsecdoi_id_b *id_bt; + struct ipsecdoi_id_b *id_bs; + vchar_t ident_t; + vchar_t ident_s; + int result; + + /* handle wildcard IDs */ + + if (idt == NULL || ids == NULL) + { + if( !exact ) + { + plog(LLV_DEBUG, LOCATION, NULL, + "check and compare ids : values matched (ANONYMOUS)\n" ); + return 0; + } + else + { + plog(LLV_DEBUG, LOCATION, NULL, + "check and compare ids : value mismatch (ANONYMOUS)\n" ); + return -1; + } + } + + /* make sure the ids are of the same type */ + + id_bt = (struct ipsecdoi_id_b *) idt->v; + id_bs = (struct ipsecdoi_id_b *) ids->v; + + ident_t.v = idt->v + sizeof(*id_bt); + ident_t.l = idt->l - sizeof(*id_bt); + ident_s.v = ids->v + sizeof(*id_bs); + ident_s.l = ids->l - sizeof(*id_bs); + + if (id_bs->type != id_bt->type) + { + /* + * special exception for comparing + * address to subnet id types when + * the netmask is address length + */ + + if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR)&& + (id_bt->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)) { + result = ipsecdoi_subnetisaddr_v4(&ident_t,&ident_s); + goto cmpid_result; + } + + if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)&& + (id_bt->type == IPSECDOI_ID_IPV4_ADDR)) { + result = ipsecdoi_subnetisaddr_v4(&ident_s,&ident_t); + goto cmpid_result; + } + +#ifdef INET6 + if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR)&& + (id_bt->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { + result = ipsecdoi_subnetisaddr_v6(&ident_t,&ident_s); + goto cmpid_result; + } + + if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)&& + (id_bt->type == IPSECDOI_ID_IPV6_ADDR)) { + result = ipsecdoi_subnetisaddr_v6(&ident_s,&ident_t); + goto cmpid_result; + } +#endif + plog(LLV_DEBUG, LOCATION, NULL, + "check and compare ids : id type mismatch %s != %s\n", + s_ipsecdoi_ident(id_bs->type), + s_ipsecdoi_ident(id_bt->type)); + + return 1; + } + + if(id_bs->proto_id != id_bt->proto_id){ + plog(LLV_DEBUG, LOCATION, NULL, + "check and compare ids : proto_id mismatch %d != %d\n", + id_bs->proto_id, id_bt->proto_id); + + return 1; + } + + /* compare the ID data. */ + + switch (id_bt->type) { + case IPSECDOI_ID_DER_ASN1_DN: + case IPSECDOI_ID_DER_ASN1_GN: + /* compare asn1 ids */ + result = eay_cmp_asn1dn(&ident_t, &ident_s); + goto cmpid_result; + + case IPSECDOI_ID_IPV4_ADDR: + /* validate lengths */ + if ((ident_t.l != sizeof(struct in_addr))|| + (ident_s.l != sizeof(struct in_addr))) + goto cmpid_invalid; + break; + + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + case IPSECDOI_ID_IPV4_ADDR_RANGE: + /* validate lengths */ + if ((ident_t.l != (sizeof(struct in_addr)*2))|| + (ident_s.l != (sizeof(struct in_addr)*2))) + goto cmpid_invalid; + break; + +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: + /* validate lengths */ + if ((ident_t.l != sizeof(struct in6_addr))|| + (ident_s.l != sizeof(struct in6_addr))) + goto cmpid_invalid; + break; + + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + case IPSECDOI_ID_IPV6_ADDR_RANGE: + /* validate lengths */ + if ((ident_t.l != (sizeof(struct in6_addr)*2))|| + (ident_s.l != (sizeof(struct in6_addr)*2))) + goto cmpid_invalid; + break; +#endif + case IPSECDOI_ID_FQDN: + case IPSECDOI_ID_USER_FQDN: + case IPSECDOI_ID_KEY_ID: + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "Unhandled id type %i specified for comparison\n", + id_bt->type); + return -1; + } + + /* validate matching data and length */ + if (ident_t.l == ident_s.l) + result = memcmp(ident_t.v,ident_s.v,ident_t.l); + else + result = 1; + +cmpid_result: + + /* debug level output */ + if(loglevel >= LLV_DEBUG) { + char *idstrt = ipsecdoi_id2str(idt); + char *idstrs = ipsecdoi_id2str(ids); + + if (!result) + plog(LLV_DEBUG, LOCATION, NULL, + "check and compare ids : values matched (%s)\n", + s_ipsecdoi_ident(id_bs->type) ); + else + plog(LLV_DEBUG, LOCATION, NULL, + "check and compare ids : value mismatch (%s)\n", + s_ipsecdoi_ident(id_bs->type)); + + plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: \'%s\'\n", idstrt ); + plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: \'%s\'\n", idstrs ); + + racoon_free(idstrs); + racoon_free(idstrt); + } + + /* return result */ + if( !result ) + return 0; + else + return 1; + +cmpid_invalid: + + /* id integrity error */ + plog(LLV_DEBUG, LOCATION, NULL, "check and compare ids : %s integrity error\n", + s_ipsecdoi_ident(id_bs->type)); + plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: length = \'%zu\'\n", ident_t.l ); + plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: length = \'%zu\'\n", ident_s.l ); + + return -1; +} + +/* + * check the following: + * - In main mode with pre-shared key, only address type can be used. + * - if proper type for phase 1 ? + * - if phase 1 ID payload conformed RFC2407 4.6.2. + * (proto, port) must be (0, 0), (udp, 500) or (udp, [specified]). + * - if ID payload sent from peer is equal to the ID expected by me. + * + * both of "id" and "id_p" should be ID payload without general header, + */ +int +ipsecdoi_checkid1(iph1) + struct ph1handle *iph1; +{ + struct ipsecdoi_id_b *id_b; + + if (iph1->id_p == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid iph1 passed id_p == NULL\n"); + return ISAKMP_INTERNAL_ERROR; + } + if (iph1->id_p->l < sizeof(*id_b)) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid value passed as \"ident\" (len=%lu)\n", + (u_long)iph1->id_p->l); + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + } + + id_b = (struct ipsecdoi_id_b *)iph1->id_p->v; + + /* In main mode with pre-shared key, only address type can be used. */ + if (iph1->etype == ISAKMP_ETYPE_IDENT && + iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_PSKEY) { + if (id_b->type != IPSECDOI_ID_IPV4_ADDR + && id_b->type != IPSECDOI_ID_IPV6_ADDR) { + plog(LLV_ERROR, LOCATION, NULL, + "Expecting IP address type in main mode, " + "but %s.\n", s_ipsecdoi_ident(id_b->type)); + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + } + } + + /* if proper type for phase 1 ? */ + switch (id_b->type) { + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + case IPSECDOI_ID_IPV4_ADDR_RANGE: + case IPSECDOI_ID_IPV6_ADDR_RANGE: + plog(LLV_WARNING, LOCATION, NULL, + "such ID type %s is not proper.\n", + s_ipsecdoi_ident(id_b->type)); + /*FALLTHROUGH*/ + } + + /* if phase 1 ID payload conformed RFC2407 4.6.2. */ + if (id_b->type == IPSECDOI_ID_IPV4_ADDR || + id_b->type == IPSECDOI_ID_IPV6_ADDR) { + + if (id_b->proto_id == 0 && ntohs(id_b->port) != 0) { + plog(LLV_WARNING, LOCATION, NULL, + "protocol ID and Port mismatched. " + "proto_id:%d port:%d\n", + id_b->proto_id, ntohs(id_b->port)); + /*FALLTHROUGH*/ + + } else if (id_b->proto_id == IPPROTO_UDP) { + /* + * copmaring with expecting port. + * always permit if port is equal to PORT_ISAKMP + */ + if (ntohs(id_b->port) != PORT_ISAKMP) { + u_int16_t port; + + port = extract_port(iph1->remote); + if (ntohs(id_b->port) != port) { + plog(LLV_WARNING, LOCATION, NULL, + "port %d expected, but %d\n", + port, ntohs(id_b->port)); + /*FALLTHROUGH*/ + } + } + } + } + + /* resolve remote configuration if not done yet */ + if (resolveph1rmconf(iph1) < 0) + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + + if (iph1->rmconf == NULL) + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + + return 0; +} + +/* + * create ID payload for phase 1 and set into iph1->id. + * NOT INCLUDING isakmp general header. + * see, RFC2407 4.6.2.1 + */ +int +ipsecdoi_setid1(iph1) + struct ph1handle *iph1; +{ + vchar_t *ret = NULL; + struct ipsecdoi_id_b id_b; + vchar_t *ident = NULL; + struct sockaddr *ipid = NULL; + + /* init */ + id_b.proto_id = 0; + id_b.port = 0; + ident = NULL; + + switch (iph1->rmconf->idvtype) { + case IDTYPE_FQDN: + id_b.type = IPSECDOI_ID_FQDN; + ident = vdup(iph1->rmconf->idv); + break; + case IDTYPE_USERFQDN: + id_b.type = IPSECDOI_ID_USER_FQDN; + ident = vdup(iph1->rmconf->idv); + break; + case IDTYPE_KEYID: + id_b.type = IPSECDOI_ID_KEY_ID; + ident = vdup(iph1->rmconf->idv); + break; + case IDTYPE_ASN1DN: + id_b.type = IPSECDOI_ID_DER_ASN1_DN; + if (iph1->rmconf->idv) { + /* XXX it must be encoded to asn1dn. */ + ident = vdup(iph1->rmconf->idv); + } else { + if (oakley_getmycert(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get own CERT.\n"); + goto err; + } + ident = eay_get_x509asn1subjectname(iph1->cert); + } + break; + case IDTYPE_ADDRESS: + /* + * if the value of the id type was set by the configuration + * file, then use it. otherwise the value is get from local + * ip address by using ike negotiation. + */ + if (iph1->rmconf->idv) + ipid = (struct sockaddr *)iph1->rmconf->idv->v; + /*FALLTHROUGH*/ + default: + { + int l; + caddr_t p; + + if (ipid == NULL) + ipid = iph1->local; + + /* use IP address */ + switch (ipid->sa_family) { + case AF_INET: + id_b.type = IPSECDOI_ID_IPV4_ADDR; + l = sizeof(struct in_addr); + p = (caddr_t)&((struct sockaddr_in *)ipid)->sin_addr; + break; +#ifdef INET6 + case AF_INET6: + id_b.type = IPSECDOI_ID_IPV6_ADDR; + l = sizeof(struct in6_addr); + p = (caddr_t)&((struct sockaddr_in6 *)ipid)->sin6_addr; + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid address family.\n"); + goto err; + } + id_b.proto_id = IPPROTO_UDP; + id_b.port = htons(PORT_ISAKMP); + ident = vmalloc(l); + if (!ident) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get ID buffer.\n"); + return -1; + } + memcpy(ident->v, p, ident->l); + } + } + if (!ident) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get ID buffer.\n"); + return -1; + } + + ret = vmalloc(sizeof(id_b) + ident->l); + if (ret == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get ID buffer.\n"); + goto err; + } + + memcpy(ret->v, &id_b, sizeof(id_b)); + memcpy(ret->v + sizeof(id_b), ident->v, ident->l); + + iph1->id = ret; + + plog(LLV_DEBUG, LOCATION, NULL, + "use ID type of %s\n", s_ipsecdoi_ident(id_b.type)); + if (ident) + vfree(ident); + return 0; + +err: + if (ident) + vfree(ident); + plog(LLV_ERROR, LOCATION, NULL, "failed get my ID\n"); + return -1; +} + +/* it's only called by cfparse.y. */ +int +set_identifier(vpp, type, value) + vchar_t **vpp, *value; + int type; +{ + return set_identifier_qual(vpp, type, value, IDQUAL_UNSPEC); +} + +int +set_identifier_qual(vpp, type, value, qual) + vchar_t **vpp, *value; + int type; + int qual; +{ + vchar_t *new = NULL; + + /* simply return if value is null. */ + if (!value){ + if( type == IDTYPE_FQDN || type == IDTYPE_USERFQDN){ + plog(LLV_ERROR, LOCATION, NULL, + "No %s\n", type == IDTYPE_FQDN ? "fqdn":"user fqdn"); + return -1; + } + return 0; + } + + switch (type) { + case IDTYPE_FQDN: + case IDTYPE_USERFQDN: + if(value->l <= 1){ + plog(LLV_ERROR, LOCATION, NULL, + "Empty %s\n", type == IDTYPE_FQDN ? "fqdn":"user fqdn"); + return -1; + } + /* length is adjusted since QUOTEDSTRING teminates NULL. */ + new = vmalloc(value->l - 1); + if (new == NULL) + return -1; + memcpy(new->v, value->v, new->l); + break; + case IDTYPE_KEYID: + /* + * If no qualifier is specified: IDQUAL_UNSPEC. It means + * to use a file for backward compatibility sake. + */ + switch(qual) { + case IDQUAL_FILE: + case IDQUAL_UNSPEC: { + FILE *fp; + char b[512]; + int tlen, len; + + fp = fopen(value->v, "r"); + if (fp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "can not open %s\n", value->v); + return -1; + } + tlen = 0; + while ((len = fread(b, 1, sizeof(b), fp)) != 0) { + new = vrealloc(new, tlen + len); + if (!new) { + fclose(fp); + return -1; + } + memcpy(new->v + tlen, b, len); + tlen += len; + } + fclose(fp); + break; + } + + case IDQUAL_TAG: + new = vmalloc(value->l - 1); + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "can not allocate memory"); + return -1; + } + memcpy(new->v, value->v, new->l); + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "unknown qualifier"); + return -1; + } + break; + + case IDTYPE_ADDRESS: { + struct sockaddr *sa; + + /* length is adjusted since QUOTEDSTRING teminates NULL. */ + if (value->l == 0) + break; + + sa = str2saddr(value->v, NULL); + if (sa == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid ip address %s\n", value->v); + return -1; + } + + new = vmalloc(sysdep_sa_len(sa)); + if (new == NULL) { + racoon_free(sa); + return -1; + } + memcpy(new->v, sa, new->l); + racoon_free(sa); + break; + } + case IDTYPE_ASN1DN: + if (value->v[0] == '~') + /* Hex-encoded ASN1 strings */ + new = eay_hex2asn1dn(value->v + 1, - 1); + else + /* DN encoded strings */ + new = eay_str2asn1dn(value->v, value->l - 1); + + if (new == NULL) + return -1; + + if (loglevel >= LLV_DEBUG) { + X509_NAME *xn; + BIO *bio; + unsigned char *ptr = (unsigned char *) new->v, *buf; + size_t len; + char save; + + xn = d2i_X509_NAME(NULL, (void *)&ptr, new->l); + bio = BIO_new(BIO_s_mem()); + + X509_NAME_print_ex(bio, xn, 0, 0); + len = BIO_get_mem_data(bio, &ptr); + save = ptr[len]; + ptr[len] = 0; + plog(LLV_DEBUG, LOCATION, NULL, "Parsed DN: %s\n", ptr); + ptr[len] = save; + X509_NAME_free(xn); + BIO_free(bio); + } + + break; + } + + *vpp = new; + + return 0; +} + +/* + * create ID payload for phase 2, and set into iph2->id and id_p. There are + * NOT INCLUDING isakmp general header. + * this function is for initiator. responder will get to copy from payload. + * responder ID type is always address type. + * see, RFC2407 4.6.2.1 + */ +int +ipsecdoi_setid2(iph2) + struct ph2handle *iph2; +{ + struct secpolicy *sp; + + /* check there is phase 2 handler ? */ + sp = getspbyspid(iph2->spid); + if (sp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no policy found for spid:%u.\n", iph2->spid); + return -1; + } + + if (!ipsecdoi_transportmode(iph2->proposal)) + iph2->id = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.src, + sp->spidx.prefs, sp->spidx.ul_proto); + else if (iph2->sa_src != NULL) { + /* He have a specific hint indicating that the transport + * mode SA will be negotiated using addresses that differ + * with the one from the SA. We need to indicate that to + * our peer by setting the SA address as ID. + * This is typically the case for the bootstrapping of the + * transport mode SA protecting BU/BA for MIPv6 traffic + * + * --arno*/ + iph2->id = ipsecdoi_sockaddr2id(iph2->sa_src, + IPSECDOI_PREFIX_HOST, + sp->spidx.ul_proto); + } else + iph2->id = ipsecdoi_sockaddr2id(iph2->src, IPSECDOI_PREFIX_HOST, + sp->spidx.ul_proto); + + if (iph2->id == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get ID for %s\n", + spidx2str(&sp->spidx)); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, "use local ID type %s\n", + s_ipsecdoi_ident(((struct ipsecdoi_id_b *)iph2->id->v)->type)); + + /* remote side */ + if (!ipsecdoi_transportmode(iph2->proposal)) + iph2->id_p = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.dst, + sp->spidx.prefd, sp->spidx.ul_proto); + else if (iph2->sa_dst != NULL) { + /* See comment above for local side. */ + iph2->id_p = ipsecdoi_sockaddr2id(iph2->sa_dst, + IPSECDOI_PREFIX_HOST, + sp->spidx.ul_proto); + } else + iph2->id_p = ipsecdoi_sockaddr2id(iph2->dst, IPSECDOI_PREFIX_HOST, + sp->spidx.ul_proto); + + if (iph2->id_p == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get ID for %s\n", + spidx2str(&sp->spidx)); + VPTRINIT(iph2->id); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, + "use remote ID type %s\n", + s_ipsecdoi_ident(((struct ipsecdoi_id_b *)iph2->id_p->v)->type)); + + return 0; +} + +/* + * set address type of ID. + * NOT INCLUDING general header. + */ +vchar_t * +ipsecdoi_sockaddr2id(saddr, prefixlen, ul_proto) + struct sockaddr *saddr; + u_int prefixlen; + u_int ul_proto; +{ + vchar_t *new; + int type, len1, len2; + caddr_t sa; + u_short port; + + /* + * Q. When type is SUBNET, is it allowed to be ::1/128. + * A. Yes. (consensus at bake-off) + */ + switch (saddr->sa_family) { + case AF_INET: + len1 = sizeof(struct in_addr); + if (prefixlen >= (sizeof(struct in_addr) << 3)) { + type = IPSECDOI_ID_IPV4_ADDR; + len2 = 0; + } else { + type = IPSECDOI_ID_IPV4_ADDR_SUBNET; + len2 = sizeof(struct in_addr); + } + sa = (caddr_t)&((struct sockaddr_in *)(saddr))->sin_addr; + port = ((struct sockaddr_in *)(saddr))->sin_port; + break; +#ifdef INET6 + case AF_INET6: + len1 = sizeof(struct in6_addr); + if (prefixlen >= (sizeof(struct in6_addr) << 3)) { + type = IPSECDOI_ID_IPV6_ADDR; + len2 = 0; + } else { + type = IPSECDOI_ID_IPV6_ADDR_SUBNET; + len2 = sizeof(struct in6_addr); + } + sa = (caddr_t)&((struct sockaddr_in6 *)(saddr))->sin6_addr; + port = ((struct sockaddr_in6 *)(saddr))->sin6_port; + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid family: %d.\n", saddr->sa_family); + return NULL; + } + + /* get ID buffer */ + new = vmalloc(sizeof(struct ipsecdoi_id_b) + len1 + len2); + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get ID buffer.\n"); + return NULL; + } + + memset(new->v, 0, new->l); + + /* set the part of header. */ + ((struct ipsecdoi_id_b *)new->v)->type = type; + + /* set ul_proto and port */ + /* + * NOTE: we use both IPSEC_ULPROTO_ANY and IPSEC_PORT_ANY as wild card + * because 0 means port number of 0. Instead of 0, we use IPSEC_*_ANY. + */ + ((struct ipsecdoi_id_b *)new->v)->proto_id = + ul_proto == IPSEC_ULPROTO_ANY ? 0 : ul_proto; + ((struct ipsecdoi_id_b *)new->v)->port = + port == IPSEC_PORT_ANY ? 0 : port; + memcpy(new->v + sizeof(struct ipsecdoi_id_b), sa, len1); + + /* set address */ + + /* set prefix */ + if (len2) { + u_char *p = (unsigned char *) new->v + + sizeof(struct ipsecdoi_id_b) + len1; + u_int bits = prefixlen; + + while (bits >= 8) { + *p++ = 0xff; + bits -= 8; + } + + if (bits > 0) + *p = ~((1 << (8 - bits)) - 1); + } + + return new; +} + +vchar_t * +ipsecdoi_sockrange2id(laddr, haddr, ul_proto) + struct sockaddr *laddr, *haddr; + u_int ul_proto; +{ + vchar_t *new; + int type, len1, len2; + u_short port; + + if (laddr->sa_family != haddr->sa_family) { + plog(LLV_ERROR, LOCATION, NULL, "Address family mismatch\n"); + return NULL; + } + + switch (laddr->sa_family) { + case AF_INET: + type = IPSECDOI_ID_IPV4_ADDR_RANGE; + len1 = sizeof(struct in_addr); + len2 = sizeof(struct in_addr); + break; +#ifdef INET6 + case AF_INET6: + type = IPSECDOI_ID_IPV6_ADDR_RANGE; + len1 = sizeof(struct in6_addr); + len2 = sizeof(struct in6_addr); + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid family: %d.\n", laddr->sa_family); + return NULL; + } + + /* get ID buffer */ + new = vmalloc(sizeof(struct ipsecdoi_id_b) + len1 + len2); + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get ID buffer.\n"); + return NULL; + } + + memset(new->v, 0, new->l); + /* set the part of header. */ + ((struct ipsecdoi_id_b *)new->v)->type = type; + + /* set ul_proto and port */ + /* + * NOTE: we use both IPSEC_ULPROTO_ANY and IPSEC_PORT_ANY as wild card + * because 0 means port number of 0. Instead of 0, we use IPSEC_*_ANY. + */ + ((struct ipsecdoi_id_b *)new->v)->proto_id = + ul_proto == IPSEC_ULPROTO_ANY ? 0 : ul_proto; + port = ((struct sockaddr_in *)(laddr))->sin_port; + ((struct ipsecdoi_id_b *)new->v)->port = + port == IPSEC_PORT_ANY ? 0 : port; + memcpy(new->v + sizeof(struct ipsecdoi_id_b), + (caddr_t)&((struct sockaddr_in *)(laddr))->sin_addr, + len1); + memcpy(new->v + sizeof(struct ipsecdoi_id_b) + len1, + (caddr_t)&((struct sockaddr_in *)haddr)->sin_addr, + len2); + return new; +} + + +/* + * create sockaddr structure from ID payload (buf). + * buffers (saddr, prefixlen, ul_proto) must be allocated. + * see, RFC2407 4.6.2.1 + */ +int +ipsecdoi_id2sockaddr(buf, saddr, prefixlen, ul_proto) + vchar_t *buf; + struct sockaddr *saddr; + u_int8_t *prefixlen; + u_int16_t *ul_proto; +{ + struct ipsecdoi_id_b *id_b = NULL; + u_int plen = 0; + + if (buf == NULL) + return ISAKMP_INTERNAL_ERROR; + + id_b = (struct ipsecdoi_id_b *)buf->v; + + /* + * When a ID payload of subnet type with a IP address of full bit + * masked, it has to be processed as host address. + * e.g. below 2 type are same. + * type = ipv6 subnet, data = 2001::1/128 + * type = ipv6 address, data = 2001::1 + */ + switch (id_b->type) { + case IPSECDOI_ID_IPV4_ADDR: + case IPSECDOI_ID_IPV4_ADDR_SUBNET: +#ifndef __linux__ + saddr->sa_len = sizeof(struct sockaddr_in); +#endif + saddr->sa_family = AF_INET; + ((struct sockaddr_in *)saddr)->sin_port = + (id_b->port == 0 + ? IPSEC_PORT_ANY + : id_b->port); /* see sockaddr2id() */ + memcpy(&((struct sockaddr_in *)saddr)->sin_addr, + buf->v + sizeof(*id_b), sizeof(struct in_addr)); + break; +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: + case IPSECDOI_ID_IPV6_ADDR_SUBNET: +#ifndef __linux__ + saddr->sa_len = sizeof(struct sockaddr_in6); +#endif + saddr->sa_family = AF_INET6; + ((struct sockaddr_in6 *)saddr)->sin6_port = + (id_b->port == 0 + ? IPSEC_PORT_ANY + : id_b->port); /* see sockaddr2id() */ + memcpy(&((struct sockaddr_in6 *)saddr)->sin6_addr, + buf->v + sizeof(*id_b), sizeof(struct in6_addr)); + ((struct sockaddr_in6 *)saddr)->sin6_scope_id = + (IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)saddr)->sin6_addr) + ? ((struct sockaddr_in6 *)id_b)->sin6_scope_id + : 0); + + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "unsupported ID type %d\n", id_b->type); + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + } + + /* get prefix length */ + switch (id_b->type) { + case IPSECDOI_ID_IPV4_ADDR: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + case IPSECDOI_ID_IPV4_ADDR_SUBNET: +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR_SUBNET: +#endif + { + u_char *p; + u_int max; + int alen = sizeof(struct in_addr); + + switch (id_b->type) { + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + alen = sizeof(struct in_addr); + break; +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + alen = sizeof(struct in6_addr); + break; +#endif + } + + /* sanity check */ + if (buf->l < alen) + return ISAKMP_INTERNAL_ERROR; + + /* get subnet mask length */ + plen = 0; + max = alen <<3; + + p = (unsigned char *) buf->v + + sizeof(struct ipsecdoi_id_b) + + alen; + + for (; *p == 0xff; p++) { + plen += 8; + if (plen >= max) + break; + } + + if (plen < max) { + u_int l = 0; + u_char b = ~(*p); + + while (b) { + b >>= 1; + l++; + } + + l = 8 - l; + plen += l; + } + } + break; + } + + *prefixlen = plen; + *ul_proto = id_b->proto_id == 0 + ? IPSEC_ULPROTO_ANY + : id_b->proto_id; /* see sockaddr2id() */ + + return 0; +} + +/* + * make printable string from ID payload except of general header. + */ +char * +ipsecdoi_id2str(id) + const vchar_t *id; +{ +#define BUFLEN 512 + char * ret = NULL; + int len = 0; + char *dat; + static char buf[BUFLEN]; + struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)id->v; + union sockaddr_any saddr; + u_int plen = 0; + + switch (id_b->type) { + case IPSECDOI_ID_IPV4_ADDR: + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + case IPSECDOI_ID_IPV4_ADDR_RANGE: + +#ifndef __linux__ + saddr.sa.sa_len = sizeof(struct sockaddr_in); +#endif + saddr.sa.sa_family = AF_INET; + saddr.sin.sin_port = IPSEC_PORT_ANY; + memcpy(&saddr.sin.sin_addr, + id->v + sizeof(*id_b), sizeof(struct in_addr)); + break; +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + case IPSECDOI_ID_IPV6_ADDR_RANGE: + +#ifndef __linux__ + saddr.sa.sa_len = sizeof(struct sockaddr_in6); +#endif + saddr.sa.sa_family = AF_INET6; + saddr.sin6.sin6_port = IPSEC_PORT_ANY; + memcpy(&saddr.sin6.sin6_addr, + id->v + sizeof(*id_b), sizeof(struct in6_addr)); + saddr.sin6.sin6_scope_id = + (IN6_IS_ADDR_LINKLOCAL(&saddr.sin6.sin6_addr) + ? ((struct sockaddr_in6 *)id_b)->sin6_scope_id + : 0); + break; +#endif + } + + switch (id_b->type) { + case IPSECDOI_ID_IPV4_ADDR: +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: +#endif + len = snprintf( buf, BUFLEN, "%s", saddrwop2str(&saddr.sa)); + break; + + case IPSECDOI_ID_IPV4_ADDR_SUBNET: +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR_SUBNET: +#endif + { + u_char *p; + u_int max; + int alen = sizeof(struct in_addr); + + switch (id_b->type) { + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + alen = sizeof(struct in_addr); + break; +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + alen = sizeof(struct in6_addr); + break; +#endif + } + + /* sanity check */ + if (id->l < alen) { + len = 0; + break; + } + + /* get subnet mask length */ + plen = 0; + max = alen <<3; + + p = (unsigned char *) id->v + + sizeof(struct ipsecdoi_id_b) + + alen; + + for (; *p == 0xff; p++) { + plen += 8; + if (plen >= max) + break; + } + + if (plen < max) { + u_int l = 0; + u_char b = ~(*p); + + while (b) { + b >>= 1; + l++; + } + + l = 8 - l; + plen += l; + } + + len = snprintf( buf, BUFLEN, "%s/%i", saddrwop2str(&saddr.sa), plen); + } + break; + + case IPSECDOI_ID_IPV4_ADDR_RANGE: + + len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(&saddr.sa)); + +#ifndef __linux__ + saddr.sa.sa_len = sizeof(struct sockaddr_in); +#endif + saddr.sa.sa_family = AF_INET; + saddr.sin.sin_port = IPSEC_PORT_ANY; + memcpy(&saddr.sin.sin_addr, + id->v + sizeof(*id_b) + sizeof(struct in_addr), + sizeof(struct in_addr)); + + len += snprintf(buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr.sa)); + break; + +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR_RANGE: + len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(&saddr.sa)); + +#ifndef __linux__ + saddr.sa.sa_len = sizeof(struct sockaddr_in6); +#endif + saddr.sa.sa_family = AF_INET6; + saddr.sin6.sin6_port = IPSEC_PORT_ANY; + memcpy(&saddr.sin6.sin6_addr, + id->v + sizeof(*id_b) + sizeof(struct in6_addr), + sizeof(struct in6_addr)); + saddr.sin6.sin6_scope_id = + (IN6_IS_ADDR_LINKLOCAL(&saddr.sin6.sin6_addr) + ? ((struct sockaddr_in6 *)id_b)->sin6_scope_id + : 0); + + len += snprintf(buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr.sa)); + break; +#endif + + case IPSECDOI_ID_FQDN: + case IPSECDOI_ID_USER_FQDN: + len = id->l - sizeof(*id_b); + if (len > BUFLEN) + len = BUFLEN; + memcpy(buf, id->v + sizeof(*id_b), len); + break; + + case IPSECDOI_ID_DER_ASN1_DN: + case IPSECDOI_ID_DER_ASN1_GN: + { + X509_NAME *xn = NULL; + + dat = id->v + sizeof(*id_b); + len = id->l - sizeof(*id_b); + + if (d2i_X509_NAME(&xn, (void*) &dat, len) != NULL) { + BIO *bio = BIO_new(BIO_s_mem()); + X509_NAME_print_ex(bio, xn, 0, 0); + len = BIO_get_mem_data(bio, &dat); + if (len > BUFLEN) + len = BUFLEN; + memcpy(buf,dat,len); + BIO_free(bio); + X509_NAME_free(xn); + } else { + plog(LLV_ERROR, LOCATION, NULL, + "unable to extract asn1dn from id\n"); + + len = sprintf(buf, ""); + } + + break; + } + + /* currently unhandled id types */ + case IPSECDOI_ID_KEY_ID: + len = sprintf( buf, ""); + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "unknown ID type %d\n", id_b->type); + } + + if (!len) + len = sprintf( buf, ""); + + ret = racoon_malloc(len+1); + if (ret != NULL) { + memcpy(ret,buf,len); + ret[len]=0; + } + + return ret; +} + +/* + * set IPsec data attributes into a proposal. + * NOTE: MUST called per a transform. + */ +int +ipsecdoi_t2satrns(t, pp, pr, tr) + struct isakmp_pl_t *t; + struct saprop *pp; + struct saproto *pr; + struct satrns *tr; +{ + struct isakmp_data *d, *prev; + int flag, type; + int error = -1; + int life_t; + int tlen; + + tr->trns_no = t->t_no; + tr->trns_id = t->t_id; + + tlen = ntohs(t->h.len) - sizeof(*t); + prev = (struct isakmp_data *)NULL; + d = (struct isakmp_data *)(t + 1); + + /* default */ + life_t = IPSECDOI_ATTR_SA_LD_TYPE_DEFAULT; + pp->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT; + pp->lifebyte = 0; + tr->authtype = IPSECDOI_ATTR_AUTH_NONE; + + while (tlen > 0) { + + type = ntohs(d->type) & ~ISAKMP_GEN_MASK; + flag = ntohs(d->type) & ISAKMP_GEN_MASK; + + plog(LLV_DEBUG, LOCATION, NULL, + "type=%s, flag=0x%04x, lorv=%s\n", + s_ipsecdoi_attr(type), flag, + s_ipsecdoi_attr_v(type, ntohs(d->lorv))); + + switch (type) { + case IPSECDOI_ATTR_SA_LD_TYPE: + { + int type = ntohs(d->lorv); + switch (type) { + case IPSECDOI_ATTR_SA_LD_TYPE_SEC: + case IPSECDOI_ATTR_SA_LD_TYPE_KB: + life_t = type; + break; + default: + plog(LLV_WARNING, LOCATION, NULL, + "invalid life duration type. " + "use default\n"); + life_t = IPSECDOI_ATTR_SA_LD_TYPE_DEFAULT; + break; + } + break; + } + case IPSECDOI_ATTR_SA_LD: + if (prev == NULL + || (ntohs(prev->type) & ~ISAKMP_GEN_MASK) != + IPSECDOI_ATTR_SA_LD_TYPE) { + plog(LLV_ERROR, LOCATION, NULL, + "life duration must follow ltype\n"); + break; + } + + { + u_int32_t t; + vchar_t *ld_buf = NULL; + + if (flag) { + /* i.e. ISAKMP_GEN_TV */ + ld_buf = vmalloc(sizeof(d->lorv)); + if (ld_buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get LD buffer.\n"); + goto end; + } + memcpy(ld_buf->v, &d->lorv, sizeof(d->lorv)); + } else { + int len = ntohs(d->lorv); + /* i.e. ISAKMP_GEN_TLV */ + ld_buf = vmalloc(len); + if (ld_buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get LD buffer.\n"); + goto end; + } + memcpy(ld_buf->v, d + 1, len); + } + switch (life_t) { + case IPSECDOI_ATTR_SA_LD_TYPE_SEC: + t = ipsecdoi_set_ld(ld_buf); + vfree(ld_buf); + if (t == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid life duration.\n"); + goto end; + } + /* lifetime must be equal in a proposal. */ + if (pp->lifetime == IPSECDOI_ATTR_SA_LD_SEC_DEFAULT) + pp->lifetime = t; + else if (pp->lifetime != t) { + plog(LLV_ERROR, LOCATION, NULL, + "lifetime mismatched " + "in a proposal, " + "prev:%ld curr:%u.\n", + (long)pp->lifetime, t); + goto end; + } + break; + case IPSECDOI_ATTR_SA_LD_TYPE_KB: + t = ipsecdoi_set_ld(ld_buf); + vfree(ld_buf); + if (t == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid life duration.\n"); + goto end; + } + /* lifebyte must be equal in a proposal. */ + if (pp->lifebyte == 0) + pp->lifebyte = t; + else if (pp->lifebyte != t) { + plog(LLV_ERROR, LOCATION, NULL, + "lifebyte mismatched " + "in a proposal, " + "prev:%d curr:%u.\n", + pp->lifebyte, t); + goto end; + } + break; + default: + vfree(ld_buf); + plog(LLV_ERROR, LOCATION, NULL, + "invalid life type: %d\n", life_t); + goto end; + } + } + break; + + case IPSECDOI_ATTR_GRP_DESC: + /* + * RFC2407: 4.5 IPSEC Security Association Attributes + * Specifies the Oakley Group to be used in a PFS QM + * negotiation. For a list of supported values, see + * Appendix A of [IKE]. + */ + if (pp->pfs_group == 0) + pp->pfs_group = (u_int16_t)ntohs(d->lorv); + else if (pp->pfs_group != (u_int16_t)ntohs(d->lorv)) { + plog(LLV_ERROR, LOCATION, NULL, + "pfs_group mismatched " + "in a proposal.\n"); + goto end; + } + break; + + case IPSECDOI_ATTR_ENC_MODE: + if (pr->encmode && + pr->encmode != (u_int16_t)ntohs(d->lorv)) { + plog(LLV_ERROR, LOCATION, NULL, + "multiple encmode exist " + "in a transform.\n"); + goto end; + } + pr->encmode = (u_int16_t)ntohs(d->lorv); + break; + + case IPSECDOI_ATTR_AUTH: + if (tr->authtype != IPSECDOI_ATTR_AUTH_NONE) { + plog(LLV_ERROR, LOCATION, NULL, + "multiple authtype exist " + "in a transform.\n"); + goto end; + } + tr->authtype = (u_int16_t)ntohs(d->lorv); + break; + + case IPSECDOI_ATTR_KEY_LENGTH: + if (pr->proto_id != IPSECDOI_PROTO_IPSEC_ESP) { + plog(LLV_ERROR, LOCATION, NULL, + "key length defined but not ESP"); + goto end; + } + tr->encklen = ntohs(d->lorv); + break; +#ifdef HAVE_SECCTX + case IPSECDOI_ATTR_SECCTX: + { + int len = ntohs(d->lorv); + memcpy(&pp->sctx, d + 1, len); + pp->sctx.ctx_strlen = ntohs(pp->sctx.ctx_strlen); + break; + } +#endif /* HAVE_SECCTX */ + case IPSECDOI_ATTR_KEY_ROUNDS: + case IPSECDOI_ATTR_COMP_DICT_SIZE: + case IPSECDOI_ATTR_COMP_PRIVALG: + default: + break; + } + + prev = d; + if (flag) { + tlen -= sizeof(*d); + d = (struct isakmp_data *)((char *)d + sizeof(*d)); + } else { + tlen -= (sizeof(*d) + ntohs(d->lorv)); + d = (struct isakmp_data *)((caddr_t)d + sizeof(*d) + ntohs(d->lorv)); + } + } + + error = 0; +end: + return error; +} + +int +ipsecdoi_authalg2trnsid(alg) + int alg; +{ + switch (alg) { + case IPSECDOI_ATTR_AUTH_HMAC_MD5: + return IPSECDOI_AH_MD5; + case IPSECDOI_ATTR_AUTH_HMAC_SHA1: + return IPSECDOI_AH_SHA; + case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256: + return IPSECDOI_AH_SHA256; + case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384: + return IPSECDOI_AH_SHA384; + case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512: + return IPSECDOI_AH_SHA512; + case IPSECDOI_ATTR_AUTH_DES_MAC: + return IPSECDOI_AH_DES; + case IPSECDOI_ATTR_AUTH_KPDK: + return IPSECDOI_AH_MD5; /* XXX */ + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid authentication algorithm:%d\n", alg); + } + return -1; +} + +static int rm_idtype2doi[] = { + 255, /* IDTYPE_UNDEFINED, 0 */ + IPSECDOI_ID_FQDN, /* IDTYPE_FQDN, 1 */ + IPSECDOI_ID_USER_FQDN, /* IDTYPE_USERFQDN, 2 */ + IPSECDOI_ID_KEY_ID, /* IDTYPE_KEYID, 3 */ + 255, /* IDTYPE_ADDRESS, 4 + * it expands into 4 types by another function. */ + IPSECDOI_ID_DER_ASN1_DN, /* IDTYPE_ASN1DN, 5 */ +}; + +/* + * convert idtype to DOI value. + * OUT 255 : NG + * other: converted. + */ +int +idtype2doi(idtype) + int idtype; +{ + if (ARRAYLEN(rm_idtype2doi) > idtype) + return rm_idtype2doi[idtype]; + return 255; +} + +int +doi2idtype(doi) + int doi; +{ + switch(doi) { + case IPSECDOI_ID_FQDN: + return(IDTYPE_FQDN); + case IPSECDOI_ID_USER_FQDN: + return(IDTYPE_USERFQDN); + case IPSECDOI_ID_KEY_ID: + return(IDTYPE_KEYID); + case IPSECDOI_ID_DER_ASN1_DN: + return(IDTYPE_ASN1DN); + case IPSECDOI_ID_IPV4_ADDR: + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + case IPSECDOI_ID_IPV6_ADDR: + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + return(IDTYPE_ADDRESS); + default: + plog(LLV_WARNING, LOCATION, NULL, + "Inproper idtype:%s in this function.\n", + s_ipsecdoi_ident(doi)); + return(IDTYPE_ADDRESS); /* XXX */ + } + /*NOTREACHED*/ +} diff --git a/ipsec-tools/src/racoon/ipsec_doi.h b/ipsec-tools/src/racoon/ipsec_doi.h new file mode 100644 index 00000000..e3128f90 --- /dev/null +++ b/ipsec-tools/src/racoon/ipsec_doi.h @@ -0,0 +1,255 @@ +/* $NetBSD: ipsec_doi.h,v 1.12 2009/03/12 10:57:26 tteras Exp $ */ + +/* Id: ipsec_doi.h,v 1.15 2006/08/11 16:06:30 vanhu Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _IPSEC_DOI_H +#define _IPSEC_DOI_H + +#include "isakmp.h" + +/* refered to RFC2407 */ + +#define IPSEC_DOI 1 + +/* 4.2 IPSEC Situation Definition */ +#define IPSECDOI_SIT_IDENTITY_ONLY 0x00000001 +#define IPSECDOI_SIT_SECRECY 0x00000002 +#define IPSECDOI_SIT_INTEGRITY 0x00000004 + +/* 4.4.1 IPSEC Security Protocol Identifiers */ + /* 4.4.2 IPSEC ISAKMP Transform Values */ +#define IPSECDOI_PROTO_ISAKMP 1 +#define IPSECDOI_KEY_IKE 1 + +/* 4.4.1 IPSEC Security Protocol Identifiers */ +#define IPSECDOI_PROTO_IPSEC_AH 2 + /* 4.4.3 IPSEC AH Transform Values */ +#define IPSECDOI_AH_MD5 2 +#define IPSECDOI_AH_SHA 3 +#define IPSECDOI_AH_DES 4 +#define IPSECDOI_AH_SHA256 5 +#define IPSECDOI_AH_SHA384 6 +#define IPSECDOI_AH_SHA512 7 + +/* 4.4.1 IPSEC Security Protocol Identifiers */ +#define IPSECDOI_PROTO_IPSEC_ESP 3 + /* 4.4.4 IPSEC ESP Transform Identifiers */ +#define IPSECDOI_ESP_DES_IV64 1 +#define IPSECDOI_ESP_DES 2 +#define IPSECDOI_ESP_3DES 3 +#define IPSECDOI_ESP_RC5 4 +#define IPSECDOI_ESP_IDEA 5 +#define IPSECDOI_ESP_CAST 6 +#define IPSECDOI_ESP_BLOWFISH 7 +#define IPSECDOI_ESP_3IDEA 8 +#define IPSECDOI_ESP_DES_IV32 9 +#define IPSECDOI_ESP_RC4 10 +#define IPSECDOI_ESP_NULL 11 +#define IPSECDOI_ESP_AES 12 +#define IPSECDOI_ESP_CAMELLIA 22 +#if 1 + /* draft-ietf-ipsec-ciph-aes-cbc-00.txt */ +#define IPSECDOI_ESP_TWOFISH 253 +#else + /* SSH uses these value for now */ +#define IPSECDOI_ESP_TWOFISH 250 +#endif + +/* 4.4.1 IPSEC Security Protocol Identifiers */ +#define IPSECDOI_PROTO_IPCOMP 4 + /* 4.4.5 IPSEC IPCOMP Transform Identifiers */ +#define IPSECDOI_IPCOMP_OUI 1 +#define IPSECDOI_IPCOMP_DEFLATE 2 +#define IPSECDOI_IPCOMP_LZS 3 + +/* 4.5 IPSEC Security Association Attributes */ +/* NOTE: default value is not included in a packet. */ +#define IPSECDOI_ATTR_SA_LD_TYPE 1 /* B */ +#define IPSECDOI_ATTR_SA_LD_TYPE_DEFAULT 1 +#define IPSECDOI_ATTR_SA_LD_TYPE_SEC 1 +#define IPSECDOI_ATTR_SA_LD_TYPE_KB 2 +#define IPSECDOI_ATTR_SA_LD_TYPE_MAX 3 +#define IPSECDOI_ATTR_SA_LD 2 /* V */ +#define IPSECDOI_ATTR_SA_LD_SEC_DEFAULT 28800 /* 8 hours */ +#define IPSECDOI_ATTR_SA_LD_KB_MAX (~(1 << ((sizeof(int) << 3) - 1))) +#define IPSECDOI_ATTR_GRP_DESC 3 /* B */ +#define IPSECDOI_ATTR_ENC_MODE 4 /* B */ + /* default value: host dependent */ +#define IPSECDOI_ATTR_ENC_MODE_ANY 0 /* NOTE:internal use */ +#define IPSECDOI_ATTR_ENC_MODE_TUNNEL 1 +#define IPSECDOI_ATTR_ENC_MODE_TRNS 2 + +/* NAT-T draft-ietf-ipsec-nat-t-ike-05 and later */ +#define IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC 3 +#define IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC 4 + +/* NAT-T up to draft-ietf-ipsec-nat-t-ike-04 */ +#define IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT 61443 +#define IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT 61444 + +#define IPSECDOI_ATTR_AUTH 5 /* B */ + /* 0 means not to use authentication. */ +#define IPSECDOI_ATTR_AUTH_HMAC_MD5 1 +#define IPSECDOI_ATTR_AUTH_HMAC_SHA1 2 +#define IPSECDOI_ATTR_AUTH_DES_MAC 3 +#define IPSECDOI_ATTR_AUTH_KPDK 4 /*RFC-1826(Key/Pad/Data/Key)*/ +#define IPSECDOI_ATTR_AUTH_HMAC_SHA2_256 5 +#define IPSECDOI_ATTR_AUTH_HMAC_SHA2_384 6 +#define IPSECDOI_ATTR_AUTH_HMAC_SHA2_512 7 +#define IPSECDOI_ATTR_AUTH_NONE 254 /* NOTE:internal use */ + /* + * When negotiating ESP without authentication, the Auth + * Algorithm attribute MUST NOT be included in the proposal. + * When negotiating ESP without confidentiality, the Auth + * Algorithm attribute MUST be included in the proposal and + * the ESP transform ID must be ESP_NULL. + */ +#define IPSECDOI_ATTR_KEY_LENGTH 6 /* B */ +#define IPSECDOI_ATTR_KEY_ROUNDS 7 /* B */ +#define IPSECDOI_ATTR_COMP_DICT_SIZE 8 /* B */ +#define IPSECDOI_ATTR_COMP_PRIVALG 9 /* V */ + +#ifdef HAVE_SECCTX +#define IPSECDOI_ATTR_SECCTX 10 /* V */ +#endif + +/* 4.6.1 Security Association Payload */ +struct ipsecdoi_pl_sa { + struct isakmp_gen h; + struct ipsecdoi_sa_b { + u_int32_t doi; /* Domain of Interpretation */ + u_int32_t sit; /* Situation */ + } b; + /* followed by Leveled Domain Identifier and so on. */ +} __attribute__((__packed__)); + +struct ipsecdoi_secrecy_h { + u_int16_t len; + u_int16_t reserved; + /* followed by the value */ +} __attribute__((__packed__)); + +/* 4.6.2 Identification Payload Content */ +struct ipsecdoi_pl_id { + struct isakmp_gen h; + struct ipsecdoi_id_b { + u_int8_t type; /* ID Type */ + u_int8_t proto_id; /* Protocol ID */ + u_int16_t port; /* Port */ + } b; + /* followed by Identification Data */ +} __attribute__((__packed__)); + +#define IPSECDOI_ID_IPV4_ADDR 1 +#define IPSECDOI_ID_FQDN 2 +#define IPSECDOI_ID_USER_FQDN 3 +#define IPSECDOI_ID_IPV4_ADDR_SUBNET 4 +#define IPSECDOI_ID_IPV6_ADDR 5 +#define IPSECDOI_ID_IPV6_ADDR_SUBNET 6 +#define IPSECDOI_ID_IPV4_ADDR_RANGE 7 +#define IPSECDOI_ID_IPV6_ADDR_RANGE 8 +#define IPSECDOI_ID_DER_ASN1_DN 9 +#define IPSECDOI_ID_DER_ASN1_GN 10 +#define IPSECDOI_ID_KEY_ID 11 + +/* compressing doi type, it's internal use. */ +#define IDTYPE_UNDEFINED 0 +#define IDTYPE_FQDN 1 +#define IDTYPE_USERFQDN 2 +#define IDTYPE_KEYID 3 +#define IDTYPE_ADDRESS 4 +#define IDTYPE_ASN1DN 5 +#define IDTYPE_SUBNET 6 + +/* qualifiers for KEYID (and maybe others) */ +#define IDQUAL_UNSPEC 0 +#define IDQUAL_FILE 1 +#define IDQUAL_TAG 2 + +/* The use for checking proposal payload. This is not exchange type. */ +#define IPSECDOI_TYPE_PH1 0 +#define IPSECDOI_TYPE_PH2 1 + +/* + * Prefix that will make ipsecdoi_sockaddr2id() generate address type + * identities without knowning the exact length of address. + */ +#define IPSECDOI_PREFIX_HOST 0xff + +struct isakmpsa; +struct ipsecdoi_pl_sa; +struct saprop; +struct saproto; +struct satrns; +struct prop_pair; + +extern int ipsecdoi_checkph1proposal __P((vchar_t *, struct ph1handle *)); +extern int ipsecdoi_selectph2proposal __P((struct ph2handle *)); +extern int ipsecdoi_checkph2proposal __P((struct ph2handle *)); + +extern struct prop_pair **get_proppair __P((vchar_t *, int)); +extern vchar_t *get_sabyproppair __P((u_int32_t, u_int32_t, struct prop_pair *)); +extern int ipsecdoi_updatespi __P((struct ph2handle *iph2)); +extern vchar_t *get_sabysaprop __P((struct saprop *, vchar_t *)); +extern int ipsecdoi_chkcmpids( const vchar_t *, const vchar_t *, int ); +extern int ipsecdoi_checkid1 __P((struct ph1handle *)); +extern int ipsecdoi_setid1 __P((struct ph1handle *)); +extern int set_identifier __P((vchar_t **, int, vchar_t *)); +extern int set_identifier_qual __P((vchar_t **, int, vchar_t *, int)); +extern int ipsecdoi_setid2 __P((struct ph2handle *)); +extern vchar_t *ipsecdoi_sockaddr2id __P((struct sockaddr *, u_int, u_int)); +extern int ipsecdoi_id2sockaddr __P((vchar_t *, struct sockaddr *, + u_int8_t *, u_int16_t *)); +extern char *ipsecdoi_id2str __P((const vchar_t *)); +extern vchar_t *ipsecdoi_sockrange2id __P(( struct sockaddr *, + struct sockaddr *, u_int)); + +extern vchar_t *ipsecdoi_setph1proposal __P((struct remoteconf *, + struct isakmpsa *)); +extern int ipsecdoi_setph2proposal __P((struct ph2handle *)); +extern int ipsecdoi_transportmode __P((struct saprop *)); +extern int ipsecdoi_get_defaultlifetime __P((void)); +extern int ipsecdoi_checkalgtypes __P((int, int, int, int)); +extern int ipproto2doi __P((int)); +extern int doi2ipproto __P((int)); + +extern int ipsecdoi_t2satrns __P((struct isakmp_pl_t *, + struct saprop *, struct saproto *, struct satrns *)); +extern int ipsecdoi_authalg2trnsid __P((int)); +extern int idtype2doi __P((int)); +extern int doi2idtype __P((int)); + +extern int ipsecdoi_parse_responder_lifetime __P((struct isakmp_pl_n *notify, + u_int32_t *lifetime_sec, u_int32_t *liftime_kb)); + + +#endif /* _IPSEC_DOI_H */ diff --git a/ipsec-tools/src/racoon/isakmp.c b/ipsec-tools/src/racoon/isakmp.c new file mode 100644 index 00000000..2672f7ae --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp.c @@ -0,0 +1,3698 @@ +/* $NetBSD: isakmp.c,v 1.71.2.2 2012/08/29 08:55:26 tteras Exp $ */ + +/* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include + +#include PATH_IPSEC_H + +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#ifdef ENABLE_HYBRID +#include +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "schedule.h" +#include "session.h" +#include "debug.h" + +#include "remoteconf.h" +#include "localconf.h" +#include "grabmyaddr.h" +#include "admin.h" +#include "privsep.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "oakley.h" +#include "evt.h" +#include "handler.h" +#include "ipsec_doi.h" +#include "pfkey.h" +#include "crypto_openssl.h" +#include "policy.h" +#include "algorithm.h" +#include "proposal.h" +#include "sainfo.h" +#include "isakmp_ident.h" +#include "isakmp_agg.h" +#include "isakmp_base.h" +#include "isakmp_quick.h" +#include "isakmp_inf.h" +#include "isakmp_newg.h" +#ifdef ENABLE_HYBRID +#include "vendorid.h" +#include "isakmp_xauth.h" +#include "isakmp_unity.h" +#include "isakmp_cfg.h" +#endif +#ifdef ENABLE_FRAG +#include "isakmp_frag.h" +#endif +#include "strnames.h" + +#include + +#ifdef ENABLE_NATT +# include "nattraversal.h" +#endif +# ifdef __linux__ +# include +# include +# ifndef SOL_UDP +# define SOL_UDP 17 +# endif +# endif /* __linux__ */ +# if defined(__NetBSD__) || defined(__FreeBSD__) || \ + (defined(__APPLE__) && defined(__MACH__)) +# include +# include +# include +# include +# define SOL_UDP IPPROTO_UDP +# endif /* __NetBSD__ / __FreeBSD__ */ + +static int nostate1 __P((struct ph1handle *, vchar_t *)); +static int nostate2 __P((struct ph2handle *, vchar_t *)); + +extern caddr_t val2str(const char *, size_t); + +static int (*ph1exchange[][2][PHASE1ST_MAX]) + __P((struct ph1handle *, vchar_t *)) = { + /* error */ + { { 0 }, { 0 }, }, + /* Identity Protection exchange */ + { + { nostate1, ident_i1send, nostate1, ident_i2recv, ident_i2send, + ident_i3recv, ident_i3send, ident_i4recv, ident_i4send, nostate1, nostate1,}, + { nostate1, ident_r1recv, ident_r1send, ident_r2recv, ident_r2send, + ident_r3recv, ident_r3send, nostate1, nostate1, nostate1, nostate1, }, + }, + /* Aggressive exchange */ + { + { nostate1, agg_i1send, nostate1, agg_i2recv, agg_i2send, + nostate1, nostate1, nostate1, nostate1, nostate1, nostate1, }, + { nostate1, agg_r1recv, agg_r1send, agg_r2recv, agg_r2send, + nostate1, nostate1, nostate1, nostate1, nostate1, nostate1, }, + }, + /* Base exchange */ + { + { nostate1, base_i1send, nostate1, base_i2recv, base_i2send, + base_i3recv, base_i3send, nostate1, nostate1, nostate1, nostate1, }, + { nostate1, base_r1recv, base_r1send, base_r2recv, base_r2send, + nostate1, nostate1, nostate1, nostate1, nostate1, nostate1, }, + }, +}; + +static int (*ph2exchange[][2][PHASE2ST_MAX]) + __P((struct ph2handle *, vchar_t *)) = { + /* error */ + { { 0 }, { 0 }, }, + /* Quick mode for IKE */ + { + { nostate2, nostate2, quick_i1prep, nostate2, quick_i1send, + quick_i2recv, quick_i2send, quick_i3recv, nostate2, nostate2, }, + { nostate2, quick_r1recv, quick_r1prep, nostate2, quick_r2send, + quick_r3recv, quick_r3prep, quick_r3send, nostate2, nostate2, } + }, +}; + +static u_char r_ck0[] = { 0,0,0,0,0,0,0,0 }; /* used to verify the r_ck. */ + +static int isakmp_main __P((vchar_t *, struct sockaddr *, struct sockaddr *)); +static int ph1_main __P((struct ph1handle *, vchar_t *)); +static int quick_main __P((struct ph2handle *, vchar_t *)); +static int isakmp_ph1begin_r __P((vchar_t *, + struct sockaddr *, struct sockaddr *, u_int8_t)); +static int isakmp_ph2begin_i __P((struct ph1handle *, struct ph2handle *)); +static int isakmp_ph2begin_r __P((struct ph1handle *, vchar_t *)); +static int etypesw1 __P((int)); +static int etypesw2 __P((int)); +static int isakmp_ph1resend __P((struct ph1handle *)); +static int isakmp_ph2resend __P((struct ph2handle *)); + +#ifdef ENABLE_FRAG +static int frag_handler(struct ph1handle *, + vchar_t *, struct sockaddr *, struct sockaddr *); +#endif + +/* + * isakmp packet handler + */ +static int +isakmp_handler(ctx, so_isakmp) + void *ctx; + int so_isakmp; +{ + struct isakmp isakmp; + union { + char buf[sizeof (isakmp) + 4]; + u_int32_t non_esp[2]; + struct { + struct udphdr udp; +#ifdef __linux + struct iphdr ip; +#else + struct ip ip; +#endif + char buf[sizeof(isakmp) + 4]; + } lbuf; + } x; + struct sockaddr_storage remote; + struct sockaddr_storage local; + unsigned int remote_len = sizeof(remote); + unsigned int local_len = sizeof(local); + int len = 0, extralen = 0; + vchar_t *buf = NULL, *tmpbuf = NULL; + int error = -1, res; + + /* read message by MSG_PEEK */ + while ((len = recvfromto(so_isakmp, x.buf, sizeof(x), + MSG_PEEK, (struct sockaddr *)&remote, &remote_len, + (struct sockaddr *)&local, &local_len)) < 0) { + if (errno == EINTR) + continue; + plog(LLV_ERROR, LOCATION, NULL, + "failed to receive isakmp packet: %s\n", + strerror (errno)); + goto end; + } + + /* keep-alive packet - ignore */ + if (len == 1 && (x.buf[0]&0xff) == 0xff) { + /* Pull the keep-alive packet */ + if ((len = recvfrom(so_isakmp, (char *)x.buf, 1, + 0, (struct sockaddr *)&remote, &remote_len)) != 1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to receive keep alive packet: %s\n", + strerror (errno)); + } + goto end; + } + + /* Lucent IKE in UDP encapsulation */ + { +#ifdef __linux__ + if (ntohs(x.lbuf.udp.dest) == 501) { + extralen += sizeof(x.lbuf.udp) + x.lbuf.ip.ihl; + } +#else + if (ntohs(x.lbuf.udp.uh_dport) == 501) { + extralen += sizeof(x.lbuf.udp) + x.lbuf.ip.ip_hl; + } +#endif + } + +#ifdef ENABLE_NATT + /* we don't know about portchange yet, + look for non-esp marker instead */ + if (x.non_esp[0] == 0 && x.non_esp[1] != 0) + extralen = NON_ESP_MARKER_LEN; +#endif + + /* now we know if there is an extra non-esp + marker at the beginning or not */ + memcpy ((char *)&isakmp, x.buf + extralen, sizeof (isakmp)); + + /* check isakmp header length, as well as sanity of header length */ + if (len < sizeof(isakmp) || ntohl(isakmp.len) < sizeof(isakmp)) { + plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote, + "packet shorter than isakmp header size (%u, %u, %zu)\n", + len, ntohl(isakmp.len), sizeof(isakmp)); + /* dummy receive */ + if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp), + 0, (struct sockaddr *)&remote, &remote_len)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to receive isakmp packet: %s\n", + strerror (errno)); + } + goto end; + } + + /* reject it if the size is tooooo big. */ + if (ntohl(isakmp.len) > 0xffff) { + plog(LLV_ERROR, LOCATION, NULL, + "the length in the isakmp header is too big.\n"); + if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp), + 0, (struct sockaddr *)&remote, &remote_len)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to receive isakmp packet: %s\n", + strerror (errno)); + } + goto end; + } + + /* read real message */ + if ((tmpbuf = vmalloc(ntohl(isakmp.len) + extralen)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate reading buffer (%u Bytes)\n", + ntohl(isakmp.len) + extralen); + /* dummy receive */ + if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp), + 0, (struct sockaddr *)&remote, &remote_len)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to receive isakmp packet: %s\n", + strerror (errno)); + } + goto end; + } + + while ((len = recvfromto(so_isakmp, (char *)tmpbuf->v, tmpbuf->l, + 0, (struct sockaddr *)&remote, &remote_len, + (struct sockaddr *)&local, &local_len)) < 0) { + if (errno == EINTR) + continue; + plog(LLV_ERROR, LOCATION, NULL, + "failed to receive isakmp packet: %s\n", + strerror (errno)); + goto end; + } + + if ((buf = vmalloc(len - extralen)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate reading buffer (%u Bytes)\n", + (len - extralen)); + goto end; + } + + memcpy (buf->v, tmpbuf->v + extralen, buf->l); + + len -= extralen; + + if (len != buf->l) { + plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote, + "received invalid length (%d != %zu), why ?\n", + len, buf->l); + goto end; + } + + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); + plog(LLV_DEBUG, LOCATION, NULL, + "%d bytes message received %s\n", + len, saddr2str_fromto("from %s to %s", + (struct sockaddr *)&remote, + (struct sockaddr *)&local)); + plogdump(LLV_DEBUG, buf->v, buf->l); + + /* avoid packets with malicious port/address */ + if (extract_port((struct sockaddr *)&remote) == 0) { + plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote, + "src port == 0 (valid as UDP but not with IKE)\n"); + goto end; + } + + /* XXX: check sender whether to be allowed or not to accept */ + + /* XXX: I don't know how to check isakmp half connection attack. */ + + /* simply reply if the packet was processed. */ + res=check_recvdpkt((struct sockaddr *)&remote,(struct sockaddr *)&local, buf); + if (res) { + plog(LLV_NOTIFY, LOCATION, NULL, + "the packet is retransmitted by %s (%d).\n", + saddr2str((struct sockaddr *)&remote), res); + error = 0; + goto end; + } + + /* isakmp main routine */ + if (isakmp_main(buf, (struct sockaddr *)&remote, + (struct sockaddr *)&local) != 0) goto end; + + error = 0; + +end: + if (tmpbuf != NULL) + vfree(tmpbuf); + if (buf != NULL) + vfree(buf); + return error; +} + +/* + * main processing to handle isakmp payload + */ +static int +isakmp_main(msg, remote, local) + vchar_t *msg; + struct sockaddr *remote, *local; +{ + struct isakmp *isakmp = (struct isakmp *)msg->v; + isakmp_index *index = (isakmp_index *)isakmp; + u_int32_t msgid = isakmp->msgid; + struct ph1handle *iph1; + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(msg, remote, local, 0); +#endif + + /* the initiator's cookie must not be zero */ + if (memcmp(&isakmp->i_ck, r_ck0, sizeof(cookie_t)) == 0) { + plog(LLV_ERROR, LOCATION, remote, + "malformed cookie received.\n"); + return -1; + } + + /* Check the Major and Minor Version fields. */ + /* + * XXX Is is right to check version here ? + * I think it may no be here because the version depends + * on exchange status. + */ + if (isakmp->v < ISAKMP_VERSION_NUMBER) { + if (ISAKMP_GETMAJORV(isakmp->v) < ISAKMP_MAJOR_VERSION) { + plog(LLV_ERROR, LOCATION, remote, + "invalid major version %d.\n", + ISAKMP_GETMAJORV(isakmp->v)); + return -1; + } +#if ISAKMP_MINOR_VERSION > 0 + if (ISAKMP_GETMINORV(isakmp->v) < ISAKMP_MINOR_VERSION) { + plog(LLV_ERROR, LOCATION, remote, + "invalid minor version %d.\n", + ISAKMP_GETMINORV(isakmp->v)); + return -1; + } +#endif + } + + /* check the Flags field. */ + /* XXX How is the exclusive check, E and A ? */ + if (isakmp->flags & ~(ISAKMP_FLAG_E | ISAKMP_FLAG_C | ISAKMP_FLAG_A)) { + plog(LLV_ERROR, LOCATION, remote, + "invalid flag 0x%02x.\n", isakmp->flags); + return -1; + } + + /* ignore commit bit. */ + if (ISSET(isakmp->flags, ISAKMP_FLAG_C)) { + if (isakmp->msgid == 0) { + isakmp_info_send_nx(isakmp, remote, local, + ISAKMP_NTYPE_INVALID_FLAGS, NULL); + plog(LLV_ERROR, LOCATION, remote, + "Commit bit on phase1 forbidden.\n"); + return -1; + } + } + + iph1 = getph1byindex(index); + if (iph1 != NULL) { + /* validity check */ + if (memcmp(&isakmp->r_ck, r_ck0, sizeof(cookie_t)) == 0 && + iph1->side == INITIATOR) { + plog(LLV_DEBUG, LOCATION, remote, + "malformed cookie received or " + "the initiator's cookies collide.\n"); + return -1; + } + +#ifdef ENABLE_NATT + /* Floating ports for NAT-T */ + if (NATT_AVAILABLE(iph1) && + ! (iph1->natt_flags & NAT_PORTS_CHANGED) && + ((cmpsaddr(iph1->remote, remote) != CMPSADDR_MATCH) || + (cmpsaddr(iph1->local, local) != CMPSADDR_MATCH))) + { + /* prevent memory leak */ + racoon_free(iph1->remote); + racoon_free(iph1->local); + iph1->remote = NULL; + iph1->local = NULL; + + /* copy-in new addresses */ + iph1->remote = dupsaddr(remote); + if (iph1->remote == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "phase1 failed: dupsaddr failed.\n"); + remph1(iph1); + delph1(iph1); + return -1; + } + iph1->local = dupsaddr(local); + if (iph1->local == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "phase1 failed: dupsaddr failed.\n"); + remph1(iph1); + delph1(iph1); + return -1; + } + + /* set the flag to prevent further port floating + (FIXME: should we allow it? E.g. when the NAT gw + is rebooted?) */ + iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER; + + /* print some neat info */ + plog (LLV_INFO, LOCATION, NULL, + "NAT-T: ports changed to: %s\n", + saddr2str_fromto ("%s<->%s", iph1->remote, iph1->local)); + + natt_keepalive_add_ph1 (iph1); + } +#endif + + /* must be same addresses in one stream of a phase at least. */ + if (cmpsaddr(iph1->remote, remote) != CMPSADDR_MATCH) { + char *saddr_db, *saddr_act; + + saddr_db = racoon_strdup(saddr2str(iph1->remote)); + saddr_act = racoon_strdup(saddr2str(remote)); + STRDUP_FATAL(saddr_db); + STRDUP_FATAL(saddr_act); + + plog(LLV_WARNING, LOCATION, remote, + "remote address mismatched. db=%s, act=%s\n", + saddr_db, saddr_act); + + racoon_free(saddr_db); + racoon_free(saddr_act); + } + + /* + * don't check of exchange type here because other type will be + * with same index, for example, informational exchange. + */ + + /* XXX more acceptable check */ + } + + switch (isakmp->etype) { + case ISAKMP_ETYPE_IDENT: + case ISAKMP_ETYPE_AGG: + case ISAKMP_ETYPE_BASE: + /* phase 1 validity check */ + if (isakmp->msgid != 0) { + plog(LLV_ERROR, LOCATION, remote, + "message id should be zero in phase1.\n"); + return -1; + } + + /* search for isakmp status record of phase 1 */ + if (iph1 == NULL) { + /* + * the packet must be the 1st message from a initiator + * or the 2nd message from the responder. + */ + + /* search for phase1 handle by index without r_ck */ + iph1 = getph1byindex0(index); + if (iph1 == NULL) { + /*it must be the 1st message from a initiator.*/ + if (memcmp(&isakmp->r_ck, r_ck0, + sizeof(cookie_t)) != 0) { + + plog(LLV_DEBUG, LOCATION, remote, + "malformed cookie received " + "or the spi expired.\n"); + return -1; + } + + /* it must be responder's 1st exchange. */ + if (isakmp_ph1begin_r(msg, remote, local, + isakmp->etype) < 0) + return -1; + break; + + /*NOTREACHED*/ + } + + /* it must be the 2nd message from the responder. */ + if (iph1->side != INITIATOR) { + plog(LLV_DEBUG, LOCATION, remote, + "malformed cookie received. " + "it has to be as the initiator. %s\n", + isakmp_pindex(&iph1->index, 0)); + return -1; + } + } + + /* + * Don't delete phase 1 handler when the exchange type + * in handler is not equal to packet's one because of no + * authencication completed. + */ + if (iph1->etype != isakmp->etype) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "exchange type is mismatched: " + "db=%s packet=%s, ignore it.\n", + s_isakmp_etype(iph1->etype), + s_isakmp_etype(isakmp->etype)); + return -1; + } + +#ifdef ENABLE_FRAG + if (isakmp->np == ISAKMP_NPTYPE_FRAG) + return frag_handler(iph1, msg, remote, local); +#endif + + /* call main process of phase 1 */ + if (ph1_main(iph1, msg) < 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "phase1 negotiation failed.\n"); + remph1(iph1); + delph1(iph1); + return -1; + } + break; + + case ISAKMP_ETYPE_AUTH: + plog(LLV_INFO, LOCATION, remote, + "unsupported exchange %d received.\n", + isakmp->etype); + break; + + case ISAKMP_ETYPE_INFO: + case ISAKMP_ETYPE_ACKINFO: + /* + * iph1 must be present for Information message. + * if iph1 is null then trying to get the phase1 status + * as the packet from responder againt initiator's 1st + * exchange in phase 1. + * NOTE: We think such informational exchange should be ignored. + */ + if (iph1 == NULL) { + iph1 = getph1byindex0(index); + if (iph1 == NULL) { + plog(LLV_ERROR, LOCATION, remote, + "unknown Informational " + "exchange received.\n"); + return -1; + } + if (cmpsaddr(iph1->remote, remote) != CMPSADDR_MATCH) { + plog(LLV_WARNING, LOCATION, remote, + "remote address mismatched. " + "db=%s\n", + saddr2str(iph1->remote)); + } + } + +#ifdef ENABLE_FRAG + if (isakmp->np == ISAKMP_NPTYPE_FRAG) + return frag_handler(iph1, msg, remote, local); +#endif + + if (isakmp_info_recv(iph1, msg) < 0) + return -1; + break; + + case ISAKMP_ETYPE_QUICK: + { + struct ph2handle *iph2; + + if (iph1 == NULL) { + isakmp_info_send_nx(isakmp, remote, local, + ISAKMP_NTYPE_INVALID_COOKIE, NULL); + plog(LLV_ERROR, LOCATION, remote, + "can't start the quick mode, " + "there is no ISAKMP-SA, %s\n", + isakmp_pindex((isakmp_index *)&isakmp->i_ck, + isakmp->msgid)); + return -1; + } +#ifdef ENABLE_HYBRID + /* Reinit the IVM if it's still there */ + if (iph1->mode_cfg && iph1->mode_cfg->ivm) { + oakley_delivm(iph1->mode_cfg->ivm); + iph1->mode_cfg->ivm = NULL; + } +#endif +#ifdef ENABLE_FRAG + if (isakmp->np == ISAKMP_NPTYPE_FRAG) + return frag_handler(iph1, msg, remote, local); +#endif + + /* check status of phase 1 whether negotiated or not. */ + if (iph1->status != PHASE1ST_ESTABLISHED && + iph1->status != PHASE1ST_DYING) { + plog(LLV_ERROR, LOCATION, remote, + "can't start the quick mode, " + "there is no valid ISAKMP-SA, %s\n", + isakmp_pindex(&iph1->index, iph1->msgid)); + return -1; + } + + /* search isakmp phase 2 stauts record. */ + iph2 = getph2bymsgid(iph1, msgid); + if (iph2 == NULL) { + /* it must be new negotiation as responder */ + if (isakmp_ph2begin_r(iph1, msg) < 0) + return -1; + return 0; + /*NOTREACHED*/ + } + + /* commit bit. */ + /* XXX + * we keep to set commit bit during negotiation. + * When SA is configured, bit will be reset. + * XXX + * don't initiate commit bit. should be fixed in the future. + */ + if (ISSET(isakmp->flags, ISAKMP_FLAG_C)) + iph2->flags |= ISAKMP_FLAG_C; + + /* call main process of quick mode */ + if (quick_main(iph2, msg) < 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "phase2 negotiation failed.\n"); + remph2(iph2); + delph2(iph2); + return -1; + } + } + break; + + case ISAKMP_ETYPE_NEWGRP: + if (iph1 == NULL) { + plog(LLV_ERROR, LOCATION, remote, + "Unknown new group mode exchange, " + "there is no ISAKMP-SA.\n"); + return -1; + } + +#ifdef ENABLE_FRAG + if (isakmp->np == ISAKMP_NPTYPE_FRAG) + return frag_handler(iph1, msg, remote, local); +#endif + + isakmp_newgroup_r(iph1, msg); + break; + +#ifdef ENABLE_HYBRID + case ISAKMP_ETYPE_CFG: + if (iph1 == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "mode config %d from %s, " + "but we have no ISAKMP-SA.\n", + isakmp->etype, saddr2str(remote)); + return -1; + } + +#ifdef ENABLE_FRAG + if (isakmp->np == ISAKMP_NPTYPE_FRAG) + return frag_handler(iph1, msg, remote, local); +#endif + + isakmp_cfg_r(iph1, msg); + break; +#endif + + case ISAKMP_ETYPE_NONE: + default: + plog(LLV_ERROR, LOCATION, NULL, + "Invalid exchange type %d from %s.\n", + isakmp->etype, saddr2str(remote)); + return -1; + } + + return 0; +} + +/* + * main function of phase 1. + */ +static int +ph1_main(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + int error; +#ifdef ENABLE_STATS + struct timeval start, end; +#endif + + /* ignore a packet */ + if (iph1->status >= PHASE1ST_ESTABLISHED) + return 0; + +#ifdef ENABLE_STATS + gettimeofday(&start, NULL); +#endif + /* receive */ + if (ph1exchange[etypesw1(iph1->etype)] + [iph1->side] + [iph1->status] == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "why isn't the function defined.\n"); + return -1; + } + error = (ph1exchange[etypesw1(iph1->etype)] + [iph1->side] + [iph1->status])(iph1, msg); + if (error != 0) { + + /* XXX + * When an invalid packet is received on phase1, it should + * be selected to process this packet. That is to respond + * with a notify and delete phase 1 handler, OR not to respond + * and keep phase 1 handler. However, in PHASE1ST_START when + * acting as RESPONDER we must not keep phase 1 handler or else + * it will stay forever. + */ + + if (iph1->side == RESPONDER && iph1->status == PHASE1ST_START) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to pre-process ph1 packet (side: %d, status %d).\n", + iph1->side, iph1->status); + return -1; + } else { + /* ignore the error and keep phase 1 handler */ + return 0; + } + } + +#ifndef ENABLE_FRAG + /* free resend buffer */ + if (iph1->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no buffer found as sendbuf\n"); + return -1; + } +#endif + + VPTRINIT(iph1->sendbuf); + + /* turn off schedule */ + sched_cancel(&iph1->scr); + + /* send */ + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); + if ((ph1exchange[etypesw1(iph1->etype)] + [iph1->side] + [iph1->status])(iph1, msg) != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to process ph1 packet (side: %d, status: %d).\n", + iph1->side, iph1->status); + return -1; + } + +#ifdef ENABLE_STATS + gettimeofday(&end, NULL); + syslog(LOG_NOTICE, "%s(%s): %8.6f", + "phase1", s_isakmp_state(iph1->etype, iph1->side, iph1->status), + timedelta(&start, &end)); +#endif + if (iph1->status == PHASE1ST_ESTABLISHED) { + +#ifdef ENABLE_STATS + gettimeofday(&iph1->end, NULL); + syslog(LOG_NOTICE, "%s(%s): %8.6f", + "phase1", s_isakmp_etype(iph1->etype), + timedelta(&iph1->start, &iph1->end)); +#endif + + /* save created date. */ + (void)time(&iph1->created); + + /* migrate ph2s from dying ph1s */ + migrate_dying_ph12(iph1); + + /* add to the schedule to expire, and seve back pointer. */ + if (ph1_rekey_enabled(iph1)) { + sched_schedule(&iph1->sce, + iph1->approval->lifetime * + PFKEY_SOFT_LIFETIME_RATE / 100, + isakmp_ph1dying_stub); + } else { + sched_schedule(&iph1->sce, iph1->approval->lifetime, + isakmp_ph1expire_stub); + } + +#ifdef ENABLE_HYBRID + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: + xauth_sendreq(iph1); + /* XXX Don't process INITIAL_CONTACT */ + iph1->rmconf->ini_contact = 0; + break; + default: + break; + } + } +#endif +#ifdef ENABLE_DPD + /* Schedule the r_u_there.... */ + if(iph1->dpd_support && iph1->rmconf->dpd_interval) + isakmp_sched_r_u(iph1, 0); +#endif + + /* INITIAL-CONTACT processing */ + /* don't anything if local test mode. */ + if (!f_local + && iph1->rmconf->ini_contact && !getcontacted(iph1->remote)) { + /* send INITIAL-CONTACT */ + isakmp_info_send_n1(iph1, + ISAKMP_NTYPE_INITIAL_CONTACT, NULL); + /* insert a node into contacted list. */ + if (inscontacted(iph1->remote) == -1) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to add contacted list.\n"); + /* ignore */ + } + } + if (iph1->initial_contact_received) + isakmp_info_recv_initialcontact(iph1, NULL); + + log_ph1established(iph1); + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); + + /* + * SA up shell script hook: do it now,except if + * ISAKMP mode config was requested. In the later + * case it is done when we receive the configuration. + */ + if ((iph1->status == PHASE1ST_ESTABLISHED) && + !iph1->rmconf->mode_cfg) { + switch (iph1->approval->authmethod) { +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + /* Unimplemeted... */ + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: + break; +#endif + default: + script_hook(iph1, SCRIPT_PHASE1_UP); + break; + } + } + } + + return 0; +} + +/* + * main function of quick mode. + */ +static int +quick_main(iph2, msg) + struct ph2handle *iph2; + vchar_t *msg; +{ + struct isakmp *isakmp = (struct isakmp *)msg->v; + int error; +#ifdef ENABLE_STATS + struct timeval start, end; +#endif + + /* ignore a packet */ + if (iph2->status == PHASE2ST_ESTABLISHED + || iph2->status == PHASE2ST_GETSPISENT) + return 0; + +#ifdef ENABLE_STATS + gettimeofday(&start, NULL); +#endif + + /* receive */ + if (ph2exchange[etypesw2(isakmp->etype)] + [iph2->side] + [iph2->status] == NULL) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "why isn't the function defined.\n"); + return -1; + } + error = (ph2exchange[etypesw2(isakmp->etype)] + [iph2->side] + [iph2->status])(iph2, msg); + if (error != 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "failed to pre-process ph2 packet (side: %d, status %d).\n", + iph2->side, iph2->status); + if (error == ISAKMP_INTERNAL_ERROR) + return 0; + isakmp_info_send_n1(iph2->ph1, error, NULL); + return -1; + } + + /* when using commit bit, status will be reached here. */ + if (iph2->status == PHASE2ST_ADDSA) + return 0; + + /* free resend buffer */ + if (iph2->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no buffer found as sendbuf\n"); + return -1; + } + VPTRINIT(iph2->sendbuf); + + /* turn off schedule */ + sched_cancel(&iph2->scr); + + /* send */ + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); + if ((ph2exchange[etypesw2(isakmp->etype)] + [iph2->side] + [iph2->status])(iph2, msg) != 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "failed to process ph2 packet (side: %d, status: %d).\n", + iph2->side, iph2->status); + return -1; + } + +#ifdef ENABLE_STATS + gettimeofday(&end, NULL); + syslog(LOG_NOTICE, "%s(%s): %8.6f", + "phase2", + s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status), + timedelta(&start, &end)); +#endif + + return 0; +} + +/* new negotiation of phase 1 for initiator */ +struct ph1handle * +isakmp_ph1begin_i(rmconf, remote, local) + struct remoteconf *rmconf; + struct sockaddr *remote, *local; +{ + struct ph1handle *iph1; +#ifdef ENABLE_STATS + struct timeval start, end; +#endif + + /* get new entry to isakmp status table. */ + iph1 = newph1(); + if (iph1 == NULL) + return NULL; + + iph1->status = PHASE1ST_START; + iph1->rmconf = rmconf; + iph1->side = INITIATOR; + iph1->version = ISAKMP_VERSION_NUMBER; + iph1->msgid = 0; + iph1->flags = 0; + iph1->ph2cnt = 0; +#ifdef HAVE_GSSAPI + iph1->gssapi_state = NULL; +#endif +#ifdef ENABLE_HYBRID + if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { + delph1(iph1); + return NULL; + } +#endif +#ifdef ENABLE_FRAG + + if(rmconf->ike_frag == ISAKMP_FRAG_FORCE) + iph1->frag = 1; + else + iph1->frag = 0; + iph1->frag_chain = NULL; +#endif + iph1->approval = NULL; + + /* XXX copy remote address */ + if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) { + delph1(iph1); + return NULL; + } + + (void)insph1(iph1); + + /* start phase 1 exchange */ + iph1->etype = rmconf->etypes->type; + + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); + { + char *a; + + a = racoon_strdup(saddr2str(iph1->local)); + STRDUP_FATAL(a); + + plog(LLV_INFO, LOCATION, NULL, + "initiate new phase 1 negotiation: %s<=>%s\n", + a, saddr2str(iph1->remote)); + racoon_free(a); + } + plog(LLV_INFO, LOCATION, NULL, + "begin %s mode.\n", + s_isakmp_etype(iph1->etype)); + +#ifdef ENABLE_STATS + gettimeofday(&iph1->start, NULL); + gettimeofday(&start, NULL); +#endif + /* start exchange */ + if ((ph1exchange[etypesw1(iph1->etype)] + [iph1->side] + [iph1->status])(iph1, NULL) != 0) { + /* failed to start phase 1 negotiation */ + remph1(iph1); + delph1(iph1); + + return NULL; + } + +#ifdef ENABLE_STATS + gettimeofday(&end, NULL); + syslog(LOG_NOTICE, "%s(%s): %8.6f", + "phase1", + s_isakmp_state(iph1->etype, iph1->side, iph1->status), + timedelta(&start, &end)); +#endif + + return iph1; +} + +/* new negotiation of phase 1 for responder */ +static int +isakmp_ph1begin_r(msg, remote, local, etype) + vchar_t *msg; + struct sockaddr *remote, *local; + u_int8_t etype; +{ + struct isakmp *isakmp = (struct isakmp *)msg->v; + struct ph1handle *iph1; + struct rmconfselector rmsel; +#ifdef ENABLE_STATS + struct timeval start, end; +#endif + + /* check if this etype is allowed */ + memset(&rmsel, 0, sizeof(rmsel)); + rmsel.remote = remote; + if (enumrmconf(&rmsel, check_etypeok, (void *) (intptr_t) etype) == 0) { + plog(LLV_ERROR, LOCATION, remote, + "exchange %s not allowed in any applicable rmconf.\n", + s_isakmp_etype(etype)); + return -1; + } + + /* get new entry to isakmp status table. */ + iph1 = newph1(); + if (iph1 == NULL) + return -1; + + memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(iph1->index.i_ck)); + iph1->status = PHASE1ST_START; + iph1->flags = 0; + iph1->side = RESPONDER; + iph1->etype = etype; + iph1->version = isakmp->v; + iph1->msgid = 0; +#ifdef HAVE_GSSAPI + iph1->gssapi_state = NULL; +#endif +#ifdef ENABLE_HYBRID + if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { + delph1(iph1); + return -1; + } +#endif +#ifdef ENABLE_FRAG + iph1->frag = 0; + iph1->frag_chain = NULL; +#endif + iph1->approval = NULL; + +#ifdef ENABLE_NATT + /* RFC3947 says that we MUST accept new phases1 on NAT-T floated port. + * We have to setup this flag now to correctly generate the first reply. + * Don't know if a better check could be done for that ? + */ + if(extract_port(local) == lcconf->port_isakmp_natt) + iph1->natt_flags |= (NAT_PORTS_CHANGED); +#endif + + /* copy remote address; remote and local always contain + * port numbers so rmconf is not needed */ + if (copy_ph1addresses(iph1, NULL, remote, local) < 0) { + delph1(iph1); + return -1; + } + (void)insph1(iph1); + + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); + { + char *a; + + a = racoon_strdup(saddr2str(iph1->local)); + STRDUP_FATAL(a); + + plog(LLV_INFO, LOCATION, NULL, + "respond new phase 1 negotiation: %s<=>%s\n", + a, saddr2str(iph1->remote)); + racoon_free(a); + } + plog(LLV_INFO, LOCATION, NULL, + "begin %s mode.\n", s_isakmp_etype(etype)); + +#ifdef ENABLE_STATS + gettimeofday(&iph1->start, NULL); + gettimeofday(&start, NULL); +#endif + +#ifndef ENABLE_FRAG + + /* start exchange */ + if ((ph1exchange[etypesw1(iph1->etype)] + [iph1->side] + [iph1->status])(iph1, msg) < 0 + || (ph1exchange[etypesw1(iph1->etype)] + [iph1->side] + [iph1->status])(iph1, msg) < 0) { + plog(LLV_ERROR, LOCATION, remote, + "failed to process ph1 packet (side: %d, status: %d).\n", + iph1->side, iph1->status); + remph1(iph1); + delph1(iph1); + return -1; + } + +#ifdef ENABLE_STATS + gettimeofday(&end, NULL); + syslog(LOG_NOTICE, "%s(%s): %8.6f", + "phase1", + s_isakmp_state(iph1->etype, iph1->side, iph1->status), + timedelta(&start, &end)); +#endif + + return 0; + +#else /* ENABLE_FRAG */ + + /* now that we have a phase1 handle, feed back into our + * main receive function to catch fragmented packets + */ + + return isakmp_main(msg, remote, local); + +#endif /* ENABLE_FRAG */ + +} + +/* new negotiation of phase 2 for initiator */ +static int +isakmp_ph2begin_i(iph1, iph2) + struct ph1handle *iph1; + struct ph2handle *iph2; +{ +#ifdef ENABLE_HYBRID + if (xauth_check(iph1) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Attempt to start phase 2 whereas Xauth failed\n"); + return -1; + } +#endif + + /* fixup ph2 ports for this ph1 */ + if (extract_port(iph2->src) == 0) + set_port(iph2->src, extract_port(iph1->local)); + if (extract_port(iph2->dst) == 0) + set_port(iph2->dst, extract_port(iph1->remote)); + + /* found ISAKMP-SA. */ + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); + plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n"); + { + char *a; + a = racoon_strdup(saddr2str(iph2->src)); + STRDUP_FATAL(a); + + plog(LLV_INFO, LOCATION, NULL, + "initiate new phase 2 negotiation: %s<=>%s\n", + a, saddr2str(iph2->dst)); + racoon_free(a); + } + +#ifdef ENABLE_STATS + gettimeofday(&iph2->start, NULL); +#endif + if (iph2->status != PHASE2ST_EXPIRED) /* Phase 1 is already bound (ongoing rekeying) */ + bindph12(iph1, iph2); + iph2->status = PHASE2ST_STATUS2; + + if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)] + [iph2->side] + [iph2->status])(iph2, NULL) < 0) { + /* release ipsecsa handler due to internal error. */ + remph2(iph2); + return -1; + } + return 0; +} + +/* new negotiation of phase 2 for responder */ +static int +isakmp_ph2begin_r(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + struct isakmp *isakmp = (struct isakmp *)msg->v; + struct ph2handle *iph2 = 0; + int error; +#ifdef ENABLE_STATS + struct timeval start, end; +#endif +#ifdef ENABLE_HYBRID + if (xauth_check(iph1) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Attempt to start phase 2 whereas Xauth failed\n"); + return -1; + } +#endif + + iph2 = newph2(); + if (iph2 == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate phase2 entry.\n"); + return -1; + } + + iph2->side = RESPONDER; + iph2->status = PHASE2ST_START; + iph2->flags = isakmp->flags; + iph2->msgid = isakmp->msgid; + iph2->seq = pk_getseq(); + iph2->ivm = oakley_newiv2(iph1, iph2->msgid); + if (iph2->ivm == NULL) { + delph2(iph2); + return -1; + } + iph2->dst = dupsaddr(iph1->remote); /* XXX should be considered */ + if (iph2->dst == NULL) { + delph2(iph2); + return -1; + } + iph2->src = dupsaddr(iph1->local); /* XXX should be considered */ + if (iph2->src == NULL) { + delph2(iph2); + return -1; + } + + /* add new entry to isakmp status table */ + insph2(iph2); + bindph12(iph1, iph2); + + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); + { + char *a; + + a = racoon_strdup(saddr2str(iph2->src)); + STRDUP_FATAL(a); + + plog(LLV_INFO, LOCATION, NULL, + "respond new phase 2 negotiation: %s<=>%s\n", + a, saddr2str(iph2->dst)); + racoon_free(a); + } + +#ifdef ENABLE_STATS + gettimeofday(&start, NULL); +#endif + + error = (ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)] + [iph2->side] + [iph2->status])(iph2, msg); + if (error != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to pre-process ph2 packet (side: %d, status: %d).\n", + iph2->side, iph2->status); + if (error != ISAKMP_INTERNAL_ERROR) + isakmp_info_send_n1(iph2->ph1, error, NULL); + /* + * release handler because it's wrong that ph2handle is kept + * after failed to check message for responder's. + */ + remph2(iph2); + delph2(iph2); + return -1; + } + + /* send */ + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); + if ((ph2exchange[etypesw2(isakmp->etype)] + [iph2->side] + [iph2->status])(iph2, msg) < 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "failed to process ph2 packet (side: %d, status: %d).\n", + iph2->side, iph2->status); + /* don't release handler */ + return -1; + } +#ifdef ENABLE_STATS + gettimeofday(&end, NULL); + syslog(LOG_NOTICE, "%s(%s): %8.6f", + "phase2", + s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status), + timedelta(&start, &end)); +#endif + + return 0; +} + +/* + * parse ISAKMP payloads, without ISAKMP base header. + */ +vchar_t * +isakmp_parsewoh(np0, gen, len) + int np0; + struct isakmp_gen *gen; + int len; +{ + u_char np = np0 & 0xff; + int tlen, plen; + vchar_t *result; + struct isakmp_parse_t *p, *ep; + + plog(LLV_DEBUG, LOCATION, NULL, "begin.\n"); + + /* + * 5 is a magic number, but any value larger than 2 should be fine + * as we do vrealloc() in the following loop. + */ + result = vmalloc(sizeof(struct isakmp_parse_t) * 5); + if (result == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer.\n"); + return NULL; + } + p = (struct isakmp_parse_t *)result->v; + ep = (struct isakmp_parse_t *)(result->v + result->l - sizeof(*ep)); + + tlen = len; + + /* parse through general headers */ + while (0 < tlen && np != ISAKMP_NPTYPE_NONE) { + if (tlen <= sizeof(struct isakmp_gen)) { + /* don't send information, see isakmp_ident_r1() */ + plog(LLV_ERROR, LOCATION, NULL, + "invalid length of payload\n"); + vfree(result); + return NULL; + } + + plog(LLV_DEBUG, LOCATION, NULL, + "seen nptype=%u(%s)\n", np, s_isakmp_nptype(np)); + + p->type = np; + p->len = ntohs(gen->len); + if (p->len < sizeof(struct isakmp_gen) || p->len > tlen) { + plog(LLV_DEBUG, LOCATION, NULL, + "invalid length of payload\n"); + vfree(result); + return NULL; + } + p->ptr = gen; + p++; + if (ep <= p) { + int off; + + off = p - (struct isakmp_parse_t *)result->v; + result = vrealloc(result, result->l * 2); + if (result == NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "failed to realloc buffer.\n"); + vfree(result); + return NULL; + } + ep = (struct isakmp_parse_t *) + (result->v + result->l - sizeof(*ep)); + p = (struct isakmp_parse_t *)result->v; + p += off; + } + + np = gen->np; + plen = ntohs(gen->len); + gen = (struct isakmp_gen *)((caddr_t)gen + plen); + tlen -= plen; + } + p->type = ISAKMP_NPTYPE_NONE; + p->len = 0; + p->ptr = NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "succeed.\n"); + + return result; +} + +/* + * parse ISAKMP payloads, including ISAKMP base header. + */ +vchar_t * +isakmp_parse(buf) + vchar_t *buf; +{ + struct isakmp *isakmp = (struct isakmp *)buf->v; + struct isakmp_gen *gen; + int tlen; + vchar_t *result; + u_char np; + + np = isakmp->np; + gen = (struct isakmp_gen *)(buf->v + sizeof(*isakmp)); + tlen = buf->l - sizeof(struct isakmp); + result = isakmp_parsewoh(np, gen, tlen); + + return result; +} + +/* %%% */ +int +isakmp_init() +{ + /* initialize a isakmp status table */ + initph1tree(); + initph2tree(); + initctdtree(); + init_recvdpkt(); + + return 0; +} + +/* + * make strings containing i_cookie + r_cookie + msgid + */ +const char * +isakmp_pindex(index, msgid) + const isakmp_index *index; + const u_int32_t msgid; +{ + static char buf[64]; + const u_char *p; + int i, j; + + memset(buf, 0, sizeof(buf)); + + /* copy index */ + p = (const u_char *)index; + for (j = 0, i = 0; i < sizeof(isakmp_index); i++) { + snprintf((char *)&buf[j], sizeof(buf) - j, "%02x", p[i]); + j += 2; + switch (i) { + case 7: + buf[j++] = ':'; + } + } + + if (msgid == 0) + return buf; + + /* copy msgid */ + snprintf((char *)&buf[j], sizeof(buf) - j, ":%08x", ntohs(msgid)); + + return buf; +} + +/* open ISAKMP sockets. */ +int +isakmp_open(struct sockaddr *addr, int udp_encap) +{ + const int yes = 1; + int ifnum = 0, encap_ifnum = 0, fd; + struct sockaddr_in *sin = (struct sockaddr_in *) addr; +#ifdef INET6 + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) addr; + int pktinfo; +#endif +#ifdef ENABLE_NATT + int option = -1; +#endif + + /* warn if wildcard address - should we forbid this? */ + switch (addr->sa_family) { + case AF_INET: + if (sin->sin_addr.s_addr == 0) + plog(LLV_WARNING, LOCATION, NULL, + "listening to wildcard address," + "broadcast IKE packet may kill you\n"); + break; +#ifdef INET6 + case AF_INET6: + if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { + plog(LLV_DEBUG, LOCATION, NULL, + "ignoring multicast address %s\n", + saddr2str(addr)); + return -1; + } + + if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) + plog(LLV_WARNING, LOCATION, NULL, + "listening to wildcard address, " + "broadcast IKE packet may kill you\n"); + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "unsupported address family %d\n", + addr->sa_family); + return -1; + } + + if ((fd = privsep_socket(addr->sa_family, SOCK_DGRAM, 0)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "socket(%s)\n", strerror(errno)); + return -1; + } + close_on_exec(fd); + if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) + plog(LLV_WARNING, LOCATION, NULL, + "failed to put socket in non-blocking mode\n"); + + /* receive my interface address on inbound packets. */ + switch (addr->sa_family) { + case AF_INET: + if (setsockopt(fd, IPPROTO_IP, +#ifdef __linux__ + IP_PKTINFO, +#else + IP_RECVDSTADDR, +#endif + (const void *) &yes, sizeof(yes)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "setsockopt IP_RECVDSTADDR (%s)\n", + strerror(errno)); + goto err; + } + +#ifdef ENABLE_NATT + if (udp_encap) + option = UDP_ENCAP_ESPINUDP; +#if defined(ENABLE_NATT_00) || defined(ENABLE_NATT_01) + else + option = UDP_ENCAP_ESPINUDP_NON_IKE; +#endif + if (option == -1) + break; + + if (setsockopt(fd, SOL_UDP, + UDP_ENCAP, &option, + sizeof(option)) < 0) { + plog(LLV_WARNING, LOCATION, NULL, + "setsockopt(%s): UDP_ENCAP %s\n", + option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE", + strerror(errno)); + } else { + plog(LLV_INFO, LOCATION, NULL, + "%s used for NAT-T\n", + saddr2str(addr)); + } +#endif + break; + +#ifdef INET6 + case AF_INET6: +#if defined(INET6_ADVAPI) +#ifdef IPV6_RECVPKTINFO + pktinfo = IPV6_RECVPKTINFO; +#else /* old adv. API */ + pktinfo = IPV6_PKTINFO; +#endif /* IPV6_RECVPKTINFO */ +#else + pktinfo = IPV6_RECVDSTADDR; +#endif + if (setsockopt(fd, IPPROTO_IPV6, pktinfo, + (const void *) &yes, sizeof(yes)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "setsockopt IPV6_RECVDSTADDR (%d):%s\n", + pktinfo, strerror(errno)); + goto err; + } + +#ifdef IPV6_USE_MIN_MTU + if (setsockopt(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, + (void *) &yes, sizeof(yes)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "setsockopt IPV6_USE_MIN_MTU (%s)\n", + strerror(errno)); + goto err; + } +#endif + break; +#endif + } + + if (setsockopt(fd, SOL_SOCKET, +#ifdef __linux__ + SO_REUSEADDR, +#else + SO_REUSEPORT, +#endif + (void *) &yes, sizeof(yes)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set REUSE flag on %s (%s).\n", + saddr2str(addr), strerror(errno)); + goto err; + } + + if (setsockopt_bypass(fd, addr->sa_family) < 0) + goto err; + + if (privsep_bind(fd, addr, sysdep_sa_len(addr)) < 0) { + plog(LLV_ERROR, LOCATION, addr, + "failed to bind to address %s (%s).\n", + saddr2str(addr), strerror(errno)); + goto err; + } + + plog(LLV_INFO, LOCATION, NULL, + "%s used as isakmp port (fd=%d)\n", + saddr2str(addr), fd); + + monitor_fd(fd, isakmp_handler, NULL, 1); + return fd; + +err: + close(fd); + return -1; +} + +void +isakmp_close(int fd) +{ + unmonitor_fd(fd); + close(fd); +} + +int +isakmp_send(iph1, sbuf) + struct ph1handle *iph1; + vchar_t *sbuf; +{ + int len = 0; + int s; + vchar_t *vbuf = NULL, swap; + +#ifdef ENABLE_NATT + size_t extralen = NON_ESP_MARKER_USE(iph1) ? NON_ESP_MARKER_LEN : 0; + + /* Check if NON_ESP_MARKER_LEN is already there (happens when resending packets) + */ + if(extralen == NON_ESP_MARKER_LEN && + *(u_int32_t *)sbuf->v == 0) + extralen = 0; + +#ifdef ENABLE_FRAG + /* + * Do not add the non ESP marker for a packet that will + * be fragmented. The non ESP marker should appear in + * all fragment's packets, but not in the fragmented packet + */ + if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN) + extralen = 0; +#endif + if (extralen) + plog (LLV_DEBUG, LOCATION, NULL, "Adding NON-ESP marker\n"); + + /* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker) + must added just before the packet itself. For this we must + allocate a new buffer and release it at the end. */ + if (extralen) { + if ((vbuf = vmalloc (sbuf->l + extralen)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "vbuf allocation failed\n"); + return -1; + } + *(u_int32_t *)vbuf->v = 0; + memcpy (vbuf->v + extralen, sbuf->v, sbuf->l); + /* ensures that the modified buffer will be sent back to the caller, so + * add_recvdpkt() will add the correct buffer + */ + swap = *sbuf; + *sbuf = *vbuf; + *vbuf = swap; + vfree(vbuf); + } +#endif + + /* select the socket to be sent */ + s = myaddr_getfd(iph1->local); + if (s == -1) + return -1; + + plog (LLV_DEBUG, LOCATION, NULL, "%zu bytes %s\n", sbuf->l, + saddr2str_fromto("from %s to %s", iph1->local, iph1->remote)); + +#ifdef ENABLE_FRAG + if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN) { + if (isakmp_sendfrags(iph1, sbuf) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "isakmp_sendfrags failed\n"); + return -1; + } + } else +#endif + { + len = sendfromto(s, sbuf->v, sbuf->l, + iph1->local, iph1->remote, lcconf->count_persend); + + if (len == -1) { + plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n"); + return -1; + } + } + + return 0; +} + +/* called from scheduler */ +static void +isakmp_ph1resend_stub(p) + struct sched *p; +{ + struct ph1handle *iph1 = container_of(p, struct ph1handle, scr); + + if (isakmp_ph1resend(iph1) < 0) { + remph1(iph1); + delph1(iph1); + } +} + +static int +isakmp_ph1resend(iph1) + struct ph1handle *iph1; +{ + /* Note: NEVER do the rem/del here, it will be done by the caller or by the _stub function + */ + if (iph1->retry_counter <= 0) { + plog(LLV_ERROR, LOCATION, NULL, + "phase1 negotiation failed due to time up. %s\n", + isakmp_pindex(&iph1->index, iph1->msgid)); + /* XXX is the peer really "dead" here ??? */ + script_hook(iph1, SCRIPT_PHASE1_DEAD); + evt_phase1(iph1, EVT_PHASE1_NO_RESPONSE, NULL); + + return -1; + } + + if (isakmp_send(iph1, iph1->sendbuf) < 0){ + plog(LLV_ERROR, LOCATION, NULL, + "phase1 negotiation failed due to send error. %s\n", + isakmp_pindex(&iph1->index, iph1->msgid)); + evt_phase1(iph1, EVT_PHASE1_NO_RESPONSE, NULL); + return -1; + } + + plog(LLV_DEBUG, LOCATION, NULL, + "resend phase1 packet %s\n", + isakmp_pindex(&iph1->index, iph1->msgid)); + + iph1->retry_counter--; + + sched_schedule(&iph1->scr, lcconf->retry_interval, + isakmp_ph1resend_stub); + + return 0; +} + +int +isakmp_ph1send(iph1) + struct ph1handle *iph1; +{ + iph1->retry_counter = lcconf->retry_counter; + return isakmp_ph1resend(iph1); +} + +/* called from scheduler */ +static void +isakmp_ph2resend_stub(p) + struct sched *p; +{ + struct ph2handle *iph2 = container_of(p, struct ph2handle, scr); + + if (isakmp_ph2resend(iph2) < 0) { + remph2(iph2); + delph2(iph2); + } +} + +static int +isakmp_ph2resend(iph2) + struct ph2handle *iph2; +{ + /* Note: NEVER do the unbind/rem/del here, it will be done by the caller or by the _stub function + */ + if (iph2->ph1->status >= PHASE1ST_EXPIRED) { + plog(LLV_ERROR, LOCATION, NULL, + "phase2 negotiation failed due to phase1 expired. %s\n", + isakmp_pindex(&iph2->ph1->index, iph2->msgid)); + return -1; + } + + if (iph2->retry_counter <= 0) { + plog(LLV_ERROR, LOCATION, NULL, + "phase2 negotiation failed due to time up. %s\n", + isakmp_pindex(&iph2->ph1->index, iph2->msgid)); + evt_phase2(iph2, EVT_PHASE2_NO_RESPONSE, NULL); + unbindph12(iph2); + return -1; + } + + if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0){ + plog(LLV_ERROR, LOCATION, NULL, + "phase2 negotiation failed due to send error. %s\n", + isakmp_pindex(&iph2->ph1->index, iph2->msgid)); + evt_phase2(iph2, EVT_PHASE2_NO_RESPONSE, NULL); + return -1; + } + + plog(LLV_DEBUG, LOCATION, NULL, + "resend phase2 packet %s\n", + isakmp_pindex(&iph2->ph1->index, iph2->msgid)); + + iph2->retry_counter--; + + sched_schedule(&iph2->scr, lcconf->retry_interval, + isakmp_ph2resend_stub); + + return 0; +} + +int +isakmp_ph2send(iph2) + struct ph2handle *iph2; +{ + iph2->retry_counter = lcconf->retry_counter; + return isakmp_ph2resend(iph2); +} + +/* called from scheduler */ +void +isakmp_ph1dying_stub(p) + struct sched *p; +{ + + isakmp_ph1dying(container_of(p, struct ph1handle, sce)); +} + +void +isakmp_ph1dying(iph1) + struct ph1handle *iph1; +{ + struct ph1handle *new_iph1; + struct ph2handle *p; + struct remoteconf *rmconf; + + if (iph1->status >= PHASE1ST_DYING) + return; + + /* Going away in after a while... */ + iph1->status = PHASE1ST_DYING; + + /* Any fresh phase1s? */ + new_iph1 = getph1(iph1, iph1->local, iph1->remote, 1); + if (new_iph1 == NULL) { + LIST_FOREACH(p, &iph1->ph2tree, ph1bind) { + if (p->status != PHASE2ST_ESTABLISHED) + continue; + + plog(LLV_INFO, LOCATION, NULL, + "renegotiating phase1 to %s due to " + "active phase2\n", + saddrwop2str(iph1->remote)); + + if (iph1->side == INITIATOR) + isakmp_ph1begin_i(iph1->rmconf, iph1->remote, + iph1->local); + + break; + } + } else { + migrate_ph12(iph1, new_iph1); + } + + /* Schedule for expiration */ + sched_schedule(&iph1->sce, iph1->approval->lifetime * + (100 - PFKEY_SOFT_LIFETIME_RATE) / 100, + isakmp_ph1expire_stub); +} + +/* called from scheduler */ +void +isakmp_ph1expire_stub(p) + struct sched *p; +{ + isakmp_ph1expire(container_of(p, struct ph1handle, sce)); +} + +void +isakmp_ph1expire(iph1) + struct ph1handle *iph1; +{ + char *src, *dst; + + if (iph1->status < PHASE1ST_EXPIRED) { + src = racoon_strdup(saddr2str(iph1->local)); + dst = racoon_strdup(saddr2str(iph1->remote)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + + plog(LLV_INFO, LOCATION, NULL, + "ISAKMP-SA expired %s-%s spi:%s\n", + src, dst, + isakmp_pindex(&iph1->index, 0)); + racoon_free(src); + racoon_free(dst); + iph1->status = PHASE1ST_EXPIRED; + } + + isakmp_ph1delete(iph1); +} + +/* called from scheduler */ +void +isakmp_ph1delete_stub(p) + struct sched *p; +{ + + isakmp_ph1delete(container_of(p, struct ph1handle, sce)); +} + +void +isakmp_ph1delete(iph1) + struct ph1handle *iph1; +{ + struct ph2handle *p, *next; + struct ph1handle *new_iph1; + char *src, *dst; + + /* Migrate established phase2s. Any fresh phase1s? */ + new_iph1 = getph1(iph1, iph1->local, iph1->remote, 1); + if (new_iph1 != NULL) + migrate_ph12(iph1, new_iph1); + + /* Discard any left phase2s */ + for (p = LIST_FIRST(&iph1->ph2tree); p; p = next) { + next = LIST_NEXT(p, ph1bind); + if (p->status == PHASE2ST_ESTABLISHED) + isakmp_info_send_d2(p); + /* remove all ph2 handles, + * as ph1handle will be expired soon + */ + delete_spd(p, 1); + remph2(p); + delph2(p); + } + + src = racoon_strdup(saddr2str(iph1->local)); + dst = racoon_strdup(saddr2str(iph1->remote)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + + plog(LLV_INFO, LOCATION, NULL, + "ISAKMP-SA deleted %s-%s spi:%s\n", + src, dst, isakmp_pindex(&iph1->index, 0)); + + evt_phase1(iph1, EVT_PHASE1_DOWN, NULL); + if (new_iph1 == NULL && ph1_rekey_enabled(iph1)) + script_hook(iph1, SCRIPT_PHASE1_DEAD); + + racoon_free(src); + racoon_free(dst); + + remph1(iph1); + delph1(iph1); +} + +/* called from scheduler. + * this function will call only isakmp_ph2delete(). + * phase 2 handler remain forever if kernel doesn't cry a expire of phase 2 SA + * by something cause. That's why this function is called after phase 2 SA + * expires in the userland. + */ +void +isakmp_ph2expire_stub(p) + struct sched *p; +{ + + isakmp_ph2expire(container_of(p, struct ph2handle, sce)); +} + +void +isakmp_ph2expire(iph2) + struct ph2handle *iph2; +{ + char *src, *dst; + + src = racoon_strdup(saddrwop2str(iph2->src)); + dst = racoon_strdup(saddrwop2str(iph2->dst)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + + plog(LLV_INFO, LOCATION, NULL, + "phase2 sa expired %s-%s\n", src, dst); + racoon_free(src); + racoon_free(dst); + + iph2->status = PHASE2ST_EXPIRED; + sched_schedule(&iph2->sce, 1, isakmp_ph2delete_stub); +} + +/* called from scheduler */ +void +isakmp_ph2delete_stub(p) + struct sched *p; +{ + + isakmp_ph2delete(container_of(p, struct ph2handle, sce)); +} + +void +isakmp_ph2delete(iph2) + struct ph2handle *iph2; +{ + char *src, *dst; + + src = racoon_strdup(saddrwop2str(iph2->src)); + dst = racoon_strdup(saddrwop2str(iph2->dst)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + + plog(LLV_INFO, LOCATION, NULL, + "phase2 sa deleted %s-%s\n", src, dst); + racoon_free(src); + racoon_free(dst); + + remph2(iph2); + delph2(iph2); + + return; +} + +/* %%% + * Interface between PF_KEYv2 and ISAKMP + */ +/* + * receive ACQUIRE from kernel, and begin either phase1 or phase2. + * if phase1 has been finished, begin phase2. + */ +int +isakmp_post_acquire(iph2, iph1hint, nopassive) + struct ph2handle *iph2; + struct ph1handle *iph1hint; + int nopassive; +{ + struct remoteconf *rmconf; + struct ph1handle *iph1 = NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "in post_acquire\n"); + + /* Search appropriate configuration with masking port. Note that + * we always use iph2->dst, and not iph2->sa_dst. + * + * XXX One possible need for using iph2->sa_dst if not NULL would + * be for selecting a remote configuration based on a stable + * address of a mobile node (not a CoA provided by MIGRATE/KMADDRESS + * as iph2->dst hint). This scenario would require additional changes, + * so no need to bother yet. --arno */ + + if (iph1hint == NULL || iph1hint->rmconf == NULL) { + rmconf = getrmconf(iph2->dst, nopassive ? GETRMCONF_F_NO_PASSIVE : 0); + if (rmconf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no configuration found for %s.\n", + saddrwop2str(iph2->dst)); + return -1; + } + } else { + rmconf = iph1hint->rmconf; + } + + /* if passive mode, ignore the acquire message */ + if (nopassive && rmconf->passive) { + plog(LLV_DEBUG, LOCATION, NULL, + "because of passive mode, " + "ignore the acquire message for %s.\n", + saddrwop2str(iph2->dst)); + return -1; + } + + /* + * XXX Searching by IP addresses + ports might fail on + * some cases, we should use the ISAKMP identity to search + * matching ISAKMP. + */ + iph1 = getph1(iph1hint, iph2->src, iph2->dst, 0); + + /* no ISAKMP-SA found. */ + if (iph1 == NULL) { + iph2->retry_checkph1 = lcconf->retry_checkph1; + sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub); + plog(LLV_INFO, LOCATION, NULL, + "IPsec-SA request for %s queued " + "due to no phase1 found.\n", + saddrwop2str(iph2->dst)); + + /* start phase 1 negotiation as a initiator. */ + if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src) == NULL) { + sched_cancel(&iph2->sce); + return -1; + } + + return 0; + /*NOTREACHED*/ + } + + /* found ISAKMP-SA, but on negotiation. */ + if (iph1->status < PHASE1ST_ESTABLISHED) { + iph2->retry_checkph1 = lcconf->retry_checkph1; + sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub); + plog(LLV_INFO, LOCATION, iph2->dst, + "request for establishing IPsec-SA was queued " + "due to no phase1 found.\n"); + return 0; + /*NOTREACHED*/ + } + + /* found established ISAKMP-SA */ + /* i.e. iph1->status == PHASE1ST_ESTABLISHED */ + + /* found ISAKMP-SA. */ + plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n"); + + /* begin quick mode */ + if (isakmp_ph2begin_i(iph1, iph2)) + return -1; + + return 0; +} + +int +isakmp_get_sainfo(iph2, sp_out, sp_in) + struct ph2handle *iph2; + struct secpolicy *sp_out, *sp_in; +{ + struct remoteconf *conf; + uint32_t remoteid = 0; + + plog(LLV_DEBUG, LOCATION, NULL, + "new acquire %s\n", spidx2str(&sp_out->spidx)); + + /* get sainfo */ + { + vchar_t *idsrc, *iddst; + + idsrc = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.src, + sp_out->spidx.prefs, sp_out->spidx.ul_proto); + if (idsrc == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get ID for %s\n", + spidx2str(&sp_out->spidx)); + return -1; + } + iddst = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.dst, + sp_out->spidx.prefd, sp_out->spidx.ul_proto); + if (iddst == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get ID for %s\n", + spidx2str(&sp_out->spidx)); + vfree(idsrc); + return -1; + } + + conf = getrmconf(iph2->dst, 0); + if (conf != NULL) + remoteid = conf->ph1id; + else + plog(LLV_DEBUG, LOCATION, NULL, "Warning: no valid rmconf !\n"); + + iph2->sainfo = getsainfo(idsrc, iddst, NULL, NULL, remoteid); + vfree(idsrc); + vfree(iddst); + if (iph2->sainfo == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get sainfo.\n"); + return -1; + /* XXX should use the algorithm list from register message */ + } + + plog(LLV_DEBUG, LOCATION, NULL, + "selected sainfo: %s\n", sainfo2str(iph2->sainfo)); + } + + if (set_proposal_from_policy(iph2, sp_out, sp_in) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to create saprop.\n"); + return -1; + } + + return 0; +} + + +/* + * receive GETSPI from kernel. + */ +int +isakmp_post_getspi(iph2) + struct ph2handle *iph2; +{ +#ifdef ENABLE_STATS + struct timeval start, end; +#endif + + /* don't process it because there is no suitable phase1-sa. */ + if (iph2->ph1->status >= PHASE1ST_EXPIRED) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "the negotiation is stopped, " + "because there is no suitable ISAKMP-SA.\n"); + return -1; + } + +#ifdef ENABLE_STATS + gettimeofday(&start, NULL); +#endif + if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)] + [iph2->side] + [iph2->status])(iph2, NULL) != 0) + return -1; +#ifdef ENABLE_STATS + gettimeofday(&end, NULL); + syslog(LOG_NOTICE, "%s(%s): %8.6f", + "phase2", + s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status), + timedelta(&start, &end)); +#endif + + return 0; +} + +/* called by scheduler */ +void +isakmp_chkph1there_stub(p) + struct sched *p; +{ + isakmp_chkph1there(container_of(p, struct ph2handle, sce)); +} + +void +isakmp_chkph1there(iph2) + struct ph2handle *iph2; +{ + struct ph1handle *iph1; + + iph2->retry_checkph1--; + if (iph2->retry_checkph1 < 0) { + plog(LLV_ERROR, LOCATION, iph2->dst, + "phase2 negotiation failed " + "due to time up waiting for phase1. %s\n", + sadbsecas2str(iph2->dst, iph2->src, + iph2->satype, 0, 0)); + plog(LLV_INFO, LOCATION, NULL, + "delete phase 2 handler.\n"); + + /* send acquire to kernel as error */ + pk_sendeacquire(iph2); + + remph2(iph2); + delph2(iph2); + + return; + } + + /* Search isakmp status table by address and port */ + iph1 = getph1byaddr(iph2->src, iph2->dst, 0); + + /* XXX Even if ph1 as responder is there, should we not start + * phase 2 negotiation ? */ + if (iph1 != NULL + && iph1->status == PHASE1ST_ESTABLISHED) { + /* found isakmp-sa */ + + plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: got a ph1 handler, setting ports.\n"); + plog(LLV_DEBUG2, LOCATION, NULL, "iph1->local: %s\n", saddr2str(iph1->local)); + plog(LLV_DEBUG2, LOCATION, NULL, "iph1->remote: %s\n", saddr2str(iph1->remote)); + plog(LLV_DEBUG2, LOCATION, NULL, "before:\n"); + plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src)); + plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst)); + set_port(iph2->src, extract_port(iph1->local)); + set_port(iph2->dst, extract_port(iph1->remote)); + plog(LLV_DEBUG2, LOCATION, NULL, "After:\n"); + plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src)); + plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst)); + + /* begin quick mode */ + (void)isakmp_ph2begin_i(iph1, iph2); + return; + } + + plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established ph1 handler found\n"); + + /* no isakmp-sa found */ + sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub); + + return; +} + +/* copy variable data into ALLOCATED buffer. */ +caddr_t +isakmp_set_attr_v(buf, type, val, len) + caddr_t buf; + int type; + caddr_t val; + int len; +{ + struct isakmp_data *data; + + data = (struct isakmp_data *)buf; + data->type = htons((u_int16_t)type | ISAKMP_GEN_TLV); + data->lorv = htons((u_int16_t)len); + memcpy(data + 1, val, len); + + return buf + sizeof(*data) + len; +} + +/* copy fixed length data into ALLOCATED buffer. */ +caddr_t +isakmp_set_attr_l(buf, type, val) + caddr_t buf; + int type; + u_int32_t val; +{ + struct isakmp_data *data; + + data = (struct isakmp_data *)buf; + data->type = htons((u_int16_t)type | ISAKMP_GEN_TV); + data->lorv = htons((u_int16_t)val); + + return buf + sizeof(*data); +} + +/* add a variable data attribute to the buffer by reallocating it. */ +vchar_t * +isakmp_add_attr_v(buf0, type, val, len) + vchar_t *buf0; + int type; + caddr_t val; + int len; +{ + vchar_t *buf = NULL; + struct isakmp_data *data; + int tlen; + int oldlen = 0; + + tlen = sizeof(*data) + len; + + if (buf0) { + oldlen = buf0->l; + buf = vrealloc(buf0, oldlen + tlen); + } else + buf = vmalloc(tlen); + if (!buf) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get a attribute buffer.\n"); + return NULL; + } + + data = (struct isakmp_data *)(buf->v + oldlen); + data->type = htons((u_int16_t)type | ISAKMP_GEN_TLV); + data->lorv = htons((u_int16_t)len); + memcpy(data + 1, val, len); + + return buf; +} + +/* add a fixed data attribute to the buffer by reallocating it. */ +vchar_t * +isakmp_add_attr_l(buf0, type, val) + vchar_t *buf0; + int type; + u_int32_t val; +{ + vchar_t *buf = NULL; + struct isakmp_data *data; + int tlen; + int oldlen = 0; + + tlen = sizeof(*data); + + if (buf0) { + oldlen = buf0->l; + buf = vrealloc(buf0, oldlen + tlen); + } else + buf = vmalloc(tlen); + if (!buf) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get a attribute buffer.\n"); + return NULL; + } + + data = (struct isakmp_data *)(buf->v + oldlen); + data->type = htons((u_int16_t)type | ISAKMP_GEN_TV); + data->lorv = htons((u_int16_t)val); + + return buf; +} + +/* + * calculate cookie and set. + */ +int +isakmp_newcookie(place, remote, local) + caddr_t place; + struct sockaddr *remote; + struct sockaddr *local; +{ + vchar_t *buf = NULL, *buf2 = NULL; + char *p; + int blen; + int alen; + caddr_t sa1, sa2; + time_t t; + int error = -1; + u_short port; + + + if (remote->sa_family != local->sa_family) { + plog(LLV_ERROR, LOCATION, NULL, + "address family mismatch, remote:%d local:%d\n", + remote->sa_family, local->sa_family); + goto end; + } + switch (remote->sa_family) { + case AF_INET: + alen = sizeof(struct in_addr); + sa1 = (caddr_t)&((struct sockaddr_in *)remote)->sin_addr; + sa2 = (caddr_t)&((struct sockaddr_in *)local)->sin_addr; + break; +#ifdef INET6 + case AF_INET6: + alen = sizeof(struct in6_addr); + sa1 = (caddr_t)&((struct sockaddr_in6 *)remote)->sin6_addr; + sa2 = (caddr_t)&((struct sockaddr_in6 *)local)->sin6_addr; + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid family: %d\n", remote->sa_family); + goto end; + } + blen = (alen + sizeof(u_short)) * 2 + + sizeof(time_t) + lcconf->secret_size; + buf = vmalloc(blen); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get a cookie.\n"); + goto end; + } + p = buf->v; + + /* copy my address */ + memcpy(p, sa1, alen); + p += alen; + port = ((struct sockaddr_in *)remote)->sin_port; + memcpy(p, &port, sizeof(u_short)); + p += sizeof(u_short); + + /* copy target address */ + memcpy(p, sa2, alen); + p += alen; + port = ((struct sockaddr_in *)local)->sin_port; + memcpy(p, &port, sizeof(u_short)); + p += sizeof(u_short); + + /* copy time */ + t = time(0); + memcpy(p, (caddr_t)&t, sizeof(t)); + p += sizeof(t); + + /* copy random value */ + buf2 = eay_set_random(lcconf->secret_size); + if (buf2 == NULL) + goto end; + memcpy(p, buf2->v, lcconf->secret_size); + p += lcconf->secret_size; + vfree(buf2); + + buf2 = eay_sha1_one(buf); + memcpy(place, buf2->v, sizeof(cookie_t)); + + sa1 = val2str(place, sizeof (cookie_t)); + plog(LLV_DEBUG, LOCATION, NULL, "new cookie:\n%s\n", sa1); + racoon_free(sa1); + + error = 0; +end: + if (buf != NULL) + vfree(buf); + if (buf2 != NULL) + vfree(buf2); + return error; +} + +/* + * save partner's(payload) data into phhandle. + */ +int +isakmp_p2ph(buf, gen) + vchar_t **buf; + struct isakmp_gen *gen; +{ + /* XXX to be checked in each functions for logging. */ + if (*buf) { + plog(LLV_WARNING, LOCATION, NULL, + "ignore this payload, same payload type exist.\n"); + return -1; + } + + *buf = vmalloc(ntohs(gen->len) - sizeof(*gen)); + if (*buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer.\n"); + return -1; + } + memcpy((*buf)->v, gen + 1, (*buf)->l); + + return 0; +} + +u_int32_t +isakmp_newmsgid2(iph1) + struct ph1handle *iph1; +{ + u_int32_t msgid2; + + do { + msgid2 = eay_random(); + } while (getph2bymsgid(iph1, msgid2)); + + return msgid2; +} + +/* + * set values into allocated buffer of isakmp header for phase 1 + */ +static caddr_t +set_isakmp_header(vbuf, iph1, nptype, etype, flags, msgid) + vchar_t *vbuf; + struct ph1handle *iph1; + int nptype; + u_int8_t etype; + u_int8_t flags; + u_int32_t msgid; +{ + struct isakmp *isakmp; + + if (vbuf->l < sizeof(*isakmp)) + return NULL; + + isakmp = (struct isakmp *)vbuf->v; + + memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t)); + memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t)); + isakmp->np = nptype; + isakmp->v = iph1->version; + isakmp->etype = etype; + isakmp->flags = flags; + isakmp->msgid = msgid; + isakmp->len = htonl(vbuf->l); + + return vbuf->v + sizeof(*isakmp); +} + +/* + * set values into allocated buffer of isakmp header for phase 1 + */ +caddr_t +set_isakmp_header1(vbuf, iph1, nptype) + vchar_t *vbuf; + struct ph1handle *iph1; + int nptype; +{ + return set_isakmp_header (vbuf, iph1, nptype, iph1->etype, iph1->flags, iph1->msgid); +} + +/* + * set values into allocated buffer of isakmp header for phase 2 + */ +caddr_t +set_isakmp_header2(vbuf, iph2, nptype) + vchar_t *vbuf; + struct ph2handle *iph2; + int nptype; +{ + return set_isakmp_header (vbuf, iph2->ph1, nptype, ISAKMP_ETYPE_QUICK, iph2->flags, iph2->msgid); +} + +/* + * set values into allocated buffer of isakmp payload. + */ +caddr_t +set_isakmp_payload(buf, src, nptype) + caddr_t buf; + vchar_t *src; + int nptype; +{ + struct isakmp_gen *gen; + caddr_t p = buf; + + plog(LLV_DEBUG, LOCATION, NULL, "add payload of len %zu, next type %d\n", + src->l, nptype); + + gen = (struct isakmp_gen *)p; + gen->np = nptype; + gen->len = htons(sizeof(*gen) + src->l); + p += sizeof(*gen); + memcpy(p, src->v, src->l); + p += src->l; + + return p; +} + +static int +etypesw1(etype) + int etype; +{ + switch (etype) { + case ISAKMP_ETYPE_IDENT: + return 1; + case ISAKMP_ETYPE_AGG: + return 2; + case ISAKMP_ETYPE_BASE: + return 3; + default: + return 0; + } + /*NOTREACHED*/ +} + +static int +etypesw2(etype) + int etype; +{ + switch (etype) { + case ISAKMP_ETYPE_QUICK: + return 1; + default: + return 0; + } + /*NOTREACHED*/ +} + +#ifdef HAVE_PRINT_ISAKMP_C +/* for print-isakmp.c */ +char *snapend; +extern void isakmp_print __P((const u_char *, u_int, const u_char *)); + +char *getname __P((const u_char *)); +#ifdef INET6 +char *getname6 __P((const u_char *)); +#endif +int safeputchar __P((int)); + +/* + * Return a name for the IP address pointed to by ap. This address + * is assumed to be in network byte order. + */ +char * +getname(ap) + const u_char *ap; +{ + struct sockaddr_in addr; + static char ntop_buf[NI_MAXHOST]; + + memset(&addr, 0, sizeof(addr)); +#ifndef __linux__ + addr.sin_len = sizeof(struct sockaddr_in); +#endif + addr.sin_family = AF_INET; + memcpy(&addr.sin_addr, ap, sizeof(addr.sin_addr)); + if (getnameinfo((struct sockaddr *)&addr, sizeof(addr), + ntop_buf, sizeof(ntop_buf), NULL, 0, + NI_NUMERICHOST | niflags)) + strlcpy(ntop_buf, "?", sizeof(ntop_buf)); + + return ntop_buf; +} + +#ifdef INET6 +/* + * Return a name for the IP6 address pointed to by ap. This address + * is assumed to be in network byte order. + */ +char * +getname6(ap) + const u_char *ap; +{ + struct sockaddr_in6 addr; + static char ntop_buf[NI_MAXHOST]; + + memset(&addr, 0, sizeof(addr)); + addr.sin6_len = sizeof(struct sockaddr_in6); + addr.sin6_family = AF_INET6; + memcpy(&addr.sin6_addr, ap, sizeof(addr.sin6_addr)); + if (getnameinfo((struct sockaddr *)&addr, addr.sin6_len, + ntop_buf, sizeof(ntop_buf), NULL, 0, + NI_NUMERICHOST | niflags)) + strlcpy(ntop_buf, "?", sizeof(ntop_buf)); + + return ntop_buf; +} +#endif /* INET6 */ + +int +safeputchar(c) + int c; +{ + unsigned char ch; + + ch = (unsigned char)(c & 0xff); + if (c < 0x80 && isprint(c)) + return printf("%c", c & 0xff); + else + return printf("\\%03o", c & 0xff); +} + +void +isakmp_printpacket(msg, from, my, decoded) + vchar_t *msg; + struct sockaddr *from; + struct sockaddr *my; + int decoded; +{ +#ifdef YIPS_DEBUG + struct timeval tv; + int s; + char hostbuf[NI_MAXHOST]; + char portbuf[NI_MAXSERV]; + struct isakmp *isakmp; + vchar_t *buf; +#endif + + if (loglevel < LLV_DEBUG) + return; + +#ifdef YIPS_DEBUG + plog(LLV_DEBUG, LOCATION, NULL, "begin.\n"); + + gettimeofday(&tv, NULL); + s = tv.tv_sec % 3600; + printf("%02d:%02d.%06u ", s / 60, s % 60, (u_int32_t)tv.tv_usec); + + if (from) { + if (getnameinfo(from, sysdep_sa_len(from), hostbuf, sizeof(hostbuf), + portbuf, sizeof(portbuf), + NI_NUMERICHOST | NI_NUMERICSERV | niflags)) { + strlcpy(hostbuf, "?", sizeof(hostbuf)); + strlcpy(portbuf, "?", sizeof(portbuf)); + } + printf("%s:%s", hostbuf, portbuf); + } else + printf("?"); + printf(" -> "); + if (my) { + if (getnameinfo(my, sysdep_sa_len(my), hostbuf, sizeof(hostbuf), + portbuf, sizeof(portbuf), + NI_NUMERICHOST | NI_NUMERICSERV | niflags)) { + strlcpy(hostbuf, "?", sizeof(hostbuf)); + strlcpy(portbuf, "?", sizeof(portbuf)); + } + printf("%s:%s", hostbuf, portbuf); + } else + printf("?"); + printf(": "); + + buf = vdup(msg); + if (!buf) { + printf("(malloc fail)\n"); + return; + } + if (decoded) { + isakmp = (struct isakmp *)buf->v; + if (isakmp->flags & ISAKMP_FLAG_E) { +#if 0 + int pad; + pad = *(u_char *)(buf->v + buf->l - 1); + if (buf->l < pad && 2 < vflag) + printf("(wrong padding)"); +#endif + isakmp->flags &= ~ISAKMP_FLAG_E; + } + } + + snapend = buf->v + buf->l; + isakmp_print(buf->v, buf->l, NULL); + vfree(buf); + printf("\n"); + fflush(stdout); + + return; +#endif +} +#endif /*HAVE_PRINT_ISAKMP_C*/ + +int +copy_ph1addresses(iph1, rmconf, remote, local) + struct ph1handle *iph1; + struct remoteconf *rmconf; + struct sockaddr *remote, *local; +{ + u_int16_t port; + + /* address portion must be grabbed from real remote address "remote" */ + iph1->remote = dupsaddr(remote); + if (iph1->remote == NULL) + return -1; + + /* + * if remote has no port # (in case of initiator - from ACQUIRE msg) + * - if remote.conf specifies port #, use that + * - if remote.conf does not, use 500 + * if remote has port # (in case of responder - from recvfrom(2)) + * respect content of "remote". + */ + if (extract_port(iph1->remote) == 0) { + port = 0; + if (rmconf != NULL) + port = extract_port(rmconf->remote); + if (port == 0) + port = PORT_ISAKMP; + set_port(iph1->remote, port); + } + + if (local == NULL) + iph1->local = getlocaladdr(iph1->remote); + else + iph1->local = dupsaddr(local); + if (iph1->local == NULL) + return -1; + + if (extract_port(iph1->local) == 0) { + port = myaddr_getsport(iph1->local); + if (port == 0) + port = PORT_ISAKMP; + set_port(iph1->local, port); + } + +#ifdef ENABLE_NATT + if (extract_port(iph1->local) == lcconf->port_isakmp_natt) { + plog(LLV_DEBUG, LOCATION, NULL, "Marking ports as changed\n"); + iph1->natt_flags |= NAT_ADD_NON_ESP_MARKER; + } +#endif + + return 0; +} + +static int +nostate1(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + plog(LLV_ERROR, LOCATION, iph1->remote, "wrong state %u.\n", + iph1->status); + return -1; +} + +static int +nostate2(iph2, msg) + struct ph2handle *iph2; + vchar_t *msg; +{ + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, "wrong state %u.\n", + iph2->status); + return -1; +} + +void +log_ph1established(iph1) + const struct ph1handle *iph1; +{ + char *src, *dst; + + src = racoon_strdup(saddr2str(iph1->local)); + dst = racoon_strdup(saddr2str(iph1->remote)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + + plog(LLV_INFO, LOCATION, NULL, + "ISAKMP-SA established %s-%s spi:%s\n", + src, dst, + isakmp_pindex(&iph1->index, 0)); + + evt_phase1(iph1, EVT_PHASE1_UP, NULL); + if(!iph1->rmconf->mode_cfg) + evt_phase1(iph1, EVT_PHASE1_MODE_CFG, NULL); + + racoon_free(src); + racoon_free(dst); + + return; +} + +struct payload_list * +isakmp_plist_append_full (struct payload_list *plist, vchar_t *payload, + u_int8_t payload_type, u_int8_t free_payload) +{ + if (! plist) { + plist = racoon_malloc (sizeof (struct payload_list)); + plist->prev = NULL; + } + else { + plist->next = racoon_malloc (sizeof (struct payload_list)); + plist->next->prev = plist; + plist = plist->next; + } + + plist->next = NULL; + plist->payload = payload; + plist->payload_type = payload_type; + plist->free_payload = free_payload; + + return plist; +} + +vchar_t * +isakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1) +{ + struct payload_list *ptr = *plist, *first; + size_t tlen = sizeof (struct isakmp), n = 0; + vchar_t *buf = NULL; + char *p; + + /* Seek to the first item. */ + while (ptr->prev) ptr = ptr->prev; + first = ptr; + + /* Compute the whole length. */ + while (ptr) { + tlen += ptr->payload->l + sizeof (struct isakmp_gen); + ptr = ptr->next; + } + + buf = vmalloc(tlen); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + goto end; + } + + ptr = first; + + p = set_isakmp_header1(buf, iph1, ptr->payload_type); + if (p == NULL) + goto end; + + while (ptr) + { + p = set_isakmp_payload (p, ptr->payload, ptr->next ? ptr->next->payload_type : ISAKMP_NPTYPE_NONE); + first = ptr; + ptr = ptr->next; + if (first->free_payload) + vfree(first->payload); + racoon_free (first); + /* ptr->prev = NULL; first = NULL; ... omitted. */ + n++; + } + + *plist = NULL; + + return buf; +end: + if (buf != NULL) + vfree(buf); + return NULL; +} + +#ifdef ENABLE_FRAG +int +frag_handler(iph1, msg, remote, local) + struct ph1handle *iph1; + vchar_t *msg; + struct sockaddr *remote; + struct sockaddr *local; +{ + vchar_t *newmsg; + + if (isakmp_frag_extract(iph1, msg) == 1) { + if ((newmsg = isakmp_frag_reassembly(iph1)) == NULL) { + plog(LLV_ERROR, LOCATION, remote, + "Packet reassembly failed\n"); + return -1; + } + return isakmp_main(newmsg, remote, local); + } + + return 0; +} +#endif + +void +script_hook(iph1, script) + struct ph1handle *iph1; + int script; +{ +#define IP_MAX 40 +#define PORT_MAX 6 + char addrstr[IP_MAX]; + char portstr[PORT_MAX]; + char **envp = NULL; + int envc = 1; + char **c; + + if (iph1 == NULL || + iph1->rmconf == NULL || + iph1->rmconf->script[script] == NULL) + return; + +#ifdef ENABLE_HYBRID + (void)isakmp_cfg_setenv(iph1, &envp, &envc); +#endif + + /* local address */ + GETNAMEINFO(iph1->local, addrstr, portstr); + + if (script_env_append(&envp, &envc, "LOCAL_ADDR", addrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_ADDR\n"); + goto out; + } + + if (script_env_append(&envp, &envc, "LOCAL_PORT", portstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_PORT\n"); + goto out; + } + + /* Peer address */ + if (iph1->remote != NULL) { + GETNAMEINFO(iph1->remote, addrstr, portstr); + + if (script_env_append(&envp, &envc, + "REMOTE_ADDR", addrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set REMOTE_ADDR\n"); + goto out; + } + + if (script_env_append(&envp, &envc, + "REMOTE_PORT", portstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set REMOTEL_PORT\n"); + goto out; + } + } + + /* Peer identity. */ + if (iph1->id_p != NULL) { + if (script_env_append(&envp, &envc, "REMOTE_ID", + ipsecdoi_id2str(iph1->id_p)) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set REMOTE_ID\n"); + goto out; + } + } + + if (privsep_script_exec(iph1->rmconf->script[script]->v, + script, envp) != 0) + plog(LLV_ERROR, LOCATION, NULL, + "Script %s execution failed\n", script_names[script]); + +out: + for (c = envp; *c; c++) + racoon_free(*c); + + racoon_free(envp); + + return; +} + +int +script_env_append(envp, envc, name, value) + char ***envp; + int *envc; + char *name; + char *value; +{ + char *envitem; + char **newenvp; + int newenvc; + + envitem = racoon_malloc(strlen(name) + 1 + strlen(value) + 1); + if (envitem == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return -1; + } + sprintf(envitem, "%s=%s", name, value); + + newenvc = (*envc) + 1; + newenvp = racoon_realloc(*envp, newenvc * sizeof(char *)); + if (newenvp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + racoon_free(envitem); + return -1; + } + + newenvp[newenvc - 2] = envitem; + newenvp[newenvc - 1] = NULL; + + *envp = newenvp; + *envc = newenvc; + return 0; +} + +int +script_exec(script, name, envp) + char *script; + int name; + char *const envp[]; +{ + char *argv[] = { NULL, NULL, NULL }; + + argv[0] = script; + argv[1] = script_names[name]; + argv[2] = NULL; + + switch (fork()) { + case 0: + execve(argv[0], argv, envp); + plog(LLV_ERROR, LOCATION, NULL, + "execve(\"%s\") failed: %s\n", + argv[0], strerror(errno)); + _exit(1); + break; + case -1: + plog(LLV_ERROR, LOCATION, NULL, + "Cannot fork: %s\n", strerror(errno)); + return -1; + break; + default: + break; + } + return 0; + +} + +void +purge_remote(iph1) + struct ph1handle *iph1; +{ + vchar_t *buf = NULL; + struct sadb_msg *msg, *next, *end; + struct sadb_sa *sa; + struct sockaddr *src, *dst; + caddr_t mhp[SADB_EXT_MAX + 1]; + u_int proto_id; + struct ph2handle *iph2; + struct ph1handle *new_iph1; + + plog(LLV_INFO, LOCATION, NULL, + "purging ISAKMP-SA spi=%s.\n", + isakmp_pindex(&(iph1->index), iph1->msgid)); + + /* Mark as expired. */ + iph1->status = PHASE1ST_EXPIRED; + + /* Check if we have another, still valid, phase1 SA. */ + new_iph1 = getph1(iph1, iph1->local, iph1->remote, GETPH1_F_ESTABLISHED); + + /* + * Delete all orphaned or binded to the deleting ph1handle phase2 SAs. + * Keep all others phase2 SAs. + */ + buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC); + if (buf == NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey_dump_sadb returned nothing.\n"); + return; + } + + msg = (struct sadb_msg *)buf->v; + end = (struct sadb_msg *)(buf->v + buf->l); + + while (msg < end) { + if ((msg->sadb_msg_len << 3) < sizeof(*msg)) + break; + next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); + if (msg->sadb_msg_type != SADB_DUMP) { + msg = next; + continue; + } + + if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { + plog(LLV_ERROR, LOCATION, NULL, + "pfkey_check (%s)\n", ipsec_strerror()); + msg = next; + continue; + } + + sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]); + if (!sa || + !mhp[SADB_EXT_ADDRESS_SRC] || + !mhp[SADB_EXT_ADDRESS_DST]) { + msg = next; + continue; + } + pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + + if (sa->sadb_sa_state != SADB_SASTATE_LARVAL && + sa->sadb_sa_state != SADB_SASTATE_MATURE && + sa->sadb_sa_state != SADB_SASTATE_DYING) { + msg = next; + continue; + } + + /* + * check in/outbound SAs. + * Select only SAs where src == local and dst == remote (outgoing) + * or src == remote and dst == local (incoming). + */ + if ((cmpsaddr(iph1->local, src) != CMPSADDR_MATCH || + cmpsaddr(iph1->remote, dst) != CMPSADDR_MATCH) && + (cmpsaddr(iph1->local, dst) != CMPSADDR_MATCH || + cmpsaddr(iph1->remote, src) != CMPSADDR_MATCH)) { + msg = next; + continue; + } + + proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); + iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); + + /* Check if there is another valid ISAKMP-SA */ + if (new_iph1 != NULL) { + + if (iph2 == NULL) { + /* No handler... still send a pfkey_delete message, but log this !*/ + plog(LLV_INFO, LOCATION, NULL, + "Unknown IPsec-SA spi=%u, hmmmm?\n", + ntohl(sa->sadb_sa_spi)); + }else{ + + /* + * If we have a new ph1, do not purge IPsec-SAs binded + * to a different ISAKMP-SA + */ + if (iph2->ph1 != NULL && iph2->ph1 != iph1){ + msg = next; + continue; + } + + /* If the ph2handle is established, do not purge IPsec-SA */ + if (iph2->status == PHASE2ST_ESTABLISHED || + iph2->status == PHASE2ST_EXPIRED) { + + plog(LLV_INFO, LOCATION, NULL, + "keeping IPsec-SA spi=%u - found valid ISAKMP-SA spi=%s.\n", + ntohl(sa->sadb_sa_spi), + isakmp_pindex(&(new_iph1->index), new_iph1->msgid)); + msg = next; + continue; + } + } + } + + + pfkey_send_delete(lcconf->sock_pfkey, + msg->sadb_msg_satype, + IPSEC_MODE_ANY, + src, dst, sa->sadb_sa_spi); + + /* delete a relative phase 2 handle. */ + if (iph2 != NULL) { + delete_spd(iph2, 0); + remph2(iph2); + delph2(iph2); + } + + plog(LLV_INFO, LOCATION, NULL, + "purged IPsec-SA spi=%u.\n", + ntohl(sa->sadb_sa_spi)); + + msg = next; + } + + if (buf) + vfree(buf); + + /* Mark the phase1 handler as EXPIRED */ + plog(LLV_INFO, LOCATION, NULL, + "purged ISAKMP-SA spi=%s.\n", + isakmp_pindex(&(iph1->index), iph1->msgid)); + + isakmp_ph1delete(iph1); +} + +void +delete_spd(iph2, created) + struct ph2handle *iph2; + u_int64_t created; +{ + struct policyindex spidx; + struct sockaddr_storage addr; + u_int8_t pref; + struct sockaddr *src; + struct sockaddr *dst; + int error; + int idi2type = 0;/* switch whether copy IDs into id[src,dst]. */ + + if (iph2 == NULL) + return; + + /* Delete the SPD entry if we generated it + */ + if (! iph2->generated_spidx ) + return; + + src = iph2->src; + dst = iph2->dst; + + plog(LLV_INFO, LOCATION, NULL, + "deleting a generated policy.\n"); + + memset(&spidx, 0, sizeof(spidx)); + iph2->spidx_gen = (caddr_t )&spidx; + + /* make inbound policy */ + iph2->src = dst; + iph2->dst = src; + spidx.dir = IPSEC_DIR_INBOUND; + spidx.ul_proto = 0; + + /* + * Note: code from get_proposal_r + */ + +#define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type + + /* + * make destination address in spidx from either ID payload + * or phase 1 address into a address in spidx. + */ + if (iph2->id != NULL + && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR + || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR + || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET + || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { + /* get a destination address of a policy */ + error = ipsecdoi_id2sockaddr(iph2->id, + (struct sockaddr *)&spidx.dst, + &spidx.prefd, &spidx.ul_proto); + if (error) + goto purge; + +#ifdef INET6 + /* + * get scopeid from the SA address. + * note that the phase 1 source address is used as + * a destination address to search for a inbound + * policy entry because rcoon is responder. + */ + if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) { + if ((error = + setscopeid((struct sockaddr *)&spidx.dst, + iph2->src)) != 0) + goto purge; + } +#endif + + if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR + || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) + idi2type = _XIDT(iph2->id); + + } else { + + plog(LLV_DEBUG, LOCATION, NULL, + "get a destination address of SP index " + "from phase1 address " + "due to no ID payloads found " + "OR because ID type is not address.\n"); + + /* + * copy the SOURCE address of IKE into the + * DESTINATION address of the key to search the + * SPD because the direction of policy is inbound. + */ + memcpy(&spidx.dst, iph2->src, sysdep_sa_len(iph2->src)); + switch (spidx.dst.ss_family) { + case AF_INET: + spidx.prefd = + sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + spidx.prefd = + sizeof(struct in6_addr) << 3; + break; +#endif + default: + spidx.prefd = 0; + break; + } + } + + /* make source address in spidx */ + if (iph2->id_p != NULL + && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR + || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR + || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET + || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { + /* get a source address of inbound SA */ + error = ipsecdoi_id2sockaddr(iph2->id_p, + (struct sockaddr *)&spidx.src, + &spidx.prefs, &spidx.ul_proto); + if (error) + goto purge; + +#ifdef INET6 + /* + * get scopeid from the SA address. + * for more detail, see above of this function. + */ + if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) { + error = + setscopeid((struct sockaddr *)&spidx.src, + iph2->dst); + if (error) + goto purge; + } +#endif + + /* make sa_[src,dst] if both ID types are IP address and same */ + if (_XIDT(iph2->id_p) == idi2type + && spidx.dst.ss_family == spidx.src.ss_family) { + iph2->sa_src = + dupsaddr((struct sockaddr *)&spidx.dst); + if (iph2->sa_src == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "allocation failed\n"); + goto purge; + } + iph2->sa_dst = + dupsaddr((struct sockaddr *)&spidx.src); + if (iph2->sa_dst == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "allocation failed\n"); + goto purge; + } + } + + } else { + plog(LLV_DEBUG, LOCATION, NULL, + "get a source address of SP index " + "from phase1 address " + "due to no ID payloads found " + "OR because ID type is not address.\n"); + + /* see above comment. */ + memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst)); + switch (spidx.src.ss_family) { + case AF_INET: + spidx.prefs = + sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + spidx.prefs = + sizeof(struct in6_addr) << 3; + break; +#endif + default: + spidx.prefs = 0; + break; + } + } + +#undef _XIDT + + plog(LLV_DEBUG, LOCATION, NULL, + "get a src address from ID payload " + "%s prefixlen=%u ul_proto=%u\n", + saddr2str((struct sockaddr *)&spidx.src), + spidx.prefs, spidx.ul_proto); + plog(LLV_DEBUG, LOCATION, NULL, + "get dst address from ID payload " + "%s prefixlen=%u ul_proto=%u\n", + saddr2str((struct sockaddr *)&spidx.dst), + spidx.prefd, spidx.ul_proto); + + /* + * convert the ul_proto if it is 0 + * because 0 in ID payload means a wild card. + */ + if (spidx.ul_proto == 0) + spidx.ul_proto = IPSEC_ULPROTO_ANY; + +#undef _XIDT + + /* Check if the generated SPD has the same timestamp as the SA. + * If timestamps are different, this means that the SPD entry has been + * refreshed by another SA, and should NOT be deleted with the current SA. + */ + if( created ){ + struct secpolicy *p; + + p = getsp(&spidx); + if(p != NULL){ + /* just do no test if p is NULL, because this probably just means + * that the policy has already be deleted for some reason. + */ + if(p->spidx.created != created) + goto purge; + } + } + + /* End of code from get_proposal_r + */ + + if (pk_sendspddelete(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "pfkey spddelete(inbound) failed.\n"); + }else{ + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey spddelete(inbound) sent.\n"); + } + +#ifdef HAVE_POLICY_FWD + /* make forward policy if required */ + if (tunnel_mode_prop(iph2->approval)) { + spidx.dir = IPSEC_DIR_FWD; + if (pk_sendspddelete(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "pfkey spddelete(forward) failed.\n"); + }else{ + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey spddelete(forward) sent.\n"); + } + } +#endif + + /* make outbound policy */ + iph2->src = src; + iph2->dst = dst; + spidx.dir = IPSEC_DIR_OUTBOUND; + addr = spidx.src; + spidx.src = spidx.dst; + spidx.dst = addr; + pref = spidx.prefs; + spidx.prefs = spidx.prefd; + spidx.prefd = pref; + + if (pk_sendspddelete(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "pfkey spddelete(outbound) failed.\n"); + }else{ + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey spddelete(outbound) sent.\n"); + } +purge: + iph2->spidx_gen=NULL; +} + + +#ifdef INET6 +u_int32_t +setscopeid(sp_addr0, sa_addr0) + struct sockaddr *sp_addr0, *sa_addr0; +{ + struct sockaddr_in6 *sp_addr, *sa_addr; + + sp_addr = (struct sockaddr_in6 *)sp_addr0; + sa_addr = (struct sockaddr_in6 *)sa_addr0; + + if (!IN6_IS_ADDR_LINKLOCAL(&sp_addr->sin6_addr) + && !IN6_IS_ADDR_SITELOCAL(&sp_addr->sin6_addr) + && !IN6_IS_ADDR_MULTICAST(&sp_addr->sin6_addr)) + return 0; + + /* this check should not be here ? */ + if (sa_addr->sin6_family != AF_INET6) { + plog(LLV_ERROR, LOCATION, NULL, + "can't get scope ID: family mismatch\n"); + return -1; + } + + if (!IN6_IS_ADDR_LINKLOCAL(&sa_addr->sin6_addr)) { + plog(LLV_ERROR, LOCATION, NULL, + "scope ID is not supported except of lladdr.\n"); + return -1; + } + + sp_addr->sin6_scope_id = sa_addr->sin6_scope_id; + + return 0; +} +#endif diff --git a/ipsec-tools/src/racoon/isakmp.h b/ipsec-tools/src/racoon/isakmp.h new file mode 100644 index 00000000..16986a95 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp.h @@ -0,0 +1,425 @@ +/* $NetBSD: isakmp.h,v 1.7 2009/05/20 07:54:50 vanhu Exp $ */ + +/* Id: isakmp.h,v 1.11 2005/04/25 22:19:39 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ISAKMP_H +#define _ISAKMP_H + +/* refer to RFC 2408 */ + +#include +#include "isakmp_var.h" + +#define INITIATOR 0 /* synonym sender */ +#define RESPONDER 1 /* synonym receiver */ + +#define GENERATE 1 +#define VALIDATE 0 + +/* 3.1 ISAKMP Header Format + 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 ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +struct isakmp { + cookie_t i_ck; /* Initiator Cookie */ + cookie_t r_ck; /* Responder Cookie */ + u_int8_t np; /* Next Payload Type */ + u_int8_t v; + u_int8_t etype; /* Exchange Type */ + u_int8_t flags; /* Flags */ + u_int32_t msgid; + u_int32_t len; /* Length */ +} __attribute__((__packed__)); + +/* Next Payload Type */ +#define ISAKMP_NPTYPE_NONE 0 /* NONE*/ +#define ISAKMP_NPTYPE_SA 1 /* Security Association */ +#define ISAKMP_NPTYPE_P 2 /* Proposal */ +#define ISAKMP_NPTYPE_T 3 /* Transform */ +#define ISAKMP_NPTYPE_KE 4 /* Key Exchange */ +#define ISAKMP_NPTYPE_ID 5 /* Identification */ +#define ISAKMP_NPTYPE_CERT 6 /* Certificate */ +#define ISAKMP_NPTYPE_CR 7 /* Certificate Request */ +#define ISAKMP_NPTYPE_HASH 8 /* Hash */ +#define ISAKMP_NPTYPE_SIG 9 /* Signature */ +#define ISAKMP_NPTYPE_NONCE 10 /* Nonce */ +#define ISAKMP_NPTYPE_N 11 /* Notification */ +#define ISAKMP_NPTYPE_D 12 /* Delete */ +#define ISAKMP_NPTYPE_VID 13 /* Vendor ID */ +#define ISAKMP_NPTYPE_ATTR 14 /* Attribute */ + + +/* NAT-T draft-ietf-ipsec-nat-t-ike-05 and later */ +/* XXX conflicts with values assigned to RFC 3547 */ +#define ISAKMP_NPTYPE_NATD_BADDRAFT 15 /* NAT Discovery */ +#define ISAKMP_NPTYPE_NATOA_BADDRAFT 16 /* NAT Original Address */ + + +/* NAT-T RFC */ +#define ISAKMP_NPTYPE_NATD_RFC 20 /* NAT Discovery */ +#define ISAKMP_NPTYPE_NATOA_RFC 21 /* NAT Original Address */ + +/* NAT-T up to draft-ietf-ipsec-nat-t-ike-04 */ +#define ISAKMP_NPTYPE_NATD_DRAFT 130 /* NAT Discovery */ +#define ISAKMP_NPTYPE_NATOA_DRAFT 131 /* NAT Original Address */ + +/* Frag does not seems to be documented */ +#define ISAKMP_NPTYPE_FRAG 132 /* IKE fragmentation payload */ + +#define ISAKMP_NPTYPE_MAX 17 + /* 128 - 255 Private Use */ + +/* + * The following are valid when the Vendor ID is one of the + * following: + * + * MD5("A GSS-API Authentication Method for IKE") + * MD5("GSSAPI") (recognized by Windows 2000) + * MD5("MS NT5 ISAKMPOAKLEY") (sent by Windows 2000) + * + * See draft-ietf-ipsec-isakmp-gss-auth-06.txt. + */ +#define ISAKMP_NPTYPE_GSS 129 /* GSS token */ + +#define ISAKMP_MAJOR_VERSION 1 +#define ISAKMP_MINOR_VERSION 0 +#define ISAKMP_VERSION_NUMBER 0x10 +#define ISAKMP_GETMAJORV(v) (((v) & 0xf0) >> 4) +#define ISAKMP_SETMAJORV(v, m) ((v) = ((v) & 0x0f) | (((m) << 4) & 0xf0)) +#define ISAKMP_GETMINORV(v) ((v) & 0x0f) +#define ISAKMP_SETMINORV(v, m) ((v) = ((v) & 0xf0) | ((m) & 0x0f)) + +/* Exchange Type */ +#define ISAKMP_ETYPE_NONE 0 /* NONE */ +#define ISAKMP_ETYPE_BASE 1 /* Base */ +#define ISAKMP_ETYPE_IDENT 2 /* Identity Protection */ +#define ISAKMP_ETYPE_AUTH 3 /* Authentication Only */ +#define ISAKMP_ETYPE_AGG 4 /* Aggressive */ +#define ISAKMP_ETYPE_INFO 5 /* Informational */ +#define ISAKMP_ETYPE_CFG 6 /* Mode config */ +/* Additional Exchange Type */ +#define ISAKMP_ETYPE_QUICK 32 /* Quick Mode */ +#define ISAKMP_ETYPE_NEWGRP 33 /* New group Mode */ +#define ISAKMP_ETYPE_ACKINFO 34 /* Acknowledged Informational */ + +/* Flags */ +#define ISAKMP_FLAG_E 0x01 /* Encryption Bit */ +#define ISAKMP_FLAG_C 0x02 /* Commit Bit */ +#define ISAKMP_FLAG_A 0x04 /* Authentication Only Bit */ + +/* 3.2 Payload Generic Header + 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_gen { + u_int8_t np; /* Next Payload */ + u_int8_t reserved; /* RESERVED, unused, must set to 0 */ + u_int16_t len; /* Payload Length */ +} __attribute__((__packed__)); + +/* 3.3 Data Attributes + 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_data { + u_int16_t type; /* defined by DOI-spec, and Attribute Format */ + u_int16_t lorv; /* if f equal 1, Attribute Length */ + /* if f equal 0, Attribute Value */ + /* if f equal 1, Attribute Value */ +} __attribute__((__packed__)); +#define ISAKMP_GEN_TLV 0x0000 +#define ISAKMP_GEN_TV 0x8000 + /* mask for type of attribute format */ +#define ISAKMP_GEN_MASK 0x8000 + +#if 0 +/* MAY NOT be used, because of being defined in ipsec-doi. */ +/* 3.4 Security Association Payload */ +struct isakmp_pl_sa { + struct isakmp_gen h; + u_int32_t doi; /* Domain of Interpretation */ + u_int32_t sit; /* Situation */ +} __attribute__((__packed__)); +#endif + +/* 3.5 Proposal Payload */ + /* + The value of the next payload field MUST only contain the value "2" + or "0". If there are additional Proposal payloads in the message, + then this field will be 2. If the current Proposal payload is the + last within the security association proposal, then this field will + be 0. + */ +struct isakmp_pl_p { + struct isakmp_gen h; + u_int8_t p_no; /* Proposal # */ + u_int8_t proto_id; /* Protocol */ + u_int8_t spi_size; /* SPI Size */ + u_int8_t num_t; /* Number of Transforms */ + /* SPI */ +} __attribute__((__packed__)); + +/* 3.6 Transform Payload */ + /* + The value of the next payload field MUST only contain the value "3" + or "0". If there are additional Transform payloads in the proposal, + then this field will be 3. If the current Transform payload is the + last within the proposal, then this field will be 0. + */ +struct isakmp_pl_t { + struct isakmp_gen h; + u_int8_t t_no; /* Transform # */ + u_int8_t t_id; /* Transform-Id */ + u_int16_t reserved; /* RESERVED2 */ + /* SA Attributes */ +} __attribute__((__packed__)); + +/* 3.7 Key Exchange Payload */ +struct isakmp_pl_ke { + struct isakmp_gen h; + /* Key Exchange Data */ +} __attribute__((__packed__)); + +#if 0 +/* NOTE: MUST NOT use because of being defined in ipsec-doi instead them. */ +/* 3.8 Identification Payload */ +struct isakmp_pl_id { + struct isakmp_gen h; + union { + u_int8_t id_type; /* ID Type */ + u_int32_t doi_data; /* DOI Specific ID Data */ + } d; + /* Identification Data */ +} __attribute__((__packed__)); +/* A.4 ISAKMP Identification Type Values */ +#define ISAKMP_ID_IPV4_ADDR 0 +#define ISAKMP_ID_IPV4_ADDR_SUBNET 1 +#define ISAKMP_ID_IPV6_ADDR 2 +#define ISAKMP_ID_IPV6_ADDR_SUBNET 3 +#endif + +/* 3.9 Certificate Payload */ +struct isakmp_pl_cert { + struct isakmp_gen h; + /* + * Encoding type of 1 octet follows immediately, + * variable length CERT data follows encoding type. + */ +} __attribute__((__packed__)); + +/* Certificate Type */ +#define ISAKMP_CERT_NONE 0 +#define ISAKMP_CERT_PKCS7 1 +#define ISAKMP_CERT_PGP 2 +#define ISAKMP_CERT_DNS 3 +#define ISAKMP_CERT_X509SIGN 4 +#define ISAKMP_CERT_X509KE 5 +#define ISAKMP_CERT_KERBEROS 6 +#define ISAKMP_CERT_CRL 7 +#define ISAKMP_CERT_ARL 8 +#define ISAKMP_CERT_SPKI 9 +#define ISAKMP_CERT_X509ATTR 10 +#define ISAKMP_CERT_PLAINRSA 11 + +/* 3.10 Certificate Request Payload */ +struct isakmp_pl_cr { + struct isakmp_gen h; + u_int8_t num_cert; /* # Cert. Types */ + /* + Certificate Types (variable length) + -- Contains a list of the types of certificates requested, + sorted in order of preference. Each individual certificate + type is 1 octet. This field is NOT required. + */ + /* # Certificate Authorities (1 octet) */ + /* Certificate Authorities (variable length) */ +} __attribute__((__packed__)); + +/* 3.11 Hash Payload */ +struct isakmp_pl_hash { + struct isakmp_gen h; + /* Hash Data */ +} __attribute__((__packed__)); + +/* 3.12 Signature Payload */ +struct isakmp_pl_sig { + struct isakmp_gen h; + /* Signature Data */ +} __attribute__((__packed__)); + +/* 3.13 Nonce Payload */ +struct isakmp_pl_nonce { + struct isakmp_gen h; + /* Nonce Data */ +} __attribute__((__packed__)); + +/* 3.14 Notification Payload */ +struct isakmp_pl_n { + struct isakmp_gen h; + u_int32_t doi; /* Domain of Interpretation */ + u_int8_t proto_id; /* Protocol-ID */ + u_int8_t spi_size; /* SPI Size */ + u_int16_t type; /* Notify Message Type */ + /* SPI */ + /* Notification Data */ +} __attribute__((__packed__)); + +/* 3.14.1 Notify Message Types */ +/* NOTIFY MESSAGES - ERROR TYPES */ +#define ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE 1 +#define ISAKMP_NTYPE_DOI_NOT_SUPPORTED 2 +#define ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED 3 +#define ISAKMP_NTYPE_INVALID_COOKIE 4 +#define ISAKMP_NTYPE_INVALID_MAJOR_VERSION 5 +#define ISAKMP_NTYPE_INVALID_MINOR_VERSION 6 +#define ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE 7 +#define ISAKMP_NTYPE_INVALID_FLAGS 8 +#define ISAKMP_NTYPE_INVALID_MESSAGE_ID 9 +#define ISAKMP_NTYPE_INVALID_PROTOCOL_ID 10 +#define ISAKMP_NTYPE_INVALID_SPI 11 +#define ISAKMP_NTYPE_INVALID_TRANSFORM_ID 12 +#define ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED 13 +#define ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN 14 +#define ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX 15 +#define ISAKMP_NTYPE_PAYLOAD_MALFORMED 16 +#define ISAKMP_NTYPE_INVALID_KEY_INFORMATION 17 +#define ISAKMP_NTYPE_INVALID_ID_INFORMATION 18 +#define ISAKMP_NTYPE_INVALID_CERT_ENCODING 19 +#define ISAKMP_NTYPE_INVALID_CERTIFICATE 20 +#define ISAKMP_NTYPE_BAD_CERT_REQUEST_SYNTAX 21 +#define ISAKMP_NTYPE_INVALID_CERT_AUTHORITY 22 +#define ISAKMP_NTYPE_INVALID_HASH_INFORMATION 23 +#define ISAKMP_NTYPE_AUTHENTICATION_FAILED 24 +#define ISAKMP_NTYPE_INVALID_SIGNATURE 25 +#define ISAKMP_NTYPE_ADDRESS_NOTIFICATION 26 +#define ISAKMP_NTYPE_NOTIFY_SA_LIFETIME 27 +#define ISAKMP_NTYPE_CERTIFICATE_UNAVAILABLE 28 +#define ISAKMP_NTYPE_UNSUPPORTED_EXCHANGE_TYPE 29 +#define ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS 30 +#define ISAKMP_NTYPE_MINERROR 1 +#define ISAKMP_NTYPE_MAXERROR 16383 +/* NOTIFY MESSAGES - STATUS TYPES */ +#define ISAKMP_NTYPE_CONNECTED 16384 +/* 4.6.3 IPSEC DOI Notify Message Types */ +#define ISAKMP_NTYPE_RESPONDER_LIFETIME 24576 +#define ISAKMP_NTYPE_REPLAY_STATUS 24577 +#define ISAKMP_NTYPE_INITIAL_CONTACT 24578 + +/* DPD */ +#define ISAKMP_NTYPE_R_U_THERE 36136 +#define ISAKMP_NTYPE_R_U_THERE_ACK 36137 + +#define ISAKMP_NTYPE_HEARTBEAT 40503 + +/* using only to log */ +#define ISAKMP_LOG_RETRY_LIMIT_REACHED 65530 + +/* XXX means internal error but it's not reserved by any drafts... */ +#define ISAKMP_INTERNAL_ERROR -1 + +/* 3.15 Delete Payload */ +struct isakmp_pl_d { + struct isakmp_gen h; + u_int32_t doi; /* Domain of Interpretation */ + u_int8_t proto_id; /* Protocol-Id */ + u_int8_t spi_size; /* SPI Size */ + u_int16_t num_spi; /* # of SPIs */ + /* SPI(es) */ +} __attribute__((__packed__)); + +struct payload_list { + struct payload_list *next, *prev; + vchar_t *payload; + u_int8_t payload_type; + u_int8_t free_payload; +}; + + +/* See draft-ietf-ipsec-isakmp-mode-cfg-04.txt, 3.2 */ +struct isakmp_pl_attr { + struct isakmp_gen h; + u_int8_t type; /* Exchange type */ + u_int8_t res2; + u_int16_t id; /* Per transaction id */ +} __attribute__((__packed__)); + +/* Exchange type */ +#define ISAKMP_CFG_REQUEST 1 +#define ISAKMP_CFG_REPLY 2 +#define ISAKMP_CFG_SET 3 +#define ISAKMP_CFG_ACK 4 + +/* IKE fragmentation payload */ +struct isakmp_frag { + u_int16_t unknown0; /* always set to zero? */ + u_int16_t len; + u_int16_t unknown1; /* always set to 1? */ + u_int8_t index; + u_int8_t flags; +} __attribute__((__packed__)); + +/* flags */ +#define ISAKMP_FRAG_LAST 1 + +/* DPD R-U-THERE / R-U-THERE-ACK Payload */ +struct isakmp_pl_ru { + struct isakmp_gen h; + u_int32_t doi; /* Domain of Interpretation */ + u_int8_t proto_id; /* Protocol-Id */ + u_int8_t spi_size; /* SPI Size */ + u_int16_t type; /* Notify type */ + cookie_t i_ck; /* Initiator Cookie */ + cookie_t r_ck; /* Responder cookie*/ + u_int32_t data; /* Notification data */ +} __attribute__((__packed__)); + +#endif /* _ISAKMP_H */ diff --git a/ipsec-tools/src/racoon/isakmp_agg.c b/ipsec-tools/src/racoon/isakmp_agg.c new file mode 100644 index 00000000..2e387fb5 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_agg.c @@ -0,0 +1,1451 @@ +/* $NetBSD: isakmp_agg.c,v 1.16 2009/09/18 10:31:11 tteras Exp $ */ + +/* Id: isakmp_agg.c,v 1.28 2006/04/06 16:46:08 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Aggressive Exchange (Aggressive Mode) */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "schedule.h" +#include "debug.h" + +#ifdef ENABLE_HYBRID +#include +#endif + +#include "localconf.h" +#include "remoteconf.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "evt.h" +#include "oakley.h" +#include "handler.h" +#include "ipsec_doi.h" +#include "crypto_openssl.h" +#include "pfkey.h" +#include "isakmp_agg.h" +#include "isakmp_inf.h" +#ifdef ENABLE_HYBRID +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif +#ifdef ENABLE_FRAG +#include "isakmp_frag.h" +#endif +#include "vendorid.h" +#include "strnames.h" + +#ifdef ENABLE_NATT +#include "nattraversal.h" +#endif + +#ifdef HAVE_GSSAPI +#include "gssapi.h" +#endif + +/* + * begin Aggressive Mode as initiator. + */ +/* + * send to responder + * psk: HDR, SA, KE, Ni, IDi1 + * sig: HDR, SA, KE, Ni, IDi1 [, CR ] + * gssapi: HDR, SA, KE, Ni, IDi1, GSSi + * rsa: HDR, SA, [ HASH(1),] KE, Pubkey_r, Pubkey_r + * rev: HDR, SA, [ HASH(1),] Pubkey_r, Ke_i, + * Ke_i [, Ke_i ] + */ +int +agg_i1send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; /* must be null */ +{ + struct payload_list *plist = NULL; + int error = -1; +#ifdef ENABLE_NATT + vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL }; + int i; +#endif +#ifdef ENABLE_HYBRID + vchar_t *vid_xauth = NULL; + vchar_t *vid_unity = NULL; +#endif +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; +#endif +#ifdef HAVE_GSSAPI + vchar_t *gsstoken = NULL; + int len; +#endif +#ifdef ENABLE_DPD + vchar_t *vid_dpd = NULL; +#endif + + /* validity check */ + if (msg != NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "msg has to be NULL in this function.\n"); + goto end; + } + if (iph1->status != PHASE1ST_START) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* create isakmp index */ + memset(&iph1->index, 0, sizeof(iph1->index)); + isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local); + + /* make ID payload into isakmp status */ + if (ipsecdoi_setid1(iph1) < 0) + goto end; + + /* create SA payload for my proposal */ + iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf, iph1->rmconf->proposal); + if (iph1->sa == NULL) + goto end; + + /* consistency check of proposals */ + if (iph1->rmconf->dhgrp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "configuration failure about DH group.\n"); + goto end; + } + + /* generate DH public value */ + if (oakley_dh_generate(iph1->rmconf->dhgrp, + &iph1->dhpub, &iph1->dhpriv) < 0) + goto end; + + /* generate NONCE value */ + iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); + if (iph1->nonce == NULL) + goto end; + +#ifdef ENABLE_HYBRID + /* Do we need Xauth VID? */ + switch (iph1->rmconf->proposal->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Xauth vendor ID generation failed\n"); + if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Unity vendor ID generation failed\n"); + break; + default: + break; + } +#endif + +#ifdef ENABLE_FRAG + if (iph1->rmconf->ike_frag) { + vid_frag = set_vendorid(VENDORID_FRAG); + if (vid_frag != NULL) + vid_frag = isakmp_frag_addcap(vid_frag, + VENDORID_FRAG_AGG); + if (vid_frag == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Frag vendorID construction failed\n"); + } +#endif + + plog(LLV_DEBUG, LOCATION, NULL, "authmethod is %s\n", + s_oakley_attr_method(iph1->rmconf->proposal->authmethod)); +#ifdef HAVE_GSSAPI + if (iph1->rmconf->proposal->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) + gssapi_get_itoken(iph1, &len); +#endif + + /* set SA payload to propose */ + plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA); + + /* create isakmp KE payload */ + plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE); + + /* create isakmp NONCE payload */ + plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE); + + /* create isakmp ID payload */ + plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); + +#ifdef HAVE_GSSAPI + if (iph1->rmconf->proposal->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { + if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Failed to get gssapi token.\n"); + goto end; + } + plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); + } +#endif + /* create isakmp CR payload */ + if (oakley_needcr(iph1->rmconf->proposal->authmethod)) + plist = oakley_append_cr(plist, iph1); + +#ifdef ENABLE_FRAG + if (vid_frag) + plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID); +#endif +#ifdef ENABLE_NATT + /* + * set VID payload for NAT-T if NAT-T + * support allowed in the config file + */ + if (iph1->rmconf->nat_traversal) + plist = isakmp_plist_append_natt_vids(plist, vid_natt); +#endif +#ifdef ENABLE_HYBRID + if (vid_xauth) + plist = isakmp_plist_append(plist, + vid_xauth, ISAKMP_NPTYPE_VID); + if (vid_unity) + plist = isakmp_plist_append(plist, + vid_unity, ISAKMP_NPTYPE_VID); +#endif +#ifdef ENABLE_DPD + if(iph1->rmconf->dpd){ + vid_dpd = set_vendorid(VENDORID_DPD); + if (vid_dpd != NULL) + plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID); + } +#endif + + iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); +#endif + + /* send the packet, add to the schedule to resend */ + if (isakmp_ph1send(iph1) == -1) + goto end; + + iph1->status = PHASE1ST_MSG1SENT; + + error = 0; + +end: +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif +#ifdef ENABLE_FRAG + if (vid_frag) + vfree(vid_frag); +#endif +#ifdef ENABLE_NATT + for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++) + vfree(vid_natt[i]); +#endif +#ifdef ENABLE_HYBRID + if (vid_xauth != NULL) + vfree(vid_xauth); + if (vid_unity != NULL) + vfree(vid_unity); +#endif +#ifdef ENABLE_DPD + if (vid_dpd != NULL) + vfree(vid_dpd); +#endif + + return error; +} + +/* + * receive from responder + * psk: HDR, SA, KE, Nr, IDr1, HASH_R + * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R + * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R + * rsa: HDR, SA, KE, PubKey_i, PubKey_i, HASH_R + * rev: HDR, SA, PubKey_i, Ke_r, Ke_r, HASH_R + */ +int +agg_i2recv(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + vchar_t *satmp = NULL; + int error = -1; + int ptype; +#ifdef ENABLE_HYBRID + vchar_t *unity_vid; + vchar_t *xauth_vid; +#endif +#ifdef HAVE_GSSAPI + vchar_t *gsstoken = NULL; +#endif + +#ifdef ENABLE_NATT + int natd_seq = 0; + struct natd_payload { + int seq; + vchar_t *payload; + TAILQ_ENTRY(natd_payload) chain; + }; + TAILQ_HEAD(_natd_payload, natd_payload) natd_tree; + TAILQ_INIT(&natd_tree); +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG1SENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + pa = (struct isakmp_parse_t *)pbuf->v; + + iph1->pl_hash = NULL; + + /* SA payload is fixed postion */ + if (pa->type != ISAKMP_NPTYPE_SA) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "received invalid next payload type %d, " + "expecting %d.\n", + pa->type, ISAKMP_NPTYPE_SA); + goto end; + } + + if (isakmp_p2ph(&satmp, pa->ptr) < 0) + goto end; + pa++; + + for (/*nothing*/; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_KE: + if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_NONCE: + if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_ID: + if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_HASH: + iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; + break; + case ISAKMP_NPTYPE_CR: + if (oakley_savecr(iph1, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_CERT: + if (oakley_savecert(iph1, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_SIG: + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_VID: + handle_vendorid(iph1, pa->ptr); + break; + case ISAKMP_NPTYPE_N: + isakmp_log_notify(iph1, + (struct isakmp_pl_n *) pa->ptr, + "aggressive exchange"); + break; +#ifdef HAVE_GSSAPI + case ISAKMP_NPTYPE_GSS: + if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + goto end; + gssapi_save_received_token(iph1, gsstoken); + break; +#endif + +#ifdef ENABLE_NATT + case ISAKMP_NPTYPE_NATD_DRAFT: + case ISAKMP_NPTYPE_NATD_RFC: + if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL && + pa->type == iph1->natt_options->payload_nat_d) { + struct natd_payload *natd; + natd = (struct natd_payload *)racoon_malloc(sizeof(*natd)); + if (!natd) + goto end; + + natd->payload = NULL; + + if (isakmp_p2ph (&natd->payload, pa->ptr) < 0) + goto end; + + natd->seq = natd_seq++; + + TAILQ_INSERT_TAIL(&natd_tree, natd, chain); + break; + } + /* passthrough to default... */ +#endif + + default: + /* don't send information, see isakmp_ident_r1() */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + + /* payload existency check */ + if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "few isakmp message received.\n"); + goto end; + } + + /* verify identifier */ + if (ipsecdoi_checkid1(iph1) != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "invalid ID payload.\n"); + goto end; + } + + /* check SA payload and set approval SA for use */ + if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to get valid proposal.\n"); + /* XXX send information */ + goto end; + } + VPTRINIT(iph1->sa_ret); + + /* fix isakmp index */ + memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck, + sizeof(cookie_t)); + +#ifdef ENABLE_NATT + if (NATT_AVAILABLE(iph1)) { + struct natd_payload *natd = NULL; + int natd_verified; + + plog(LLV_INFO, LOCATION, iph1->remote, + "Selected NAT-T version: %s\n", + vid_string_by_id(iph1->natt_options->version)); + + /* set both bits first so that we can clear them + upon verifying hashes */ + iph1->natt_flags |= NAT_DETECTED; + + while ((natd = TAILQ_FIRST(&natd_tree)) != NULL) { + /* this function will clear appropriate bits bits + from iph1->natt_flags */ + natd_verified = natt_compare_addr_hash (iph1, + natd->payload, natd->seq); + + plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n", + natd->seq - 1, + natd_verified ? "verified" : "doesn't match"); + + vfree (natd->payload); + + TAILQ_REMOVE(&natd_tree, natd, chain); + racoon_free (natd); + } + + plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n", + iph1->natt_flags & NAT_DETECTED ? + "detected:" : "not detected", + iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "", + iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : ""); + + if (iph1->natt_flags & NAT_DETECTED) + natt_float_ports (iph1); + } +#endif + + /* compute sharing secret of DH */ + if (oakley_dh_compute(iph1->rmconf->dhgrp, iph1->dhpub, + iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) + goto end; + + /* generate SKEYIDs & IV & final cipher key */ + if (oakley_skeyid(iph1) < 0) + goto end; + if (oakley_skeyid_dae(iph1) < 0) + goto end; + if (oakley_compute_enckey(iph1) < 0) + goto end; + if (oakley_newiv(iph1) < 0) + goto end; + + /* validate authentication value */ + ptype = oakley_validate_auth(iph1); + if (ptype != 0) { + if (ptype == -1) { + /* message printed inner oakley_validate_auth() */ + goto end; + } + evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL); + isakmp_info_send_n1(iph1, ptype, NULL); + goto end; + } + + if (oakley_checkcr(iph1) < 0) { + /* Ignore this error in order to be interoperability. */ + ; + } + + /* change status of isakmp status entry */ + iph1->status = PHASE1ST_MSG2RECEIVED; + + error = 0; + +end: +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif + if (pbuf) + vfree(pbuf); + if (satmp) + vfree(satmp); + if (error) { + VPTRINIT(iph1->dhpub_p); + VPTRINIT(iph1->nonce_p); + VPTRINIT(iph1->id_p); + VPTRINIT(iph1->cert_p); + VPTRINIT(iph1->crl_p); + VPTRINIT(iph1->sig_p); + VPTRINIT(iph1->cr_p); + } + + return error; +} + +/* + * send to responder + * psk: HDR, HASH_I + * gssapi: HDR, HASH_I + * sig: HDR, [ CERT, ] SIG_I + * rsa: HDR, HASH_I + * rev: HDR, HASH_I + */ +int +agg_i2send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + struct payload_list *plist = NULL; + int need_cert = 0; + int error = -1; + vchar_t *gsshash = NULL; + + /* validity check */ + if (iph1->status != PHASE1ST_MSG2RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* generate HASH to send */ + plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n"); + iph1->hash = oakley_ph1hash_common(iph1, GENERATE); + if (iph1->hash == NULL) { +#ifdef HAVE_GSSAPI + if (gssapi_more_tokens(iph1) && +#ifdef ENABLE_HYBRID + !iph1->rmconf->xauth && +#endif + 1) + isakmp_info_send_n1(iph1, + ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); +#endif + goto end; + } + + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: +#endif + /* set HASH payload */ + plist = isakmp_plist_append(plist, + iph1->hash, ISAKMP_NPTYPE_HASH); + break; + + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: +#endif + /* XXX if there is CR or not ? */ + + if (oakley_getmycert(iph1) < 0) + goto end; + + if (oakley_getsign(iph1) < 0) + goto end; + + if (iph1->cert != NULL && iph1->rmconf->send_cert) + need_cert = 1; + + /* add CERT payload if there */ + if (need_cert) + plist = isakmp_plist_append(plist, iph1->cert, + ISAKMP_NPTYPE_CERT); + + /* add SIG payload */ + plist = isakmp_plist_append(plist, + iph1->sig, ISAKMP_NPTYPE_SIG); + break; + + case OAKLEY_ATTR_AUTH_METHOD_RSAENC: + case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: +#endif + break; +#ifdef HAVE_GSSAPI + case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: + gsshash = gssapi_wraphash(iph1); + if (gsshash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to wrap hash\n"); + isakmp_info_send_n1(iph1, + ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); + goto end; + } + + plist = isakmp_plist_append(plist, + gsshash, ISAKMP_NPTYPE_HASH); + break; +#endif + } + +#ifdef ENABLE_NATT + /* generate NAT-D payloads */ + if (NATT_AVAILABLE(iph1)) { + vchar_t *natd[2] = { NULL, NULL }; + + plog(LLV_INFO, LOCATION, + NULL, "Adding remote and local NAT-D payloads.\n"); + + if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "NAT-D hashing failed for %s\n", + saddr2str(iph1->remote)); + goto end; + } + + if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "NAT-D hashing failed for %s\n", + saddr2str(iph1->local)); + goto end; + } + + plist = isakmp_plist_append(plist, + natd[0], iph1->natt_options->payload_nat_d); + plist = isakmp_plist_append(plist, + natd[1], iph1->natt_options->payload_nat_d); + } +#endif + + iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); +#endif + + /* send to responder */ + if (isakmp_send(iph1, iph1->sendbuf) < 0) + goto end; + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + /* set encryption flag */ + iph1->flags |= ISAKMP_FLAG_E; + + iph1->status = PHASE1ST_ESTABLISHED; + + error = 0; + +end: + if (gsshash) + vfree(gsshash); + return error; +} + +/* + * receive from initiator + * psk: HDR, SA, KE, Ni, IDi1 + * sig: HDR, SA, KE, Ni, IDi1 [, CR ] + * gssapi: HDR, SA, KE, Ni, IDi1 , GSSi + * rsa: HDR, SA, [ HASH(1),] KE, Pubkey_r, Pubkey_r + * rev: HDR, SA, [ HASH(1),] Pubkey_r, Ke_i, + * Ke_i [, Ke_i ] + */ +int +agg_r1recv(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + int error = -1; + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + int vid_numeric; +#ifdef HAVE_GSSAPI + vchar_t *gsstoken = NULL; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_START) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + pa = (struct isakmp_parse_t *)pbuf->v; + + /* SA payload is fixed postion */ + if (pa->type != ISAKMP_NPTYPE_SA) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "received invalid next payload type %d, " + "expecting %d.\n", + pa->type, ISAKMP_NPTYPE_SA); + goto end; + } + if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) + goto end; + pa++; + + for (/*nothing*/; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + plog(LLV_DEBUG, LOCATION, NULL, + "received payload of type %s\n", + s_isakmp_nptype(pa->type)); + + switch (pa->type) { + case ISAKMP_NPTYPE_KE: + if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_NONCE: + if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_ID: + if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_VID: + vid_numeric = handle_vendorid(iph1, pa->ptr); +#ifdef ENABLE_FRAG + if ((vid_numeric == VENDORID_FRAG) && + (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_AGG)) + iph1->frag = 1; +#endif + break; + + case ISAKMP_NPTYPE_CR: + if (oakley_savecr(iph1, pa->ptr) < 0) + goto end; + break; + +#ifdef HAVE_GSSAPI + case ISAKMP_NPTYPE_GSS: + if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + goto end; + gssapi_save_received_token(iph1, gsstoken); + break; +#endif + default: + /* don't send information, see isakmp_ident_r1() */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + + /* payload existency check */ + if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "few isakmp message received.\n"); + goto end; + } + + /* verify identifier */ + if (ipsecdoi_checkid1(iph1) != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "invalid ID payload.\n"); + goto end; + } + +#ifdef ENABLE_NATT + if (NATT_AVAILABLE(iph1)) + plog(LLV_INFO, LOCATION, iph1->remote, + "Selected NAT-T version: %s\n", + vid_string_by_id(iph1->natt_options->version)); +#endif + + /* check SA payload and set approval SA for use */ + if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to get valid proposal.\n"); + /* XXX send information */ + goto end; + } + + if (oakley_checkcr(iph1) < 0) { + /* Ignore this error in order to be interoperability. */ + ; + } + + iph1->status = PHASE1ST_MSG1RECEIVED; + + error = 0; + +end: +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif + if (pbuf) + vfree(pbuf); + if (error) { + VPTRINIT(iph1->sa); + VPTRINIT(iph1->dhpub_p); + VPTRINIT(iph1->nonce_p); + VPTRINIT(iph1->id_p); + VPTRINIT(iph1->cr_p); + } + + return error; +} + +/* + * send to initiator + * psk: HDR, SA, KE, Nr, IDr1, HASH_R + * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R + * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R + * rsa: HDR, SA, KE, PubKey_i, PubKey_i, HASH_R + * rev: HDR, SA, PubKey_i, Ke_r, Ke_r, HASH_R + */ +int +agg_r1send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + struct payload_list *plist = NULL; + int need_cert = 0; + int error = -1; +#ifdef ENABLE_HYBRID + vchar_t *xauth_vid = NULL; + vchar_t *unity_vid = NULL; +#endif +#ifdef ENABLE_NATT + vchar_t *vid_natt = NULL; + vchar_t *natd[2] = { NULL, NULL }; +#endif +#ifdef ENABLE_DPD + vchar_t *vid_dpd = NULL; +#endif +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; +#endif + +#ifdef HAVE_GSSAPI + int gsslen; + vchar_t *gsstoken = NULL, *gsshash = NULL; + vchar_t *gss_sa = NULL; + int free_gss_sa = 0; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG1RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* set responder's cookie */ + isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local); + + /* make ID payload into isakmp status */ + if (ipsecdoi_setid1(iph1) < 0) + goto end; + + /* generate DH public value */ + if (oakley_dh_generate(iph1->rmconf->dhgrp, + &iph1->dhpub, &iph1->dhpriv) < 0) + goto end; + + /* generate NONCE value */ + iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); + if (iph1->nonce == NULL) + goto end; + + /* compute sharing secret of DH */ + if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, + iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) + goto end; + + /* generate SKEYIDs & IV & final cipher key */ + if (oakley_skeyid(iph1) < 0) + goto end; + if (oakley_skeyid_dae(iph1) < 0) + goto end; + if (oakley_compute_enckey(iph1) < 0) + goto end; + if (oakley_newiv(iph1) < 0) + goto end; + +#ifdef HAVE_GSSAPI + if (iph1->rmconf->proposal->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) + gssapi_get_rtoken(iph1, &gsslen); +#endif + + /* generate HASH to send */ + plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n"); + iph1->hash = oakley_ph1hash_common(iph1, GENERATE); + if (iph1->hash == NULL) { +#ifdef HAVE_GSSAPI + if (gssapi_more_tokens(iph1)) + isakmp_info_send_n1(iph1, + ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); +#endif + goto end; + } + +#ifdef ENABLE_NATT + /* Has the peer announced NAT-T? */ + if (NATT_AVAILABLE(iph1)) { + /* set chosen VID */ + vid_natt = set_vendorid(iph1->natt_options->version); + + /* generate NAT-D payloads */ + plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n"); + if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "NAT-D hashing failed for %s\n", saddr2str(iph1->remote)); + goto end; + } + + if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "NAT-D hashing failed for %s\n", saddr2str(iph1->local)); + goto end; + } + } +#endif +#ifdef ENABLE_DPD + /* Only send DPD support if remote announced DPD and if DPD support is active */ + if (iph1->dpd_support && iph1->rmconf->dpd) + vid_dpd = set_vendorid(VENDORID_DPD); +#endif +#ifdef ENABLE_FRAG + if (iph1->frag) { + vid_frag = set_vendorid(VENDORID_FRAG); + if (vid_frag != NULL) + vid_frag = isakmp_frag_addcap(vid_frag, + VENDORID_FRAG_AGG); + if (vid_frag == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Frag vendorID construction failed\n"); + } +#endif + + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif + /* set SA payload to reply */ + plist = isakmp_plist_append(plist, + iph1->sa_ret, ISAKMP_NPTYPE_SA); + + /* create isakmp KE payload */ + plist = isakmp_plist_append(plist, + iph1->dhpub, ISAKMP_NPTYPE_KE); + + /* create isakmp NONCE payload */ + plist = isakmp_plist_append(plist, + iph1->nonce, ISAKMP_NPTYPE_NONCE); + + /* create isakmp ID payload */ + plist = isakmp_plist_append(plist, + iph1->id, ISAKMP_NPTYPE_ID); + + /* create isakmp HASH payload */ + plist = isakmp_plist_append(plist, + iph1->hash, ISAKMP_NPTYPE_HASH); + + /* create isakmp CR payload if needed */ + if (oakley_needcr(iph1->approval->authmethod)) + plist = oakley_append_cr(plist, iph1); + break; + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: +#endif + /* XXX if there is CR or not ? */ + + if (oakley_getmycert(iph1) < 0) + goto end; + + if (oakley_getsign(iph1) < 0) + goto end; + + if (iph1->cert != NULL && iph1->rmconf->send_cert) + need_cert = 1; + + /* set SA payload to reply */ + plist = isakmp_plist_append(plist, + iph1->sa_ret, ISAKMP_NPTYPE_SA); + + /* create isakmp KE payload */ + plist = isakmp_plist_append(plist, + iph1->dhpub, ISAKMP_NPTYPE_KE); + + /* create isakmp NONCE payload */ + plist = isakmp_plist_append(plist, + iph1->nonce, ISAKMP_NPTYPE_NONCE); + + /* add ID payload */ + plist = isakmp_plist_append(plist, + iph1->id, ISAKMP_NPTYPE_ID); + + /* add CERT payload if there */ + if (need_cert) + plist = isakmp_plist_append(plist, iph1->cert, + ISAKMP_NPTYPE_CERT); + + /* add SIG payload */ + plist = isakmp_plist_append(plist, + iph1->sig, ISAKMP_NPTYPE_SIG); + + /* create isakmp CR payload if needed */ + if (oakley_needcr(iph1->approval->authmethod)) + plist = oakley_append_cr(plist, iph1); + break; + + case OAKLEY_ATTR_AUTH_METHOD_RSAENC: + case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif + break; +#ifdef HAVE_GSSAPI + case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: + /* create buffer to send isakmp payload */ + gsshash = gssapi_wraphash(iph1); + if (gsshash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to wrap hash\n"); + /* + * This is probably due to the GSS + * roundtrips not being finished yet. + * Return this error in the hope that + * a fallback to main mode will be done. + */ + isakmp_info_send_n1(iph1, + ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); + goto end; + } + if (iph1->approval->gssid != NULL) + gss_sa = ipsecdoi_setph1proposal(iph1->rmconf, + iph1->approval); + else + gss_sa = iph1->sa_ret; + + if (gss_sa != iph1->sa_ret) + free_gss_sa = 1; + + /* set SA payload to reply */ + plist = isakmp_plist_append(plist, + gss_sa, ISAKMP_NPTYPE_SA); + + /* create isakmp KE payload */ + plist = isakmp_plist_append(plist, + iph1->dhpub, ISAKMP_NPTYPE_KE); + + /* create isakmp NONCE payload */ + plist = isakmp_plist_append(plist, + iph1->nonce, ISAKMP_NPTYPE_NONCE); + + /* create isakmp ID payload */ + plist = isakmp_plist_append(plist, + iph1->id, ISAKMP_NPTYPE_ID); + + /* create GSS payload */ + if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Failed to get gssapi token.\n"); + goto end; + } + plist = isakmp_plist_append(plist, + gsstoken, ISAKMP_NPTYPE_GSS); + + /* create isakmp HASH payload */ + plist = isakmp_plist_append(plist, + gsshash, ISAKMP_NPTYPE_HASH); + + /* append vendor id, if needed */ + break; +#endif + } + +#ifdef ENABLE_HYBRID + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { + plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n"); + if ((xauth_vid = set_vendorid(VENDORID_XAUTH)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot create Xauth vendor ID\n"); + goto end; + } + plist = isakmp_plist_append(plist, + xauth_vid, ISAKMP_NPTYPE_VID); + } + + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) { + if ((unity_vid = set_vendorid(VENDORID_UNITY)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot create Unity vendor ID\n"); + goto end; + } + plist = isakmp_plist_append(plist, + unity_vid, ISAKMP_NPTYPE_VID); + } +#endif + +#ifdef ENABLE_NATT + /* append NAT-T payloads */ + if (vid_natt) { + /* chosen VID */ + plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID); + /* NAT-D */ + plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d); + plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d); + } +#endif + +#ifdef ENABLE_FRAG + if (vid_frag) + plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID); +#endif + +#ifdef ENABLE_DPD + if (vid_dpd) + plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID); +#endif + + iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 1); +#endif + + /* send the packet, add to the schedule to resend */ + if (isakmp_ph1send(iph1) == -1) + goto end; + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + iph1->status = PHASE1ST_MSG1SENT; + + error = 0; + +end: +#ifdef ENABLE_HYBRID + if (xauth_vid) + vfree(xauth_vid); + if (unity_vid) + vfree(unity_vid); +#endif +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); + if (gsshash) + vfree(gsshash); + if (free_gss_sa) + vfree(gss_sa); +#endif +#ifdef ENABLE_DPD + if (vid_dpd) + vfree(vid_dpd); +#endif +#ifdef ENABLE_FRAG + if (vid_frag) + vfree(vid_frag); +#endif + + return error; +} + +/* + * receive from initiator + * psk: HDR, HASH_I + * gssapi: HDR, HASH_I + * sig: HDR, [ CERT, ] SIG_I + * rsa: HDR, HASH_I + * rev: HDR, HASH_I + */ +int +agg_r2recv(iph1, msg0) + struct ph1handle *iph1; + vchar_t *msg0; +{ + vchar_t *msg = NULL; + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + int error = -1, ptype; +#ifdef ENABLE_NATT + int natd_seq = 0; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG1SENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* decrypting if need. */ + /* XXX configurable ? */ + if (ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { + msg = oakley_do_decrypt(iph1, msg0, + iph1->ivm->iv, iph1->ivm->ive); + if (msg == NULL) + goto end; + } else + msg = vdup(msg0); + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + + iph1->pl_hash = NULL; + + for (pa = (struct isakmp_parse_t *)pbuf->v; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_HASH: + iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; + break; + case ISAKMP_NPTYPE_VID: + handle_vendorid(iph1, pa->ptr); + break; + case ISAKMP_NPTYPE_CERT: + if (oakley_savecert(iph1, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_SIG: + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_N: + isakmp_log_notify(iph1, + (struct isakmp_pl_n *) pa->ptr, + "aggressive exchange"); + break; + +#ifdef ENABLE_NATT + case ISAKMP_NPTYPE_NATD_DRAFT: + case ISAKMP_NPTYPE_NATD_RFC: + if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL && + pa->type == iph1->natt_options->payload_nat_d) + { + vchar_t *natd_received = NULL; + int natd_verified; + + if (isakmp_p2ph (&natd_received, pa->ptr) < 0) + goto end; + + if (natd_seq == 0) + iph1->natt_flags |= NAT_DETECTED; + + natd_verified = natt_compare_addr_hash (iph1, + natd_received, natd_seq++); + + plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n", + natd_seq - 1, + natd_verified ? "verified" : "doesn't match"); + + vfree (natd_received); + break; + } + /* passthrough to default... */ +#endif + + default: + /* don't send information, see isakmp_ident_r1() */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + +#ifdef ENABLE_NATT + if (NATT_AVAILABLE(iph1)) + plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n", + iph1->natt_flags & NAT_DETECTED ? + "detected:" : "not detected", + iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "", + iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : ""); +#endif + + /* validate authentication value */ + ptype = oakley_validate_auth(iph1); + if (ptype != 0) { + if (ptype == -1) { + /* message printed inner oakley_validate_auth() */ + goto end; + } + evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL); + isakmp_info_send_n1(iph1, ptype, NULL); + goto end; + } + + iph1->status = PHASE1ST_MSG2RECEIVED; + + error = 0; + +end: + if (pbuf) + vfree(pbuf); + if (msg) + vfree(msg); + if (error) { + VPTRINIT(iph1->cert_p); + VPTRINIT(iph1->crl_p); + VPTRINIT(iph1->sig_p); + } + + return error; +} + +/* + * status update and establish isakmp sa. + */ +int +agg_r2send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + int error = -1; + + /* validity check */ + if (iph1->status != PHASE1ST_MSG2RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* IV synchronized when packet encrypted. */ + /* see handler.h about IV synchronization. */ + if (ISSET(((struct isakmp *)msg->v)->flags, ISAKMP_FLAG_E)) + memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l); + + /* set encryption flag */ + iph1->flags |= ISAKMP_FLAG_E; + + iph1->status = PHASE1ST_ESTABLISHED; + + error = 0; + +end: + return error; +} diff --git a/ipsec-tools/src/racoon/isakmp_agg.h b/ipsec-tools/src/racoon/isakmp_agg.h new file mode 100644 index 00000000..89645ebe --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_agg.h @@ -0,0 +1,46 @@ +/* $NetBSD: isakmp_agg.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: isakmp_agg.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ISAKMP_AGG_H +#define _ISAKMP_AGG_H + +extern int agg_i1send __P((struct ph1handle *, vchar_t *)); +extern int agg_i2recv __P((struct ph1handle *, vchar_t *)); +extern int agg_i2send __P((struct ph1handle *, vchar_t *)); + +extern int agg_r1recv __P((struct ph1handle *, vchar_t *)); +extern int agg_r1send __P((struct ph1handle *, vchar_t *)); +extern int agg_r2recv __P((struct ph1handle *, vchar_t *)); +extern int agg_r2send __P((struct ph1handle *, vchar_t *)); + +#endif /* _ISAKMP_AGG_H */ diff --git a/ipsec-tools/src/racoon/isakmp_base.c b/ipsec-tools/src/racoon/isakmp_base.c new file mode 100644 index 00000000..f37d51e0 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_base.c @@ -0,0 +1,1394 @@ +/* $NetBSD: isakmp_base.c,v 1.12 2009/03/12 10:57:26 tteras Exp $ */ + +/* $KAME: isakmp_base.c,v 1.49 2003/11/13 02:30:20 sakane Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Base Exchange (Base Mode) */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "schedule.h" +#include "debug.h" + +#ifdef ENABLE_HYBRID +#include +#endif + +#include "localconf.h" +#include "remoteconf.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "evt.h" +#include "oakley.h" +#include "handler.h" +#include "ipsec_doi.h" +#include "crypto_openssl.h" +#include "pfkey.h" +#include "isakmp_base.h" +#include "isakmp_inf.h" +#include "vendorid.h" +#ifdef ENABLE_NATT +#include "nattraversal.h" +#endif +#ifdef ENABLE_FRAG +#include "isakmp_frag.h" +#endif +#ifdef ENABLE_HYBRID +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif + +/* %%% + * begin Identity Protection Mode as initiator. + */ +/* + * send to responder + * psk: HDR, SA, Idii, Ni_b + * sig: HDR, SA, Idii, Ni_b + * rsa: HDR, SA, [HASH(1),] Pubkey_r, Pubkey_r + * rev: HDR, SA, [HASH(1),] Pubkey_r, Ke_i + */ +int +base_i1send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; /* must be null */ +{ + struct payload_list *plist = NULL; + int error = -1; +#ifdef ENABLE_NATT + vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL }; + int i, vid_natt_i = 0; +#endif +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; +#endif +#ifdef ENABLE_HYBRID + vchar_t *vid_xauth = NULL; + vchar_t *vid_unity = NULL; +#endif +#ifdef ENABLE_DPD + vchar_t *vid_dpd = NULL; +#endif + + + /* validity check */ + if (msg != NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "msg has to be NULL in this function.\n"); + goto end; + } + if (iph1->status != PHASE1ST_START) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* create isakmp index */ + memset(&iph1->index, 0, sizeof(iph1->index)); + isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local); + + /* make ID payload into isakmp status */ + if (ipsecdoi_setid1(iph1) < 0) + goto end; + + /* create SA payload for my proposal */ + iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf, + iph1->rmconf->proposal); + if (iph1->sa == NULL) + goto end; + + /* generate NONCE value */ + iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); + if (iph1->nonce == NULL) + goto end; + +#ifdef ENABLE_HYBRID + /* Do we need Xauth VID? */ + switch (iph1->rmconf->proposal->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Xauth vendor ID generation failed\n"); + + if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Unity vendor ID generation failed\n"); + break; + default: + break; + } +#endif +#ifdef ENABLE_FRAG + if (iph1->rmconf->ike_frag) { + vid_frag = set_vendorid(VENDORID_FRAG); + if (vid_frag != NULL) + vid_frag = isakmp_frag_addcap(vid_frag, + VENDORID_FRAG_BASE); + if (vid_frag == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Frag vendorID construction failed\n"); + } +#endif +#ifdef ENABLE_NATT + /* Is NAT-T support allowed in the config file? */ + if (iph1->rmconf->nat_traversal) { + /* Advertise NAT-T capability */ + memset (vid_natt, 0, sizeof (vid_natt)); +#ifdef VENDORID_NATT_00 + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_00)) != NULL) + vid_natt_i++; +#endif +#ifdef VENDORID_NATT_02 + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02)) != NULL) + vid_natt_i++; +#endif +#ifdef VENDORID_NATT_02_N + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02_N)) != NULL) + vid_natt_i++; +#endif +#ifdef VENDORID_NATT_RFC + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_RFC)) != NULL) + vid_natt_i++; +#endif + } +#endif + + /* set SA payload to propose */ + plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA); + + /* create isakmp ID payload */ + plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); + + /* create isakmp NONCE payload */ + plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE); + +#ifdef ENABLE_FRAG + if (vid_frag) + plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID); +#endif +#ifdef ENABLE_HYBRID + if (vid_xauth) + plist = isakmp_plist_append(plist, + vid_xauth, ISAKMP_NPTYPE_VID); + if (vid_unity) + plist = isakmp_plist_append(plist, + vid_unity, ISAKMP_NPTYPE_VID); +#endif +#ifdef ENABLE_DPD + if (iph1->rmconf->dpd) { + vid_dpd = set_vendorid(VENDORID_DPD); + if (vid_dpd != NULL) + plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID); + } +#endif +#ifdef ENABLE_NATT + /* set VID payload for NAT-T */ + for (i = 0; i < vid_natt_i; i++) + plist = isakmp_plist_append(plist, vid_natt[i], ISAKMP_NPTYPE_VID); +#endif + iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); +#endif + + /* send the packet, add to the schedule to resend */ + if (isakmp_ph1send(iph1) == -1) + goto end; + + iph1->status = PHASE1ST_MSG1SENT; + + error = 0; + +end: +#ifdef ENABLE_FRAG + if (vid_frag) + vfree(vid_frag); +#endif +#ifdef ENABLE_NATT + for (i = 0; i < vid_natt_i; i++) + vfree(vid_natt[i]); +#endif +#ifdef ENABLE_HYBRID + if (vid_xauth != NULL) + vfree(vid_xauth); + if (vid_unity != NULL) + vfree(vid_unity); +#endif +#ifdef ENABLE_DPD + if (vid_dpd != NULL) + vfree(vid_dpd); +#endif + + return error; +} + +/* + * receive from responder + * psk: HDR, SA, Idir, Nr_b + * sig: HDR, SA, Idir, Nr_b, [ CR ] + * rsa: HDR, SA, PubKey_i, PubKey_i + * rev: HDR, SA, PubKey_i, Ke_r + */ +int +base_i2recv(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + vchar_t *satmp = NULL; + int error = -1; +#ifdef ENABLE_HYBRID + vchar_t *unity_vid; + vchar_t *xauth_vid; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG1SENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + pa = (struct isakmp_parse_t *)pbuf->v; + + /* SA payload is fixed postion */ + if (pa->type != ISAKMP_NPTYPE_SA) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "received invalid next payload type %d, " + "expecting %d.\n", + pa->type, ISAKMP_NPTYPE_SA); + goto end; + } + if (isakmp_p2ph(&satmp, pa->ptr) < 0) + goto end; + pa++; + + for (/*nothing*/; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_NONCE: + if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_ID: + if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_VID: + handle_vendorid(iph1, pa->ptr); + break; + default: + /* don't send information, see ident_r1recv() */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + + if (iph1->nonce_p == NULL || iph1->id_p == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "few isakmp message received.\n"); + goto end; + } + + /* verify identifier */ + if (ipsecdoi_checkid1(iph1) != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "invalid ID payload.\n"); + goto end; + } + +#ifdef ENABLE_NATT + if (NATT_AVAILABLE(iph1)) + plog(LLV_INFO, LOCATION, iph1->remote, + "Selected NAT-T version: %s\n", + vid_string_by_id(iph1->natt_options->version)); +#endif + + /* check SA payload and set approval SA for use */ + if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to get valid proposal.\n"); + /* XXX send information */ + goto end; + } + VPTRINIT(iph1->sa_ret); + + iph1->status = PHASE1ST_MSG2RECEIVED; + + error = 0; + +end: + if (pbuf) + vfree(pbuf); + if (satmp) + vfree(satmp); + + if (error) { + VPTRINIT(iph1->nonce_p); + VPTRINIT(iph1->id_p); + } + + return error; +} + +/* + * send to responder + * psk: HDR, KE, HASH_I + * sig: HDR, KE, [ CR, ] [CERT,] SIG_I + * rsa: HDR, KE, HASH_I + * rev: HDR, Ke_i, HASH_I + */ +int +base_i2send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + struct payload_list *plist = NULL; + vchar_t *vid = NULL; + int need_cert = 0; + int error = -1; + + /* validity check */ + if (iph1->status != PHASE1ST_MSG2RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* fix isakmp index */ + memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck, + sizeof(cookie_t)); + + /* generate DH public value */ + if (oakley_dh_generate(iph1->approval->dhgrp, + &iph1->dhpub, &iph1->dhpriv) < 0) + goto end; + + /* generate SKEYID to compute hash if not signature mode */ + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: +#endif + break; + default: + if (oakley_skeyid(iph1) < 0) + goto end; + break; + } + + /* generate HASH to send */ + plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n"); + iph1->hash = oakley_ph1hash_base_i(iph1, GENERATE); + if (iph1->hash == NULL) + goto end; + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: +#endif + vid = set_vendorid(iph1->approval->vendorid); + + /* create isakmp KE payload */ + plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE); + + /* create isakmp HASH payload */ + plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH); + + /* append vendor id, if needed */ + if (vid) + plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); + break; + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: +#endif + /* XXX if there is CR or not ? */ + + if (oakley_getmycert(iph1) < 0) + goto end; + + if (oakley_getsign(iph1) < 0) + goto end; + + if (iph1->cert && iph1->rmconf->send_cert) + need_cert = 1; + + /* create isakmp KE payload */ + plist = isakmp_plist_append(plist, iph1->dhpub, + ISAKMP_NPTYPE_KE); + + /* add CERT payload if there */ + if (need_cert) + plist = isakmp_plist_append(plist, iph1->cert, + ISAKMP_NPTYPE_CERT); + + /* add SIG payload */ + plist = isakmp_plist_append(plist, + iph1->sig, ISAKMP_NPTYPE_SIG); + + break; +#ifdef HAVE_GSSAPI + case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: + /* ... */ + break; +#endif + case OAKLEY_ATTR_AUTH_METHOD_RSAENC: + case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: +#endif + break; + } + +#ifdef ENABLE_NATT + /* generate NAT-D payloads */ + if (NATT_AVAILABLE(iph1)) + { + vchar_t *natd[2] = { NULL, NULL }; + + plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n"); + if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "NAT-D hashing failed for %s\n", saddr2str(iph1->remote)); + goto end; + } + + if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "NAT-D hashing failed for %s\n", saddr2str(iph1->local)); + goto end; + } + + plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d); + plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d); + } +#endif + + iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); +#endif + + /* send the packet, add to the schedule to resend */ + if (isakmp_ph1send(iph1) == -1) + goto end; + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + iph1->status = PHASE1ST_MSG2SENT; + + error = 0; + +end: + if (vid) + vfree(vid); + return error; +} + +/* + * receive from responder + * psk: HDR, KE, HASH_R + * sig: HDR, KE, [CERT,] SIG_R + * rsa: HDR, KE, HASH_R + * rev: HDR, _Ke_r, HASH_R + */ +int +base_i3recv(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + int error = -1, ptype; +#ifdef ENABLE_NATT + vchar_t *natd_received; + int natd_seq = 0, natd_verified; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG2SENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + + for (pa = (struct isakmp_parse_t *)pbuf->v; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_KE: + if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_HASH: + iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; + break; + case ISAKMP_NPTYPE_CERT: + if (oakley_savecert(iph1, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_SIG: + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_VID: + handle_vendorid(iph1, pa->ptr); + break; + +#ifdef ENABLE_NATT + case ISAKMP_NPTYPE_NATD_DRAFT: + case ISAKMP_NPTYPE_NATD_RFC: + if (NATT_AVAILABLE(iph1) && iph1->natt_options && + pa->type == iph1->natt_options->payload_nat_d) { + natd_received = NULL; + if (isakmp_p2ph (&natd_received, pa->ptr) < 0) + goto end; + + /* set both bits first so that we can clear them + upon verifying hashes */ + if (natd_seq == 0) + iph1->natt_flags |= NAT_DETECTED; + + /* this function will clear appropriate bits bits + from iph1->natt_flags */ + natd_verified = natt_compare_addr_hash (iph1, + natd_received, natd_seq++); + + plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n", + natd_seq - 1, + natd_verified ? "verified" : "doesn't match"); + + vfree (natd_received); + break; + } + /* passthrough to default... */ +#endif + + default: + /* don't send information, see ident_r1recv() */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + +#ifdef ENABLE_NATT + if (NATT_AVAILABLE(iph1)) { + plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n", + iph1->natt_flags & NAT_DETECTED ? + "detected:" : "not detected", + iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "", + iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : ""); + if (iph1->natt_flags & NAT_DETECTED) + natt_float_ports (iph1); + } +#endif + + /* payload existency check */ + /* validate authentication value */ + ptype = oakley_validate_auth(iph1); + if (ptype != 0) { + if (ptype == -1) { + /* message printed inner oakley_validate_auth() */ + goto end; + } + evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL); + isakmp_info_send_n1(iph1, ptype, NULL); + goto end; + } + + /* compute sharing secret of DH */ + if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, + iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) + goto end; + + /* generate SKEYID to compute hash if signature mode */ + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: +#endif + if (oakley_skeyid(iph1) < 0) + goto end; + break; + default: + break; + } + + /* generate SKEYIDs & IV & final cipher key */ + if (oakley_skeyid_dae(iph1) < 0) + goto end; + if (oakley_compute_enckey(iph1) < 0) + goto end; + if (oakley_newiv(iph1) < 0) + goto end; + + /* see handler.h about IV synchronization. */ + memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l); + + /* set encryption flag */ + iph1->flags |= ISAKMP_FLAG_E; + + iph1->status = PHASE1ST_MSG3RECEIVED; + + error = 0; + +end: + if (pbuf) + vfree(pbuf); + + if (error) { + VPTRINIT(iph1->dhpub_p); + VPTRINIT(iph1->cert_p); + VPTRINIT(iph1->crl_p); + VPTRINIT(iph1->sig_p); + } + + return error; +} + +/* + * status update and establish isakmp sa. + */ +int +base_i3send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + int error = -1; + + /* validity check */ + if (iph1->status != PHASE1ST_MSG3RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + iph1->status = PHASE1ST_ESTABLISHED; + + error = 0; + +end: + return error; +} + +/* + * receive from initiator + * psk: HDR, SA, Idii, Ni_b + * sig: HDR, SA, Idii, Ni_b + * rsa: HDR, SA, [HASH(1),] Pubkey_r, Pubkey_r + * rev: HDR, SA, [HASH(1),] Pubkey_r, Ke_i + */ +int +base_r1recv(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + int error = -1; + int vid_numeric; + + /* validity check */ + if (iph1->status != PHASE1ST_START) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + pa = (struct isakmp_parse_t *)pbuf->v; + + /* check the position of SA payload */ + if (pa->type != ISAKMP_NPTYPE_SA) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "received invalid next payload type %d, " + "expecting %d.\n", + pa->type, ISAKMP_NPTYPE_SA); + goto end; + } + if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) + goto end; + pa++; + + for (/*nothing*/; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_NONCE: + if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_ID: + if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_VID: + vid_numeric = handle_vendorid(iph1, pa->ptr); +#ifdef ENABLE_FRAG + if ((vid_numeric == VENDORID_FRAG) && + (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_BASE)) + iph1->frag = 1; +#endif + break; + default: + /* don't send information, see ident_r1recv() */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + + if (iph1->nonce_p == NULL || iph1->id_p == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "few isakmp message received.\n"); + goto end; + } + + /* verify identifier */ + if (ipsecdoi_checkid1(iph1) != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "invalid ID payload.\n"); + goto end; + } + +#ifdef ENABLE_NATT + if (NATT_AVAILABLE(iph1)) + plog(LLV_INFO, LOCATION, iph1->remote, + "Selected NAT-T version: %s\n", + vid_string_by_id(iph1->natt_options->version)); +#endif + + /* check SA payload and set approval SA for use */ + if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to get valid proposal.\n"); + /* XXX send information */ + goto end; + } + + iph1->status = PHASE1ST_MSG1RECEIVED; + + error = 0; + +end: + if (pbuf) + vfree(pbuf); + + if (error) { + VPTRINIT(iph1->sa); + VPTRINIT(iph1->nonce_p); + VPTRINIT(iph1->id_p); + } + + return error; +} + +/* + * send to initiator + * psk: HDR, SA, Idir, Nr_b + * sig: HDR, SA, Idir, Nr_b, [ CR ] + * rsa: HDR, SA, PubKey_i, PubKey_i + * rev: HDR, SA, PubKey_i, Ke_r + */ +int +base_r1send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + struct payload_list *plist = NULL; + int error = -1; +#ifdef ENABLE_NATT + vchar_t *vid_natt = NULL; +#endif +#ifdef ENABLE_HYBRID + vchar_t *vid_xauth = NULL; + vchar_t *vid_unity = NULL; +#endif +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; +#endif +#ifdef ENABLE_DPD + vchar_t *vid_dpd = NULL; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG1RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* set responder's cookie */ + isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local); + + /* make ID payload into isakmp status */ + if (ipsecdoi_setid1(iph1) < 0) + goto end; + + /* generate NONCE value */ + iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); + if (iph1->nonce == NULL) + goto end; + + /* set SA payload to reply */ + plist = isakmp_plist_append(plist, iph1->sa_ret, ISAKMP_NPTYPE_SA); + + /* create isakmp ID payload */ + plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); + + /* create isakmp NONCE payload */ + plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE); + +#ifdef ENABLE_NATT + /* has the peer announced nat-t? */ + if (NATT_AVAILABLE(iph1)) + vid_natt = set_vendorid(iph1->natt_options->version); + if (vid_natt) + plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID); +#endif +#ifdef ENABLE_HYBRID + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { + plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n"); + if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot create Xauth vendor ID\n"); + goto end; + } + plist = isakmp_plist_append(plist, + vid_xauth, ISAKMP_NPTYPE_VID); + } + + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) { + if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot create Unity vendor ID\n"); + goto end; + } + plist = isakmp_plist_append(plist, + vid_unity, ISAKMP_NPTYPE_VID); + } +#endif +#ifdef ENABLE_DPD + /* + * Only send DPD support if remote announced DPD + * and if DPD support is active + */ + if (iph1->dpd_support && iph1->rmconf->dpd) { + if ((vid_dpd = set_vendorid(VENDORID_DPD)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "DPD vendorID construction failed\n"); + } else { + plist = isakmp_plist_append(plist, vid_dpd, + ISAKMP_NPTYPE_VID); + } + } +#endif +#ifdef ENABLE_FRAG + if (iph1->rmconf->ike_frag) { + if ((vid_frag = set_vendorid(VENDORID_FRAG)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Frag vendorID construction failed\n"); + } else { + vid_frag = isakmp_frag_addcap(vid_frag, + VENDORID_FRAG_BASE); + plist = isakmp_plist_append(plist, + vid_frag, ISAKMP_NPTYPE_VID); + } + } +#endif + + iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); +#endif + + /* send the packet, add to the schedule to resend */ + if (isakmp_ph1send(iph1) == -1) { + iph1 = NULL; + goto end; + } + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + iph1->status = PHASE1ST_MSG1SENT; + + error = 0; + +end: +#ifdef ENABLE_NATT + if (vid_natt) + vfree(vid_natt); +#endif +#ifdef ENABLE_HYBRID + if (vid_xauth != NULL) + vfree(vid_xauth); + if (vid_unity != NULL) + vfree(vid_unity); +#endif +#ifdef ENABLE_FRAG + if (vid_frag) + vfree(vid_frag); +#endif +#ifdef ENABLE_DPD + if (vid_dpd) + vfree(vid_dpd); +#endif + + if (iph1 != NULL) + VPTRINIT(iph1->sa_ret); + + return error; +} + +/* + * receive from initiator + * psk: HDR, KE, HASH_I + * sig: HDR, KE, [ CR, ] [CERT,] SIG_I + * rsa: HDR, KE, HASH_I + * rev: HDR, Ke_i, HASH_I + */ +int +base_r2recv(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + int error = -1, ptype; +#ifdef ENABLE_NATT + int natd_seq = 0; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG1SENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + + iph1->pl_hash = NULL; + + for (pa = (struct isakmp_parse_t *)pbuf->v; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_KE: + if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_HASH: + iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; + break; + case ISAKMP_NPTYPE_CERT: + if (oakley_savecert(iph1, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_SIG: + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_VID: + handle_vendorid(iph1, pa->ptr); + break; + +#ifdef ENABLE_NATT + case ISAKMP_NPTYPE_NATD_DRAFT: + case ISAKMP_NPTYPE_NATD_RFC: + if (pa->type == iph1->natt_options->payload_nat_d) + { + vchar_t *natd_received = NULL; + int natd_verified; + + if (isakmp_p2ph (&natd_received, pa->ptr) < 0) + goto end; + + if (natd_seq == 0) + iph1->natt_flags |= NAT_DETECTED; + + natd_verified = natt_compare_addr_hash (iph1, + natd_received, natd_seq++); + + plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n", + natd_seq - 1, + natd_verified ? "verified" : "doesn't match"); + + vfree (natd_received); + break; + } + /* passthrough to default... */ +#endif + + default: + /* don't send information, see ident_r1recv() */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + + /* generate DH public value */ + if (oakley_dh_generate(iph1->approval->dhgrp, + &iph1->dhpub, &iph1->dhpriv) < 0) + goto end; + + /* compute sharing secret of DH */ + if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, + iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) + goto end; + + /* generate SKEYID */ + if (oakley_skeyid(iph1) < 0) + goto end; + +#ifdef ENABLE_NATT + if (NATT_AVAILABLE(iph1)) + plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n", + iph1->natt_flags & NAT_DETECTED ? + "detected:" : "not detected", + iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "", + iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : ""); +#endif + + /* payload existency check */ + /* validate authentication value */ + ptype = oakley_validate_auth(iph1); + if (ptype != 0) { + if (ptype == -1) { + /* message printed inner oakley_validate_auth() */ + goto end; + } + evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL); + isakmp_info_send_n1(iph1, ptype, NULL); + goto end; + } + + iph1->status = PHASE1ST_MSG2RECEIVED; + + error = 0; + +end: + if (pbuf) + vfree(pbuf); + + if (error) { + VPTRINIT(iph1->dhpub_p); + VPTRINIT(iph1->cert_p); + VPTRINIT(iph1->crl_p); + VPTRINIT(iph1->sig_p); + } + + return error; +} + +/* + * send to initiator + * psk: HDR, KE, HASH_R + * sig: HDR, KE, [CERT,] SIG_R + * rsa: HDR, KE, HASH_R + * rev: HDR, _Ke_r, HASH_R + */ +int +base_r2send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + struct payload_list *plist = NULL; + vchar_t *vid = NULL; + int need_cert = 0; + int error = -1; + + /* validity check */ + if (iph1->status != PHASE1ST_MSG2RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* generate HASH to send */ + plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n"); + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif + case OAKLEY_ATTR_AUTH_METHOD_RSAENC: + case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif + iph1->hash = oakley_ph1hash_common(iph1, GENERATE); + break; + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: +#endif +#ifdef HAVE_GSSAPI + case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: +#endif + iph1->hash = oakley_ph1hash_base_r(iph1, GENERATE); + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid authentication method %d\n", + iph1->approval->authmethod); + goto end; + } + if (iph1->hash == NULL) + goto end; + + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif + vid = set_vendorid(iph1->approval->vendorid); + + /* create isakmp KE payload */ + plist = isakmp_plist_append(plist, + iph1->dhpub, ISAKMP_NPTYPE_KE); + + /* create isakmp HASH payload */ + plist = isakmp_plist_append(plist, + iph1->hash, ISAKMP_NPTYPE_HASH); + + /* append vendor id, if needed */ + if (vid) + plist = isakmp_plist_append(plist, + vid, ISAKMP_NPTYPE_VID); + break; + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: +#endif + /* XXX if there is CR or not ? */ + + if (oakley_getmycert(iph1) < 0) + goto end; + + if (oakley_getsign(iph1) < 0) + goto end; + + if (iph1->cert && iph1->rmconf->send_cert) + need_cert = 1; + + /* create isakmp KE payload */ + plist = isakmp_plist_append(plist, iph1->dhpub, + ISAKMP_NPTYPE_KE); + + /* add CERT payload if there */ + if (need_cert) + plist = isakmp_plist_append(plist, iph1->cert, + ISAKMP_NPTYPE_CERT); + + /* add SIG payload */ + plist = isakmp_plist_append(plist, iph1->sig, + ISAKMP_NPTYPE_SIG); + break; +#ifdef HAVE_GSSAPI + case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: + /* ... */ + break; +#endif + case OAKLEY_ATTR_AUTH_METHOD_RSAENC: + case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif + break; + } + +#ifdef ENABLE_NATT + /* generate NAT-D payloads */ + if (NATT_AVAILABLE(iph1)) { + vchar_t *natd[2] = { NULL, NULL }; + + plog(LLV_INFO, LOCATION, + NULL, "Adding remote and local NAT-D payloads.\n"); + if ((natd[0] = natt_hash_addr(iph1, iph1->remote)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "NAT-D hashing failed for %s\n", + saddr2str(iph1->remote)); + goto end; + } + + if ((natd[1] = natt_hash_addr(iph1, iph1->local)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "NAT-D hashing failed for %s\n", + saddr2str(iph1->local)); + goto end; + } + + plist = isakmp_plist_append(plist, + natd[0], iph1->natt_options->payload_nat_d); + plist = isakmp_plist_append(plist, + natd[1], iph1->natt_options->payload_nat_d); + } +#endif + + iph1->sendbuf = isakmp_plist_set_all(&plist, iph1); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); +#endif + + /* send HDR;KE;NONCE to responder */ + if (isakmp_send(iph1, iph1->sendbuf) < 0) + goto end; + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + /* generate SKEYIDs & IV & final cipher key */ + if (oakley_skeyid_dae(iph1) < 0) + goto end; + if (oakley_compute_enckey(iph1) < 0) + goto end; + if (oakley_newiv(iph1) < 0) + goto end; + + /* set encryption flag */ + iph1->flags |= ISAKMP_FLAG_E; + + iph1->status = PHASE1ST_ESTABLISHED; + + error = 0; + +end: + if (vid) + vfree(vid); + return error; +} diff --git a/ipsec-tools/src/racoon/isakmp_base.h b/ipsec-tools/src/racoon/isakmp_base.h new file mode 100644 index 00000000..560880e9 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_base.h @@ -0,0 +1,48 @@ +/* $NetBSD: isakmp_base.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: isakmp_base.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ISAKMP_BASE_H +#define _ISAKMP_BASE_H + +extern int base_i1send __P((struct ph1handle *, vchar_t *)); +extern int base_i2recv __P((struct ph1handle *, vchar_t *)); +extern int base_i2send __P((struct ph1handle *, vchar_t *)); +extern int base_i3recv __P((struct ph1handle *, vchar_t *)); +extern int base_i3send __P((struct ph1handle *, vchar_t *)); + +extern int base_r1recv __P((struct ph1handle *, vchar_t *)); +extern int base_r1send __P((struct ph1handle *, vchar_t *)); +extern int base_r2recv __P((struct ph1handle *, vchar_t *)); +extern int base_r2send __P((struct ph1handle *, vchar_t *)); + +#endif /* _ISAKMP_BASE_H */ diff --git a/ipsec-tools/src/racoon/isakmp_cfg.c b/ipsec-tools/src/racoon/isakmp_cfg.c new file mode 100644 index 00000000..67464590 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_cfg.c @@ -0,0 +1,2193 @@ +/* $NetBSD: isakmp_cfg.c,v 1.24.4.1 2013/04/12 10:04:21 tteras Exp $ */ + +/* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */ + +/* + * Copyright (C) 2004-2006 Emmanuel Dreyfus + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#if defined(__APPLE__) && defined(__MACH__) +#include +#endif + +#ifdef __FreeBSD__ +# include +#endif +#ifdef __NetBSD__ +# include +#endif + +#include +#include + +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#if HAVE_STDINT_H +#include +#endif +#include +#include + +#ifdef HAVE_LIBRADIUS +#include +#include +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "schedule.h" +#include "debug.h" + +#include "isakmp_var.h" +#include "isakmp.h" +#include "handler.h" +#include "evt.h" +#include "throttle.h" +#include "remoteconf.h" +#include "crypto_openssl.h" +#include "isakmp_inf.h" +#include "isakmp_xauth.h" +#include "isakmp_unity.h" +#include "isakmp_cfg.h" +#include "strnames.h" +#include "admin.h" +#include "privsep.h" + +struct isakmp_cfg_config isakmp_cfg_config; + +static vchar_t *buffer_cat(vchar_t *s, vchar_t *append); +static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *); +#if 0 +static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *); +#endif +static vchar_t *isakmp_cfg_addr4(struct ph1handle *, + struct isakmp_data *, in_addr_t *); +static vchar_t *isakmp_cfg_addrnet4(struct ph1handle *, + struct isakmp_data *, in_addr_t *, in_addr_t *); +static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *); +static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *, + struct isakmp_data *, in_addr_t *, int); +static void isakmp_cfg_appendaddr4(struct isakmp_data *, + struct in_addr *, int *, int); +static void isakmp_cfg_getstring(struct isakmp_data *,char *); +void isakmp_cfg_iplist_to_str(char *, int, void *, int); + +#define ISAKMP_CFG_LOGIN 1 +#define ISAKMP_CFG_LOGOUT 2 +static int isakmp_cfg_accounting(struct ph1handle *, int); +#ifdef HAVE_LIBRADIUS +static int isakmp_cfg_accounting_radius(struct ph1handle *, int); +#endif + +/* + * Handle an ISAKMP config mode packet + * We expect HDR, HASH, ATTR + */ +void +isakmp_cfg_r(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + struct isakmp *packet; + struct isakmp_gen *ph; + int tlen; + char *npp; + int np; + vchar_t *dmsg; + struct isakmp_ivm *ivm; + + /* Check that the packet is long enough to have a header */ + if (msg->l < sizeof(*packet)) { + plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n"); + return; + } + + packet = (struct isakmp *)msg->v; + + /* Is it encrypted? It should be encrypted */ + if ((packet->flags & ISAKMP_FLAG_E) == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "User credentials sent in cleartext!\n"); + return; + } + + /* + * Decrypt the packet. If this is the beginning of a new + * exchange, reinitialize the IV + */ + if (iph1->mode_cfg->ivm == NULL || + iph1->mode_cfg->last_msgid != packet->msgid ) + iph1->mode_cfg->ivm = + isakmp_cfg_newiv(iph1, packet->msgid); + ivm = iph1->mode_cfg->ivm; + + dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive); + if (dmsg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to decrypt message\n"); + return; + } + + plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet\n"); + plogdump(LLV_DEBUG, dmsg->v, dmsg->l); + + /* Now work with the decrypted packet */ + packet = (struct isakmp *)dmsg->v; + tlen = dmsg->l - sizeof(*packet); + ph = (struct isakmp_gen *)(packet + 1); + + np = packet->np; + while ((tlen > 0) && (np != ISAKMP_NPTYPE_NONE)) { + /* Check that the payload header fits in the packet */ + if (tlen < sizeof(*ph)) { + plog(LLV_WARNING, LOCATION, NULL, + "Short payload header\n"); + goto out; + } + + /* Check that the payload fits in the packet */ + if (tlen < ntohs(ph->len)) { + plog(LLV_WARNING, LOCATION, NULL, + "Short payload\n"); + goto out; + } + + plog(LLV_DEBUG, LOCATION, NULL, "Seen payload %d\n", np); + plogdump(LLV_DEBUG, ph, ntohs(ph->len)); + + switch(np) { + case ISAKMP_NPTYPE_HASH: { + vchar_t *check; + vchar_t *payload; + size_t plen; + struct isakmp_gen *nph; + + plen = ntohs(ph->len); + nph = (struct isakmp_gen *)((char *)ph + plen); + plen = ntohs(nph->len); + + if ((payload = vmalloc(plen)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory\n"); + goto out; + } + memcpy(payload->v, nph, plen); + + if ((check = oakley_compute_hash1(iph1, + packet->msgid, payload)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot compute hash\n"); + vfree(payload); + goto out; + } + + if (memcmp(ph + 1, check->v, check->l) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Hash verification failed\n"); + vfree(payload); + vfree(check); + goto out; + } + vfree(payload); + vfree(check); + break; + } + case ISAKMP_NPTYPE_ATTR: { + struct isakmp_pl_attr *attrpl; + + attrpl = (struct isakmp_pl_attr *)ph; + isakmp_cfg_attr_r(iph1, packet->msgid, attrpl); + + break; + } + default: + plog(LLV_WARNING, LOCATION, NULL, + "Unexpected next payload %d\n", np); + /* Skip to the next payload */ + break; + } + + /* Move to the next payload */ + np = ph->np; + tlen -= ntohs(ph->len); + npp = (char *)ph; + ph = (struct isakmp_gen *)(npp + ntohs(ph->len)); + } + +out: + vfree(dmsg); +} + +int +isakmp_cfg_attr_r(iph1, msgid, attrpl) + struct ph1handle *iph1; + u_int32_t msgid; + struct isakmp_pl_attr *attrpl; +{ + int type = attrpl->type; + + plog(LLV_DEBUG, LOCATION, NULL, + "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type)); + switch (type) { + case ISAKMP_CFG_ACK: + /* ignore, but this is the time to reinit the IV */ + oakley_delivm(iph1->mode_cfg->ivm); + iph1->mode_cfg->ivm = NULL; + return 0; + break; + + case ISAKMP_CFG_REPLY: + return isakmp_cfg_reply(iph1, attrpl); + break; + + case ISAKMP_CFG_REQUEST: + iph1->msgid = msgid; + return isakmp_cfg_request(iph1, attrpl); + break; + + case ISAKMP_CFG_SET: + iph1->msgid = msgid; + return isakmp_cfg_set(iph1, attrpl); + break; + + default: + plog(LLV_WARNING, LOCATION, NULL, + "Unepected configuration exchange type %d\n", type); + return -1; + break; + } + + return 0; +} + +int +isakmp_cfg_reply(iph1, attrpl) + struct ph1handle *iph1; + struct isakmp_pl_attr *attrpl; +{ + struct isakmp_data *attr; + int tlen; + size_t alen; + char *npp; + int type; + struct sockaddr_in *sin; + int error; + + tlen = ntohs(attrpl->h.len); + attr = (struct isakmp_data *)(attrpl + 1); + tlen -= sizeof(*attrpl); + + while (tlen > 0) { + type = ntohs(attr->type); + + /* Handle short attributes */ + if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { + type &= ~ISAKMP_GEN_MASK; + + plog(LLV_DEBUG, LOCATION, NULL, + "Short attribute %s = %d\n", + s_isakmp_cfg_type(type), ntohs(attr->lorv)); + + switch (type) { + case XAUTH_TYPE: + if ((error = xauth_attr_reply(iph1, + attr, ntohs(attrpl->id))) != 0) + return error; + break; + + default: + plog(LLV_WARNING, LOCATION, NULL, + "Ignored short attribute %s\n", + s_isakmp_cfg_type(type)); + break; + } + + tlen -= sizeof(*attr); + attr++; + continue; + } + + type = ntohs(attr->type); + alen = ntohs(attr->lorv); + + /* Check that the attribute fit in the packet */ + if (tlen < alen) { + plog(LLV_ERROR, LOCATION, NULL, + "Short attribute %s\n", + s_isakmp_cfg_type(type)); + return -1; + } + + plog(LLV_DEBUG, LOCATION, NULL, + "Attribute %s, len %zu\n", + s_isakmp_cfg_type(type), alen); + + switch(type) { + case XAUTH_TYPE: + case XAUTH_USER_NAME: + case XAUTH_USER_PASSWORD: + case XAUTH_PASSCODE: + case XAUTH_MESSAGE: + case XAUTH_CHALLENGE: + case XAUTH_DOMAIN: + case XAUTH_STATUS: + case XAUTH_NEXT_PIN: + case XAUTH_ANSWER: + if ((error = xauth_attr_reply(iph1, + attr, ntohs(attrpl->id))) != 0) + return error; + break; + case INTERNAL_IP4_ADDRESS: + isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4); + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4; + break; + case INTERNAL_IP4_NETMASK: + isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4); + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4; + break; + case INTERNAL_IP4_DNS: + isakmp_cfg_appendaddr4(attr, + &iph1->mode_cfg->dns4[iph1->mode_cfg->dns4_index], + &iph1->mode_cfg->dns4_index, MAXNS); + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4; + break; + case INTERNAL_IP4_NBNS: + isakmp_cfg_appendaddr4(attr, + &iph1->mode_cfg->wins4[iph1->mode_cfg->wins4_index], + &iph1->mode_cfg->wins4_index, MAXNS); + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4; + break; + case UNITY_DEF_DOMAIN: + isakmp_cfg_getstring(attr, + iph1->mode_cfg->default_domain); + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DEFAULT_DOMAIN; + break; + case UNITY_SPLIT_INCLUDE: + case UNITY_LOCAL_LAN: + case UNITY_SPLITDNS_NAME: + case UNITY_BANNER: + case UNITY_SAVE_PASSWD: + case UNITY_NATT_PORT: + case UNITY_PFS: + case UNITY_FW_TYPE: + case UNITY_BACKUP_SERVERS: + case UNITY_DDNS_HOSTNAME: + isakmp_unity_reply(iph1, attr); + break; + case INTERNAL_IP4_SUBNET: + case INTERNAL_ADDRESS_EXPIRY: + default: + plog(LLV_WARNING, LOCATION, NULL, + "Ignored attribute %s\n", + s_isakmp_cfg_type(type)); + break; + } + + npp = (char *)attr; + attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen); + tlen -= (sizeof(*attr) + alen); + } + + /* + * Call the SA up script hook now that we have the configuration + * It is done at the end of phase 1 if ISAKMP mode config is not + * requested. + */ + + if ((iph1->status == PHASE1ST_ESTABLISHED) && + iph1->rmconf->mode_cfg) { + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + /* Unimplemented */ + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + script_hook(iph1, SCRIPT_PHASE1_UP); + break; + default: + break; + } + } + + +#ifdef ENABLE_ADMINPORT + { + vchar_t *buf; + + alen = ntohs(attrpl->h.len) - sizeof(*attrpl); + if ((buf = vmalloc(alen)) == NULL) { + plog(LLV_WARNING, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + } else { + memcpy(buf->v, attrpl + 1, buf->l); + evt_phase1(iph1, EVT_PHASE1_MODE_CFG, buf); + vfree(buf); + } + } +#endif + + return 0; +} + +int +isakmp_cfg_request(iph1, attrpl) + struct ph1handle *iph1; + struct isakmp_pl_attr *attrpl; +{ + struct isakmp_data *attr; + int tlen; + size_t alen; + char *npp; + vchar_t *payload; + struct isakmp_pl_attr *reply; + vchar_t *reply_attr; + int type; + int error = -1; + + if ((payload = vmalloc(sizeof(*reply))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + return -1; + } + memset(payload->v, 0, sizeof(*reply)); + + tlen = ntohs(attrpl->h.len); + attr = (struct isakmp_data *)(attrpl + 1); + tlen -= sizeof(*attrpl); + + while (tlen > 0) { + reply_attr = NULL; + type = ntohs(attr->type); + + /* Handle short attributes */ + if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { + type &= ~ISAKMP_GEN_MASK; + + plog(LLV_DEBUG, LOCATION, NULL, + "Short attribute %s = %d\n", + s_isakmp_cfg_type(type), ntohs(attr->lorv)); + + switch (type) { + case XAUTH_TYPE: + reply_attr = isakmp_xauth_req(iph1, attr); + break; + default: + plog(LLV_WARNING, LOCATION, NULL, + "Ignored short attribute %s\n", + s_isakmp_cfg_type(type)); + break; + } + + tlen -= sizeof(*attr); + attr++; + + if (reply_attr != NULL) { + payload = buffer_cat(payload, reply_attr); + vfree(reply_attr); + } + + continue; + } + + type = ntohs(attr->type); + alen = ntohs(attr->lorv); + + /* Check that the attribute fit in the packet */ + if (tlen < alen) { + plog(LLV_ERROR, LOCATION, NULL, + "Short attribute %s\n", + s_isakmp_cfg_type(type)); + goto end; + } + + plog(LLV_DEBUG, LOCATION, NULL, + "Attribute %s, len %zu\n", + s_isakmp_cfg_type(type), alen); + + switch(type) { + case INTERNAL_IP4_ADDRESS: + case INTERNAL_IP4_NETMASK: + case INTERNAL_IP4_DNS: + case INTERNAL_IP4_NBNS: + case INTERNAL_IP4_SUBNET: + reply_attr = isakmp_cfg_net(iph1, attr); + break; + + case XAUTH_TYPE: + case XAUTH_USER_NAME: + case XAUTH_USER_PASSWORD: + case XAUTH_PASSCODE: + case XAUTH_MESSAGE: + case XAUTH_CHALLENGE: + case XAUTH_DOMAIN: + case XAUTH_STATUS: + case XAUTH_NEXT_PIN: + case XAUTH_ANSWER: + reply_attr = isakmp_xauth_req(iph1, attr); + break; + + case APPLICATION_VERSION: + reply_attr = isakmp_cfg_string(iph1, + attr, ISAKMP_CFG_RACOON_VERSION); + break; + + case UNITY_BANNER: + case UNITY_PFS: + case UNITY_SAVE_PASSWD: + case UNITY_DEF_DOMAIN: + case UNITY_DDNS_HOSTNAME: + case UNITY_FW_TYPE: + case UNITY_SPLITDNS_NAME: + case UNITY_SPLIT_INCLUDE: + case UNITY_LOCAL_LAN: + case UNITY_NATT_PORT: + case UNITY_BACKUP_SERVERS: + reply_attr = isakmp_unity_req(iph1, attr); + break; + + case INTERNAL_ADDRESS_EXPIRY: + default: + plog(LLV_WARNING, LOCATION, NULL, + "Ignored attribute %s\n", + s_isakmp_cfg_type(type)); + break; + } + + npp = (char *)attr; + attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen); + tlen -= (sizeof(*attr) + alen); + + if (reply_attr != NULL) { + payload = buffer_cat(payload, reply_attr); + vfree(reply_attr); + } + + } + + reply = (struct isakmp_pl_attr *)payload->v; + reply->h.len = htons(payload->l); + reply->type = ISAKMP_CFG_REPLY; + reply->id = attrpl->id; + + plog(LLV_DEBUG, LOCATION, NULL, + "Sending MODE_CFG REPLY\n"); + + error = isakmp_cfg_send(iph1, payload, + ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0); + + if (iph1->status == PHASE1ST_ESTABLISHED) { + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + /* Unimplemented */ + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: + script_hook(iph1, SCRIPT_PHASE1_UP); + break; + default: + break; + } + } + +end: + vfree(payload); + + return error; +} + +int +isakmp_cfg_set(iph1, attrpl) + struct ph1handle *iph1; + struct isakmp_pl_attr *attrpl; +{ + struct isakmp_data *attr; + int tlen; + size_t alen; + char *npp; + vchar_t *payload; + struct isakmp_pl_attr *reply; + vchar_t *reply_attr; + int type; + int error = -1; + + if ((payload = vmalloc(sizeof(*reply))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + return -1; + } + memset(payload->v, 0, sizeof(*reply)); + + tlen = ntohs(attrpl->h.len); + attr = (struct isakmp_data *)(attrpl + 1); + tlen -= sizeof(*attrpl); + + /* + * We should send ack for the attributes we accepted + */ + while (tlen > 0) { + reply_attr = NULL; + type = ntohs(attr->type); + + plog(LLV_DEBUG, LOCATION, NULL, + "Attribute %s\n", + s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK)); + + switch (type & ~ISAKMP_GEN_MASK) { + case XAUTH_STATUS: + reply_attr = isakmp_xauth_set(iph1, attr); + break; + default: + plog(LLV_DEBUG, LOCATION, NULL, + "Unexpected SET attribute %s\n", + s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK)); + break; + } + + if (reply_attr != NULL) { + payload = buffer_cat(payload, reply_attr); + vfree(reply_attr); + } + + /* + * Move to next attribute. If we run out of the packet, + * tlen becomes negative and we exit. + */ + if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { + tlen -= sizeof(*attr); + attr++; + } else { + alen = ntohs(attr->lorv); + tlen -= (sizeof(*attr) + alen); + npp = (char *)attr; + attr = (struct isakmp_data *) + (npp + sizeof(*attr) + alen); + } + } + + reply = (struct isakmp_pl_attr *)payload->v; + reply->h.len = htons(payload->l); + reply->type = ISAKMP_CFG_ACK; + reply->id = attrpl->id; + + plog(LLV_DEBUG, LOCATION, NULL, + "Sending MODE_CFG ACK\n"); + + error = isakmp_cfg_send(iph1, payload, + ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0); + + if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) { + if (iph1->status == PHASE1ST_ESTABLISHED || + iph1->status == PHASE1ST_DYING) + isakmp_info_send_d1(iph1); + remph1(iph1); + delph1(iph1); + iph1 = NULL; + } +end: + vfree(payload); + + /* + * If required, request ISAKMP mode config information + */ + if ((iph1 != NULL) && (iph1->rmconf->mode_cfg) && (error == 0)) + error = isakmp_cfg_getconfig(iph1); + + return error; +} + + +static vchar_t * +buffer_cat(s, append) + vchar_t *s; + vchar_t *append; +{ + vchar_t *new; + + new = vmalloc(s->l + append->l); + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory\n"); + return s; + } + + memcpy(new->v, s->v, s->l); + memcpy(new->v + s->l, append->v, append->l); + + vfree(s); + return new; +} + +static vchar_t * +isakmp_cfg_net(iph1, attr) + struct ph1handle *iph1; + struct isakmp_data *attr; +{ + int type; + int confsource; + in_addr_t addr4; + + type = ntohs(attr->type); + + /* + * Don't give an address to a peer that did not succeed Xauth + */ + if (xauth_check(iph1) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Attempt to start phase config whereas Xauth failed\n"); + return NULL; + } + + confsource = isakmp_cfg_config.confsource; + /* + * If we have to fall back to a local + * configuration source, we will jump + * back to this point. + */ +retry_source: + + switch(type) { + case INTERNAL_IP4_ADDRESS: + switch(confsource) { +#ifdef HAVE_LIBLDAP + case ISAKMP_CFG_CONF_LDAP: + if (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) + break; + plog(LLV_INFO, LOCATION, NULL, + "No IP from LDAP, using local pool\n"); + /* FALLTHROUGH */ + confsource = ISAKMP_CFG_CONF_LOCAL; + goto retry_source; +#endif +#ifdef HAVE_LIBRADIUS + case ISAKMP_CFG_CONF_RADIUS: + if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) + && (iph1->mode_cfg->addr4.s_addr != htonl(-2))) + /* + * -2 is 255.255.255.254, RADIUS uses that + * to instruct the NAS to use a local pool + */ + break; + plog(LLV_INFO, LOCATION, NULL, + "No IP from RADIUS, using local pool\n"); + /* FALLTHROUGH */ + confsource = ISAKMP_CFG_CONF_LOCAL; + goto retry_source; +#endif + case ISAKMP_CFG_CONF_LOCAL: + if (isakmp_cfg_getport(iph1) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "Port pool depleted\n"); + break; + } + + iph1->mode_cfg->addr4.s_addr = + htonl(ntohl(isakmp_cfg_config.network4) + + iph1->mode_cfg->port); + iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL; + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "Unexpected confsource\n"); + } + + if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGIN) != 0) + plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n"); + + return isakmp_cfg_addr4(iph1, + attr, &iph1->mode_cfg->addr4.s_addr); + break; + + case INTERNAL_IP4_NETMASK: + switch(confsource) { +#ifdef HAVE_LIBLDAP + case ISAKMP_CFG_CONF_LDAP: + if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN) + break; + plog(LLV_INFO, LOCATION, NULL, + "No mask from LDAP, using local pool\n"); + /* FALLTHROUGH */ + confsource = ISAKMP_CFG_CONF_LOCAL; + goto retry_source; +#endif +#ifdef HAVE_LIBRADIUS + case ISAKMP_CFG_CONF_RADIUS: + if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN) + break; + plog(LLV_INFO, LOCATION, NULL, + "No mask from RADIUS, using local pool\n"); + /* FALLTHROUGH */ + confsource = ISAKMP_CFG_CONF_LOCAL; + goto retry_source; +#endif + case ISAKMP_CFG_CONF_LOCAL: + iph1->mode_cfg->mask4.s_addr + = isakmp_cfg_config.netmask4; + iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL; + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "Unexpected confsource\n"); + } + return isakmp_cfg_addr4(iph1, attr, + &iph1->mode_cfg->mask4.s_addr); + break; + + case INTERNAL_IP4_DNS: + return isakmp_cfg_addr4_list(iph1, + attr, &isakmp_cfg_config.dns4[0], + isakmp_cfg_config.dns4_index); + break; + + case INTERNAL_IP4_NBNS: + return isakmp_cfg_addr4_list(iph1, + attr, &isakmp_cfg_config.nbns4[0], + isakmp_cfg_config.nbns4_index); + break; + + case INTERNAL_IP4_SUBNET: + if(isakmp_cfg_config.splitnet_count > 0){ + return isakmp_cfg_addrnet4(iph1, attr, + &isakmp_cfg_config.splitnet_list->network.addr4.s_addr, + &isakmp_cfg_config.splitnet_list->network.mask4.s_addr); + }else{ + plog(LLV_INFO, LOCATION, NULL, + "%s requested but no splitnet in configuration\n", + s_isakmp_cfg_type(type)); + } + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type); + break; + } + return NULL; +} + +#if 0 +static vchar_t * +isakmp_cfg_void(iph1, attr) + struct ph1handle *iph1; + struct isakmp_data *attr; +{ + vchar_t *buffer; + struct isakmp_data *new; + + if ((buffer = vmalloc(sizeof(*attr))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + return NULL; + } + + new = (struct isakmp_data *)buffer->v; + + new->type = attr->type; + new->lorv = htons(0); + + return buffer; +} +#endif + +vchar_t * +isakmp_cfg_copy(iph1, attr) + struct ph1handle *iph1; + struct isakmp_data *attr; +{ + vchar_t *buffer; + size_t len = 0; + + if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV) + len = ntohs(attr->lorv); + + if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + return NULL; + } + + memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv)); + + return buffer; +} + +vchar_t * +isakmp_cfg_short(iph1, attr, value) + struct ph1handle *iph1; + struct isakmp_data *attr; + int value; +{ + vchar_t *buffer; + struct isakmp_data *new; + int type; + + if ((buffer = vmalloc(sizeof(*attr))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + return NULL; + } + + new = (struct isakmp_data *)buffer->v; + type = ntohs(attr->type) & ~ISAKMP_GEN_MASK; + + new->type = htons(type | ISAKMP_GEN_TV); + new->lorv = htons(value); + + return buffer; +} + +vchar_t * +isakmp_cfg_varlen(iph1, attr, string, len) + struct ph1handle *iph1; + struct isakmp_data *attr; + char *string; + size_t len; +{ + vchar_t *buffer; + struct isakmp_data *new; + char *data; + + if (!len) + return NULL; + + if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + return NULL; + } + + new = (struct isakmp_data *)buffer->v; + + new->type = attr->type; + new->lorv = htons(len); + data = (char *)(new + 1); + + memcpy(data, string, len); + + return buffer; +} +vchar_t * +isakmp_cfg_string(iph1, attr, string) + struct ph1handle *iph1; + struct isakmp_data *attr; + char *string; +{ + size_t len = strlen(string); + return isakmp_cfg_varlen(iph1, attr, string, len); +} + +static vchar_t * +isakmp_cfg_addr4(iph1, attr, addr) + struct ph1handle *iph1; + struct isakmp_data *attr; + in_addr_t *addr; +{ + vchar_t *buffer; + struct isakmp_data *new; + size_t len; + + len = sizeof(*addr); + if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + return NULL; + } + + new = (struct isakmp_data *)buffer->v; + + new->type = attr->type; + new->lorv = htons(len); + memcpy(new + 1, addr, len); + + return buffer; +} + +static vchar_t * +isakmp_cfg_addrnet4(iph1, attr, addr, mask) + struct ph1handle *iph1; + struct isakmp_data *attr; + in_addr_t *addr; + in_addr_t *mask; +{ + vchar_t *buffer; + struct isakmp_data *new; + size_t len; + in_addr_t netbuff[2]; + + len = sizeof(netbuff); + if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + return NULL; + } + + new = (struct isakmp_data *)buffer->v; + + new->type = attr->type; + new->lorv = htons(len); + netbuff[0]=*addr; + netbuff[1]=*mask; + memcpy(new + 1, netbuff, len); + + return buffer; +} + + +static vchar_t * +isakmp_cfg_addr4_list(iph1, attr, addr, nbr) + struct ph1handle *iph1; + struct isakmp_data *attr; + in_addr_t *addr; + int nbr; +{ + int error = -1; + vchar_t *buffer = NULL; + vchar_t *bufone = NULL; + struct isakmp_data *new; + size_t len; + int i; + + len = sizeof(*addr); + if ((buffer = vmalloc(0)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + goto out; + } + for(i = 0; i < nbr; i++) { + if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory\n"); + goto out; + } + new = (struct isakmp_data *)bufone->v; + new->type = attr->type; + new->lorv = htons(len); + memcpy(new + 1, &addr[i], len); + new += (len + sizeof(*attr)); + buffer = buffer_cat(buffer, bufone); + vfree(bufone); + } + + error = 0; + +out: + if ((error != 0) && (buffer != NULL)) { + vfree(buffer); + buffer = NULL; + } + + return buffer; +} + +struct isakmp_ivm * +isakmp_cfg_newiv(iph1, msgid) + struct ph1handle *iph1; + u_int32_t msgid; +{ + struct isakmp_cfg_state *ics = iph1->mode_cfg; + + if (ics == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "isakmp_cfg_newiv called without mode config state\n"); + return NULL; + } + + if (ics->ivm != NULL) + oakley_delivm(ics->ivm); + + ics->ivm = oakley_newiv2(iph1, msgid); + ics->last_msgid = msgid; + + return ics->ivm; +} + +/* Derived from isakmp_info_send_common */ +int +isakmp_cfg_send(iph1, payload, np, flags, new_exchange) + struct ph1handle *iph1; + vchar_t *payload; + u_int32_t np; + int flags; + int new_exchange; +{ + struct ph2handle *iph2 = NULL; + vchar_t *hash = NULL; + struct isakmp *isakmp; + struct isakmp_gen *gen; + char *p; + int tlen; + int error = -1; + struct isakmp_cfg_state *ics = iph1->mode_cfg; + + /* Check if phase 1 is established */ + if ((iph1->status < PHASE1ST_ESTABLISHED) || + (iph1->local == NULL) || + (iph1->remote == NULL)) { + plog(LLV_ERROR, LOCATION, NULL, + "ISAKMP mode config exchange with immature phase 1\n"); + goto end; + } + + /* add new entry to isakmp status table */ + iph2 = newph2(); + if (iph2 == NULL) + goto end; + + iph2->dst = dupsaddr(iph1->remote); + if (iph2->dst == NULL) { + delph2(iph2); + goto end; + } + iph2->src = dupsaddr(iph1->local); + if (iph2->src == NULL) { + delph2(iph2); + goto end; + } + + iph2->side = INITIATOR; + iph2->status = PHASE2ST_START; + + if (new_exchange) + iph2->msgid = isakmp_newmsgid2(iph1); + else + iph2->msgid = iph1->msgid; + + /* get IV and HASH(1) if skeyid_a was generated. */ + if (iph1->skeyid_a != NULL) { + if (new_exchange) { + if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) { + delph2(iph2); + goto end; + } + } + + /* generate HASH(1) */ + hash = oakley_compute_hash1(iph1, iph2->msgid, payload); + if (hash == NULL) { + delph2(iph2); + goto end; + } + + /* initialized total buffer length */ + tlen = hash->l; + tlen += sizeof(*gen); + } else { + /* IKE-SA is not established */ + hash = NULL; + + /* initialized total buffer length */ + tlen = 0; + } + if ((flags & ISAKMP_FLAG_A) == 0) + iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E); + else + iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A); + + insph2(iph2); + bindph12(iph1, iph2); + + tlen += sizeof(*isakmp) + payload->l; + + /* create buffer for isakmp payload */ + iph2->sendbuf = vmalloc(tlen); + if (iph2->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + goto err; + } + + /* create isakmp header */ + isakmp = (struct isakmp *)iph2->sendbuf->v; + memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t)); + memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t)); + isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH; + isakmp->v = iph1->version; + isakmp->etype = ISAKMP_ETYPE_CFG; + isakmp->flags = iph2->flags; + memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid)); + isakmp->len = htonl(tlen); + p = (char *)(isakmp + 1); + + /* create HASH payload */ + if (hash != NULL) { + gen = (struct isakmp_gen *)p; + gen->np = np & 0xff; + gen->len = htons(sizeof(*gen) + hash->l); + p += sizeof(*gen); + memcpy(p, hash->v, hash->l); + p += hash->l; + } + + /* add payload */ + memcpy(p, payload->v, payload->l); + p += payload->l; + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1); +#endif + + plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n"); + plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l); + + /* encoding */ + if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) { + vchar_t *tmp; + + tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, + ics->ivm->ive, ics->ivm->iv); + VPTRINIT(iph2->sendbuf); + if (tmp == NULL) + goto err; + iph2->sendbuf = tmp; + } + + /* HDR*, HASH(1), ATTR */ + if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { + VPTRINIT(iph2->sendbuf); + goto err; + } + + plog(LLV_DEBUG, LOCATION, NULL, + "sendto mode config %s.\n", s_isakmp_nptype(np)); + + /* + * XXX We might need to resend the message... + */ + + error = 0; + VPTRINIT(iph2->sendbuf); + +err: + if (iph2->sendbuf != NULL) + vfree(iph2->sendbuf); + + remph2(iph2); + delph2(iph2); +end: + if (hash) + vfree(hash); + return error; +} + + +void +isakmp_cfg_rmstate(iph1) + struct ph1handle *iph1; +{ + struct isakmp_cfg_state *state = iph1->mode_cfg; + + if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0) + plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n"); + + if (state->flags & ISAKMP_CFG_PORT_ALLOCATED) + isakmp_cfg_putport(iph1, state->port); + + /* Delete the IV if it's still there */ + if(iph1->mode_cfg->ivm) { + oakley_delivm(iph1->mode_cfg->ivm); + iph1->mode_cfg->ivm = NULL; + } + + /* Free any allocated splitnet lists */ + if(iph1->mode_cfg->split_include != NULL) + splitnet_list_free(iph1->mode_cfg->split_include, + &iph1->mode_cfg->include_count); + if(iph1->mode_cfg->split_local != NULL) + splitnet_list_free(iph1->mode_cfg->split_local, + &iph1->mode_cfg->local_count); + + xauth_rmstate(&state->xauth); + + racoon_free(state); + iph1->mode_cfg = NULL; + + return; +} + +struct isakmp_cfg_state * +isakmp_cfg_mkstate(void) +{ + struct isakmp_cfg_state *state; + + if ((state = racoon_malloc(sizeof(*state))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory for mode config state\n"); + return NULL; + } + memset(state, 0, sizeof(*state)); + + return state; +} + +int +isakmp_cfg_getport(iph1) + struct ph1handle *iph1; +{ + unsigned int i; + size_t size = isakmp_cfg_config.pool_size; + + if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED) + return iph1->mode_cfg->port; + + if (isakmp_cfg_config.port_pool == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "isakmp_cfg_config.port_pool == NULL\n"); + return -1; + } + + for (i = 0; i < size; i++) { + if (isakmp_cfg_config.port_pool[i].used == 0) + break; + } + + if (i == size) { + plog(LLV_ERROR, LOCATION, NULL, + "No more addresses available\n"); + return -1; + } + + isakmp_cfg_config.port_pool[i].used = 1; + + plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i); + + iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED; + iph1->mode_cfg->port = i; + + return i; +} + +int +isakmp_cfg_putport(iph1, index) + struct ph1handle *iph1; + unsigned int index; +{ + if (isakmp_cfg_config.port_pool == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "isakmp_cfg_config.port_pool == NULL\n"); + return -1; + } + + if (isakmp_cfg_config.port_pool[index].used == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Attempt to release an unallocated address (port %d)\n", + index); + return -1; + } + +#ifdef HAVE_LIBPAM + /* Cleanup PAM status associated with the port */ + if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM) + privsep_cleanup_pam(index); +#endif + isakmp_cfg_config.port_pool[index].used = 0; + iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED; + + plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index); + + return 0; +} + +#ifdef HAVE_LIBPAM +void +cleanup_pam(port) + int port; +{ + if (isakmp_cfg_config.port_pool[port].pam != NULL) { + pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS); + isakmp_cfg_config.port_pool[port].pam = NULL; + } + + return; +} +#endif + +/* Accounting, only for RADIUS or PAM */ +static int +isakmp_cfg_accounting(iph1, inout) + struct ph1handle *iph1; + int inout; +{ +#ifdef HAVE_LIBPAM + if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM) + return privsep_accounting_pam(iph1->mode_cfg->port, + inout); +#endif +#ifdef HAVE_LIBRADIUS + if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) + return isakmp_cfg_accounting_radius(iph1, inout); +#endif + if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM) + return privsep_accounting_system(iph1->mode_cfg->port, + iph1->remote, iph1->mode_cfg->login, inout); + return 0; +} + +#ifdef HAVE_LIBPAM +int +isakmp_cfg_accounting_pam(port, inout) + int port; + int inout; +{ + int error = 0; + pam_handle_t *pam; + + if (isakmp_cfg_config.port_pool == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "isakmp_cfg_config.port_pool == NULL\n"); + return -1; + } + + pam = isakmp_cfg_config.port_pool[port].pam; + if (pam == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n"); + return -1; + } + + switch (inout) { + case ISAKMP_CFG_LOGIN: + error = pam_open_session(pam, 0); + break; + case ISAKMP_CFG_LOGOUT: + error = pam_close_session(pam, 0); + pam_end(pam, error); + isakmp_cfg_config.port_pool[port].pam = NULL; + break; + default: + plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); + break; + } + + if (error != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "pam_open_session/pam_close_session failed: %s\n", + pam_strerror(pam, error)); + return -1; + } + + return 0; +} +#endif /* HAVE_LIBPAM */ + +#ifdef HAVE_LIBRADIUS +static int +isakmp_cfg_accounting_radius(iph1, inout) + struct ph1handle *iph1; + int inout; +{ + if (rad_create_request(radius_acct_state, + RAD_ACCOUNTING_REQUEST) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_create_request failed: %s\n", + rad_strerror(radius_acct_state)); + return -1; + } + + if (rad_put_string(radius_acct_state, RAD_USER_NAME, + iph1->mode_cfg->login) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_put_string failed: %s\n", + rad_strerror(radius_acct_state)); + return -1; + } + + switch (inout) { + case ISAKMP_CFG_LOGIN: + inout = RAD_START; + break; + case ISAKMP_CFG_LOGOUT: + inout = RAD_STOP; + break; + default: + plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); + break; + } + + if (rad_put_addr(radius_acct_state, + RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_put_addr failed: %s\n", + rad_strerror(radius_acct_state)); + return -1; + } + + if (rad_put_addr(radius_acct_state, + RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_put_addr failed: %s\n", + rad_strerror(radius_acct_state)); + return -1; + } + + if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_put_int failed: %s\n", + rad_strerror(radius_acct_state)); + return -1; + } + + if (isakmp_cfg_radius_common(radius_acct_state, + iph1->mode_cfg->port) != 0) + return -1; + + if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_send_request failed: %s\n", + rad_strerror(radius_acct_state)); + return -1; + } + + return 0; +} +#endif /* HAVE_LIBRADIUS */ + +/* + * Attributes common to all RADIUS requests + */ +#ifdef HAVE_LIBRADIUS +int +isakmp_cfg_radius_common(radius_state, port) + struct rad_handle *radius_state; + int port; +{ + struct utsname name; + static struct hostent *host = NULL; + struct in_addr nas_addr; + + /* + * Find our own IP by resolving our nodename + */ + if (host == NULL) { + if (uname(&name) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "uname failed: %s\n", strerror(errno)); + return -1; + } + + if ((host = gethostbyname(name.nodename)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "gethostbyname failed: %s\n", strerror(errno)); + return -1; + } + } + + memcpy(&nas_addr, host->h_addr, sizeof(nas_addr)); + if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_put_addr failed: %s\n", + rad_strerror(radius_state)); + return -1; + } + + if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_put_int failed: %s\n", + rad_strerror(radius_state)); + return -1; + } + + if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_put_int failed: %s\n", + rad_strerror(radius_state)); + return -1; + } + + if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_put_int failed: %s\n", + rad_strerror(radius_state)); + return -1; + } + + return 0; +} +#endif + +/* + Logs the user into the utmp system files. +*/ + +int +isakmp_cfg_accounting_system(port, raddr, usr, inout) + int port; + struct sockaddr *raddr; + char *usr; + int inout; +{ + int error = 0; + struct utmpx ut; + char addr[NI_MAXHOST]; + + if (usr == NULL || usr[0]=='\0') { + plog(LLV_ERROR, LOCATION, NULL, + "system accounting : no login found\n"); + return -1; + } + + memset(&ut, 0, sizeof ut); + gettimeofday((struct timeval *)&ut.ut_tv, NULL); + snprintf(ut.ut_id, sizeof ut.ut_id, TERMSPEC, port); + + switch (inout) { + case ISAKMP_CFG_LOGIN: + ut.ut_type = USER_PROCESS; + strncpy(ut.ut_user, usr, sizeof ut.ut_user); + + GETNAMEINFO_NULL(raddr, addr); + strncpy(ut.ut_host, addr, sizeof ut.ut_host); + + plog(LLV_INFO, LOCATION, NULL, + "Accounting : '%s' logging on '%s' from %s.\n", + ut.ut_user, ut.ut_id, addr); + + pututxline(&ut); + + break; + case ISAKMP_CFG_LOGOUT: + ut.ut_type = DEAD_PROCESS; + + plog(LLV_INFO, LOCATION, NULL, + "Accounting : '%s' unlogging from '%s'.\n", + usr, ut.ut_id); + + pututxline(&ut); + + break; + default: + plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); + break; + } + + return 0; +} + +int +isakmp_cfg_getconfig(iph1) + struct ph1handle *iph1; +{ + vchar_t *buffer; + struct isakmp_pl_attr *attrpl; + struct isakmp_data *attr; + size_t len; + int error; + int attrcount; + int i; + int attrlist[] = { + INTERNAL_IP4_ADDRESS, + INTERNAL_IP4_NETMASK, + INTERNAL_IP4_DNS, + INTERNAL_IP4_NBNS, + UNITY_BANNER, + UNITY_DEF_DOMAIN, + UNITY_SPLITDNS_NAME, + UNITY_SPLIT_INCLUDE, + UNITY_LOCAL_LAN, + APPLICATION_VERSION, + }; + + attrcount = sizeof(attrlist) / sizeof(*attrlist); + len = sizeof(*attrpl) + sizeof(*attr) * attrcount; + + if ((buffer = vmalloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + return -1; + } + + attrpl = (struct isakmp_pl_attr *)buffer->v; + attrpl->h.len = htons(len); + attrpl->type = ISAKMP_CFG_REQUEST; + attrpl->id = htons((u_int16_t)(eay_random() & 0xffff)); + + attr = (struct isakmp_data *)(attrpl + 1); + + for (i = 0; i < attrcount; i++) { + attr->type = htons(attrlist[i]); + attr->lorv = htons(0); + attr++; + } + + plog(LLV_DEBUG, LOCATION, NULL, + "Sending MODE_CFG REQUEST\n"); + + error = isakmp_cfg_send(iph1, buffer, + ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1); + + vfree(buffer); + + return error; +} + +static void +isakmp_cfg_getaddr4(attr, ip) + struct isakmp_data *attr; + struct in_addr *ip; +{ + size_t alen = ntohs(attr->lorv); + in_addr_t *addr; + + if (alen != sizeof(*ip)) { + plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n"); + return; + } + + addr = (in_addr_t *)(attr + 1); + ip->s_addr = *addr; + + return; +} + +static void +isakmp_cfg_appendaddr4(attr, ip, num, max) + struct isakmp_data *attr; + struct in_addr *ip; + int *num; + int max; +{ + size_t alen = ntohs(attr->lorv); + in_addr_t *addr; + + if (alen != sizeof(*ip)) { + plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n"); + return; + } + if (*num == max) { + plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n"); + return; + } + + addr = (in_addr_t *)(attr + 1); + ip->s_addr = *addr; + (*num)++; + + return; +} + +static void +isakmp_cfg_getstring(attr, str) + struct isakmp_data *attr; + char *str; +{ + size_t alen = ntohs(attr->lorv); + char *src; + src = (char *)(attr + 1); + + memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen)); + + return; +} + +#define IP_MAX 40 + +void +isakmp_cfg_iplist_to_str(dest, count, addr, withmask) + char *dest; + int count; + void *addr; + int withmask; +{ + int i; + int p; + int l; + struct unity_network tmp; + for(i = 0, p = 0; i < count; i++) { + if(withmask == 1) + l = sizeof(struct unity_network); + else + l = sizeof(struct in_addr); + memcpy(&tmp, addr, l); + addr += l; + if((uint32_t)tmp.addr4.s_addr == 0) + break; + + inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX); + p += strlen(dest + p); + if(withmask == 1) { + dest[p] = '/'; + p++; + inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX); + p += strlen(dest + p); + } + dest[p] = ' '; + p++; + } + if(p > 0) + dest[p-1] = '\0'; + else + dest[0] = '\0'; +} + +int +isakmp_cfg_setenv(iph1, envp, envc) + struct ph1handle *iph1; + char ***envp; + int *envc; +{ + char addrstr[IP_MAX]; + char addrlist[IP_MAX * MAXNS + MAXNS]; + char *splitlist = addrlist; + char *splitlist_cidr; + char defdom[MAXPATHLEN + 1]; + int cidr, tmp; + char cidrstr[4]; + int i, p; + int test; + + plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n"); + + /* + * Internal IPv4 address, either if + * we are a client or a server. + */ + if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) || +#ifdef HAVE_LIBLDAP + (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) || +#endif +#ifdef HAVE_LIBRADIUS + (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) || +#endif + (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) { + inet_ntop(AF_INET, &iph1->mode_cfg->addr4, + addrstr, IP_MAX); + } else + addrstr[0] = '\0'; + + if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n"); + return -1; + } + + if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) { + if (script_env_append(envp, envc, "XAUTH_USER", + iph1->mode_cfg->xauth.authdata.generic.usr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set XAUTH_USER\n"); + return -1; + } + } + + /* Internal IPv4 mask */ + if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) + inet_ntop(AF_INET, &iph1->mode_cfg->mask4, + addrstr, IP_MAX); + else + addrstr[0] = '\0'; + + /* + * During several releases, documentation adverised INTERNAL_NETMASK4 + * while code was using INTERNAL_MASK4. We now do both. + */ + + if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n"); + return -1; + } + + if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set INTERNAL_NETMASK4\n"); + return -1; + } + + tmp = ntohl(iph1->mode_cfg->mask4.s_addr); + for (cidr = 0; tmp != 0; cidr++) + tmp <<= 1; + snprintf(cidrstr, 3, "%d", cidr); + + if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n"); + return -1; + } + + /* Internal IPv4 DNS */ + if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) { + /* First Internal IPv4 DNS (for compatibilty with older code */ + inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0], + addrstr, IP_MAX); + + /* Internal IPv4 DNS - all */ + isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index, + (void *)iph1->mode_cfg->dns4, 0); + } else { + addrstr[0] = '\0'; + addrlist[0] = '\0'; + } + + if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n"); + return -1; + } + if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set INTERNAL_DNS4_LIST\n"); + return -1; + } + + /* Internal IPv4 WINS */ + if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) { + /* + * First Internal IPv4 WINS + * (for compatibilty with older code + */ + inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0], + addrstr, IP_MAX); + + /* Internal IPv4 WINS - all */ + isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index, + (void *)iph1->mode_cfg->wins4, 0); + } else { + addrstr[0] = '\0'; + addrlist[0] = '\0'; + } + + if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set INTERNAL_WINS4\n"); + return -1; + } + if (script_env_append(envp, envc, + "INTERNAL_WINS4_LIST", addrlist) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set INTERNAL_WINS4_LIST\n"); + return -1; + } + + /* Deault domain */ + if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) + strncpy(defdom, + iph1->mode_cfg->default_domain, + MAXPATHLEN + 1); + else + defdom[0] = '\0'; + + if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set DEFAULT_DOMAIN\n"); + return -1; + } + + /* Split networks */ + if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE) { + splitlist = + splitnet_list_2str(iph1->mode_cfg->split_include, NETMASK); + splitlist_cidr = + splitnet_list_2str(iph1->mode_cfg->split_include, CIDR); + } else { + splitlist = addrlist; + splitlist_cidr = addrlist; + addrlist[0] = '\0'; + } + + if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n"); + return -1; + } + if (script_env_append(envp, envc, + "SPLIT_INCLUDE_CIDR", splitlist_cidr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set SPLIT_INCLUDE_CIDR\n"); + return -1; + } + if (splitlist != addrlist) + racoon_free(splitlist); + if (splitlist_cidr != addrlist) + racoon_free(splitlist_cidr); + + if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) { + splitlist = + splitnet_list_2str(iph1->mode_cfg->split_local, NETMASK); + splitlist_cidr = + splitnet_list_2str(iph1->mode_cfg->split_local, CIDR); + } else { + splitlist = addrlist; + splitlist_cidr = addrlist; + addrlist[0] = '\0'; + } + + if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n"); + return -1; + } + if (script_env_append(envp, envc, + "SPLIT_LOCAL_CIDR", splitlist_cidr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set SPLIT_LOCAL_CIDR\n"); + return -1; + } + if (splitlist != addrlist) + racoon_free(splitlist); + if (splitlist_cidr != addrlist) + racoon_free(splitlist_cidr); + + return 0; +} + +int +isakmp_cfg_resize_pool(size) + int size; +{ + struct isakmp_cfg_port *new_pool; + size_t len; + int i; + + if (size == isakmp_cfg_config.pool_size) + return 0; + + plog(LLV_INFO, LOCATION, NULL, + "Resize address pool from %zu to %d\n", + isakmp_cfg_config.pool_size, size); + + /* If a pool already exists, check if we can shrink it */ + if ((isakmp_cfg_config.port_pool != NULL) && + (size < isakmp_cfg_config.pool_size)) { + for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) { + if (isakmp_cfg_config.port_pool[i].used) { + plog(LLV_ERROR, LOCATION, NULL, + "resize pool from %zu to %d impossible " + "port %d is in use\n", + isakmp_cfg_config.pool_size, size, i); + size = i; + break; + } + } + } + + len = size * sizeof(*isakmp_cfg_config.port_pool); + new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len); + if (new_pool == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "resize pool from %zu to %d impossible: %s", + isakmp_cfg_config.pool_size, size, strerror(errno)); + return -1; + } + + /* If size increase, intialize correctly the new records */ + if (size > isakmp_cfg_config.pool_size) { + size_t unit; + size_t old_size; + + unit = sizeof(*isakmp_cfg_config.port_pool); + old_size = isakmp_cfg_config.pool_size; + + bzero((char *)new_pool + (old_size * unit), + (size - old_size) * unit); + } + + isakmp_cfg_config.port_pool = new_pool; + isakmp_cfg_config.pool_size = size; + + return 0; +} + +int +isakmp_cfg_init(cold) + int cold; +{ + int i; + int error; + + isakmp_cfg_config.network4 = (in_addr_t)0x00000000; + isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000; + for (i = 0; i < MAXNS; i++) + isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000; + isakmp_cfg_config.dns4_index = 0; + for (i = 0; i < MAXWINS; i++) + isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000; + isakmp_cfg_config.nbns4_index = 0; + if (cold == ISAKMP_CFG_INIT_COLD) + isakmp_cfg_config.port_pool = NULL; + isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM; + isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM; + if (cold == ISAKMP_CFG_INIT_COLD) { + if (isakmp_cfg_config.grouplist != NULL) { + for (i = 0; i < isakmp_cfg_config.groupcount; i++) + racoon_free(isakmp_cfg_config.grouplist[i]); + racoon_free(isakmp_cfg_config.grouplist); + } + } + isakmp_cfg_config.grouplist = NULL; + isakmp_cfg_config.groupcount = 0; + isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL; + isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE; + if (cold == ISAKMP_CFG_INIT_COLD) + isakmp_cfg_config.pool_size = 0; + isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY; + strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN, + MAXPATHLEN); + strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, MAXPATHLEN); + + if (cold != ISAKMP_CFG_INIT_COLD ) + if (isakmp_cfg_config.splitnet_list != NULL) + splitnet_list_free(isakmp_cfg_config.splitnet_list, + &isakmp_cfg_config.splitnet_count); + isakmp_cfg_config.splitnet_list = NULL; + isakmp_cfg_config.splitnet_count = 0; + isakmp_cfg_config.splitnet_type = 0; + + isakmp_cfg_config.pfs_group = 0; + isakmp_cfg_config.save_passwd = 0; + + if (cold != ISAKMP_CFG_INIT_COLD ) + if (isakmp_cfg_config.splitdns_list != NULL) + racoon_free(isakmp_cfg_config.splitdns_list); + isakmp_cfg_config.splitdns_list = NULL; + isakmp_cfg_config.splitdns_len = 0; + +#if 0 + if (cold == ISAKMP_CFG_INIT_COLD) { + if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0) + return error; + } +#endif + + return 0; +} + diff --git a/ipsec-tools/src/racoon/isakmp_cfg.h b/ipsec-tools/src/racoon/isakmp_cfg.h new file mode 100644 index 00000000..63fe4594 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_cfg.h @@ -0,0 +1,222 @@ +/* $NetBSD: isakmp_cfg.h,v 1.6 2006/09/09 16:22:09 manu Exp $ */ + +/* $KAME$ */ + +/* + * Copyright (C) 2004 Emmanuel Dreyfus + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_LIBPAM +#include +#endif + +/* + * XXX don't forget to update + * src/racoon/handler.c:exclude_cfg_addr() + * if you add IPv6 capability + */ + +/* Attribute types */ +#define INTERNAL_IP4_ADDRESS 1 +#define INTERNAL_IP4_NETMASK 2 +#define INTERNAL_IP4_DNS 3 +#define INTERNAL_IP4_NBNS 4 +#define INTERNAL_ADDRESS_EXPIRY 5 +#define INTERNAL_IP4_DHCP 6 +#define APPLICATION_VERSION 7 +#define INTERNAL_IP6_ADDRESS 8 +#define INTERNAL_IP6_NETMASK 9 +#define INTERNAL_IP6_DNS 10 +#define INTERNAL_IP6_NBNS 11 +#define INTERNAL_IP6_DHCP 12 +#define INTERNAL_IP4_SUBNET 13 +#define SUPPORTED_ATTRIBUTES 14 +#define INTERNAL_IP6_SUBNET 15 + +/* For APPLICATION_VERSION */ +#define ISAKMP_CFG_RACOON_VERSION "racoon / IPsec-tools" + +/* For the wins servers -- XXX find the value somewhere ? */ +#define MAXWINS 4 + +/* + * Global configuration for ISAKMP mode confiration address allocation + * Read from the mode_cfg section of racoon.conf + */ +struct isakmp_cfg_port { + char used; +#ifdef HAVE_LIBPAM + pam_handle_t *pam; +#endif +}; + +struct isakmp_cfg_config { + in_addr_t network4; + in_addr_t netmask4; + in_addr_t dns4[MAXNS]; + int dns4_index; + in_addr_t nbns4[MAXWINS]; + int nbns4_index; + struct isakmp_cfg_port *port_pool; + int authsource; + int groupsource; + char **grouplist; + int groupcount; + int confsource; + int accounting; + size_t pool_size; + int auth_throttle; + /* XXX move this to a unity specific sub-structure */ + char default_domain[MAXPATHLEN + 1]; + char motd[MAXPATHLEN + 1]; + struct unity_netentry *splitnet_list; + int splitnet_count; + int splitnet_type; + char *splitdns_list; + int splitdns_len; + int pfs_group; + int save_passwd; +}; + +/* For utmp updating */ +#define TERMSPEC "vpn%d" + +/* For authsource */ +#define ISAKMP_CFG_AUTH_SYSTEM 0 +#define ISAKMP_CFG_AUTH_RADIUS 1 +#define ISAKMP_CFG_AUTH_PAM 2 +#define ISAKMP_CFG_AUTH_LDAP 4 + +/* For groupsource */ +#define ISAKMP_CFG_GROUP_SYSTEM 0 +#define ISAKMP_CFG_GROUP_LDAP 1 + +/* For confsource */ +#define ISAKMP_CFG_CONF_LOCAL 0 +#define ISAKMP_CFG_CONF_RADIUS 1 +#define ISAKMP_CFG_CONF_LDAP 2 + +/* For accounting */ +#define ISAKMP_CFG_ACCT_NONE 0 +#define ISAKMP_CFG_ACCT_RADIUS 1 +#define ISAKMP_CFG_ACCT_PAM 2 +#define ISAKMP_CFG_ACCT_LDAP 3 +#define ISAKMP_CFG_ACCT_SYSTEM 4 + +/* For pool_size */ +#define ISAKMP_CFG_MAX_CNX 255 + +/* For motd */ +#define ISAKMP_CFG_MOTD "/etc/motd" + +/* For default domain */ +#define ISAKMP_CFG_DEFAULT_DOMAIN "" + +extern struct isakmp_cfg_config isakmp_cfg_config; + +/* + * ISAKMP mode config state + */ +#define LOGINLEN 31 +struct isakmp_cfg_state { + int flags; /* See below */ + unsigned int port; /* address index */ + char login[LOGINLEN + 1]; /* login */ + struct in_addr addr4; /* IPv4 address */ + struct in_addr mask4; /* IPv4 netmask */ + struct in_addr dns4[MAXNS]; /* IPv4 DNS (when client only) */ + int dns4_index; /* Number of IPv4 DNS (client only) */ + struct in_addr wins4[MAXWINS]; /* IPv4 WINS (when client only) */ + int wins4_index; /* Number of IPv4 WINS (client only) */ + char default_domain[MAXPATHLEN + 1]; /* Default domain recieved */ + struct unity_netentry + *split_include; /* UNITY_SPLIT_INCLUDE */ + int include_count; /* Number of SPLIT_INCLUDES */ + struct unity_netentry + *split_local; /* UNITY_LOCAL_LAN */ + int local_count; /* Number of SPLIT_LOCAL */ + struct xauth_state xauth; /* Xauth state, if revelant */ + struct isakmp_ivm *ivm; /* XXX Use iph1's ivm? */ + u_int32_t last_msgid; /* Last message-ID */ +}; + +/* flags */ +#define ISAKMP_CFG_VENDORID_XAUTH 0x01 /* Supports Xauth */ +#define ISAKMP_CFG_VENDORID_UNITY 0x02 /* Cisco Unity compliant */ +#define ISAKMP_CFG_PORT_ALLOCATED 0x04 /* Port allocated */ +#define ISAKMP_CFG_ADDR4_EXTERN 0x08 /* Address from external config */ +#define ISAKMP_CFG_MASK4_EXTERN 0x10 /* Netmask from external config */ +#define ISAKMP_CFG_ADDR4_LOCAL 0x20 /* Address from local pool */ +#define ISAKMP_CFG_MASK4_LOCAL 0x40 /* Netmask from local pool */ +#define ISAKMP_CFG_GOT_ADDR4 0x80 /* Client got address */ +#define ISAKMP_CFG_GOT_MASK4 0x100 /* Client got mask */ +#define ISAKMP_CFG_GOT_DNS4 0x200 /* Client got DNS */ +#define ISAKMP_CFG_GOT_WINS4 0x400 /* Client got WINS */ +#define ISAKMP_CFG_DELETE_PH1 0x800 /* phase 1 should be deleted */ +#define ISAKMP_CFG_GOT_DEFAULT_DOMAIN 0x1000 /* Client got default domain */ +#define ISAKMP_CFG_GOT_SPLIT_INCLUDE 0x2000 /* Client got a split network config */ +#define ISAKMP_CFG_GOT_SPLIT_LOCAL 0x4000 /* Client got a split LAN config */ + +struct isakmp_pl_attr; +struct ph1handle; +struct isakmp_ivm; +void isakmp_cfg_r(struct ph1handle *, vchar_t *); +int isakmp_cfg_attr_r(struct ph1handle *, u_int32_t, struct isakmp_pl_attr *); +int isakmp_cfg_reply(struct ph1handle *, struct isakmp_pl_attr *); +int isakmp_cfg_request(struct ph1handle *, struct isakmp_pl_attr *); +int isakmp_cfg_set(struct ph1handle *, struct isakmp_pl_attr *); +int isakmp_cfg_send(struct ph1handle *, vchar_t *, u_int32_t, int, int); +struct isakmp_ivm *isakmp_cfg_newiv(struct ph1handle *, u_int32_t); +void isakmp_cfg_rmstate(struct ph1handle *); +struct isakmp_cfg_state *isakmp_cfg_mkstate(void); +vchar_t *isakmp_cfg_copy(struct ph1handle *, struct isakmp_data *); +vchar_t *isakmp_cfg_short(struct ph1handle *, struct isakmp_data *, int); +vchar_t *isakmp_cfg_varlen(struct ph1handle *, struct isakmp_data *, char *, size_t); +vchar_t *isakmp_cfg_string(struct ph1handle *, struct isakmp_data *, char *); +int isakmp_cfg_getconfig(struct ph1handle *); +int isakmp_cfg_setenv(struct ph1handle *, char ***, int *); + +int isakmp_cfg_resize_pool(int); +int isakmp_cfg_getport(struct ph1handle *); +int isakmp_cfg_putport(struct ph1handle *, unsigned int); +int isakmp_cfg_init(int); +#define ISAKMP_CFG_INIT_COLD 1 +#define ISAKMP_CFG_INIT_WARM 0 + +#ifdef HAVE_LIBRADIUS +struct rad_handle; +extern struct rad_handle *radius_acct_state; +int isakmp_cfg_radius_common(struct rad_handle *, int); +#endif + +#ifdef HAVE_LIBPAM +int isakmp_cfg_accounting_pam(int, int); +void cleanup_pam(int); +#endif + +int isakmp_cfg_accounting_system(int, struct sockaddr *, char *, int); diff --git a/ipsec-tools/src/racoon/isakmp_frag.c b/ipsec-tools/src/racoon/isakmp_frag.c new file mode 100644 index 00000000..ebba34b4 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_frag.c @@ -0,0 +1,356 @@ +/* $NetBSD: isakmp_frag.c,v 1.5 2009/04/22 11:24:20 tteras Exp $ */ + +/* Id: isakmp_frag.c,v 1.4 2004/11/13 17:31:36 manubsd Exp */ + +/* + * Copyright (C) 2004 Emmanuel Dreyfus + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "schedule.h" +#include "debug.h" + +#include "isakmp_var.h" +#include "isakmp.h" +#include "handler.h" +#include "isakmp_frag.h" +#include "strnames.h" + +int +isakmp_sendfrags(iph1, buf) + struct ph1handle *iph1; + vchar_t *buf; +{ + struct isakmp *hdr; + struct isakmp_frag *fraghdr; + caddr_t data; + caddr_t sdata; + size_t datalen; + size_t max_datalen; + size_t fraglen; + vchar_t *frag; + unsigned int trailer; + unsigned int fragnum = 0; + size_t len; + int etype; + + /* + * Catch the exchange type for later: the fragments and the + * fragmented packet must have the same exchange type. + */ + hdr = (struct isakmp *)buf->v; + etype = hdr->etype; + + /* + * We want to send a a packet smaller than ISAKMP_FRAG_MAXLEN + * First compute the maximum data length that will fit in it + */ + max_datalen = ISAKMP_FRAG_MAXLEN - + (sizeof(*hdr) + sizeof(*fraghdr) + sizeof(trailer)); + + sdata = buf->v; + len = buf->l; + + while (len > 0) { + fragnum++; + + if (len > max_datalen) + datalen = max_datalen; + else + datalen = len; + + fraglen = sizeof(*hdr) + + sizeof(*fraghdr) + + datalen; + + if ((frag = vmalloc(fraglen)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory\n"); + return -1; + } + + set_isakmp_header1(frag, iph1, ISAKMP_NPTYPE_FRAG); + hdr = (struct isakmp *)frag->v; + hdr->etype = etype; + + fraghdr = (struct isakmp_frag *)(hdr + 1); + fraghdr->unknown0 = htons(0); + fraghdr->len = htons(fraglen - sizeof(*hdr)); + fraghdr->unknown1 = htons(1); + fraghdr->index = fragnum; + if (len == datalen) + fraghdr->flags = ISAKMP_FRAG_LAST; + else + fraghdr->flags = 0; + + data = (caddr_t)(fraghdr + 1); + memcpy(data, sdata, datalen); + + if (isakmp_send(iph1, frag) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "isakmp_send failed\n"); + return -1; + } + + vfree(frag); + + len -= datalen; + sdata += datalen; + } + + return fragnum; +} + +unsigned int +vendorid_frag_cap(gen) + struct isakmp_gen *gen; +{ + int *hp; + + hp = (int *)(gen + 1); + + return ntohl(hp[MD5_DIGEST_LENGTH / sizeof(*hp)]); +} + +int +isakmp_frag_extract(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + struct isakmp *isakmp; + struct isakmp_frag *frag; + struct isakmp_frag_item *item; + vchar_t *buf; + size_t len; + int last_frag = 0; + char *data; + int i; + + if (msg->l < sizeof(*isakmp) + sizeof(*frag)) { + plog(LLV_ERROR, LOCATION, NULL, "Message too short\n"); + return -1; + } + + isakmp = (struct isakmp *)msg->v; + frag = (struct isakmp_frag *)(isakmp + 1); + + /* + * frag->len is the frag payload data plus the frag payload header, + * whose size is sizeof(*frag) + */ + if (msg->l < sizeof(*isakmp) + ntohs(frag->len) || + ntohs(frag->len) < sizeof(*frag) + 1) { + plog(LLV_ERROR, LOCATION, NULL, "Fragment too short\n"); + return -1; + } + + if ((buf = vmalloc(ntohs(frag->len) - sizeof(*frag))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + return -1; + } + + if ((item = racoon_malloc(sizeof(*item))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + vfree(buf); + return -1; + } + + data = (char *)(frag + 1); + memcpy(buf->v, data, buf->l); + + item->frag_num = frag->index; + item->frag_last = (frag->flags & ISAKMP_FRAG_LAST); + item->frag_next = NULL; + item->frag_packet = buf; + + /* Look for the last frag while inserting the new item in the chain */ + if (item->frag_last) + last_frag = item->frag_num; + + if (iph1->frag_chain == NULL) { + iph1->frag_chain = item; + } else { + struct isakmp_frag_item *current; + + current = iph1->frag_chain; + while (current->frag_next) { + if (current->frag_last) + last_frag = item->frag_num; + current = current->frag_next; + } + current->frag_next = item; + } + + /* If we saw the last frag, check if the chain is complete */ + if (last_frag != 0) { + for (i = 1; i <= last_frag; i++) { + item = iph1->frag_chain; + do { + if (item->frag_num == i) + break; + item = item->frag_next; + } while (item != NULL); + + if (item == NULL) /* Not found */ + break; + } + + if (item != NULL) /* It is complete */ + return 1; + } + + return 0; +} + +vchar_t * +isakmp_frag_reassembly(iph1) + struct ph1handle *iph1; +{ + struct isakmp_frag_item *item; + size_t len = 0; + vchar_t *buf = NULL; + int frag_count = 0; + int i; + char *data; + + if ((item = iph1->frag_chain) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "No fragment to reassemble\n"); + goto out; + } + + do { + frag_count++; + len += item->frag_packet->l; + item = item->frag_next; + } while (item != NULL); + + if ((buf = vmalloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + goto out; + } + data = buf->v; + + for (i = 1; i <= frag_count; i++) { + item = iph1->frag_chain; + do { + if (item->frag_num == i) + break; + item = item->frag_next; + } while (item != NULL); + + if (item == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Missing fragment #%d\n", i); + vfree(buf); + buf = NULL; + goto out; + } + memcpy(data, item->frag_packet->v, item->frag_packet->l); + data += item->frag_packet->l; + } + +out: + item = iph1->frag_chain; + do { + struct isakmp_frag_item *next_item; + + next_item = item->frag_next; + + vfree(item->frag_packet); + racoon_free(item); + + item = next_item; + } while (item != NULL); + + iph1->frag_chain = NULL; + + return buf; +} + +vchar_t * +isakmp_frag_addcap(buf, cap) + vchar_t *buf; + int cap; +{ + int *capp; + size_t len; + + /* If the capability has not been added, add room now */ + len = buf->l; + if (len == MD5_DIGEST_LENGTH) { + if ((buf = vrealloc(buf, len + sizeof(cap))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory\n"); + return NULL; + } + capp = (int *)(buf->v + len); + *capp = htonl(0); + } + + capp = (int *)(buf->v + MD5_DIGEST_LENGTH); + *capp |= htonl(cap); + + return buf; +} + diff --git a/ipsec-tools/src/racoon/isakmp_frag.h b/ipsec-tools/src/racoon/isakmp_frag.h new file mode 100644 index 00000000..f2d4c335 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_frag.h @@ -0,0 +1,58 @@ +/* $NetBSD: isakmp_frag.h,v 1.5 2006/09/18 20:32:40 manu Exp $ */ + +/* Id: isakmp_frag.h,v 1.3 2005/04/09 16:25:24 manubsd Exp */ + +/* + * Copyright (C) 2004 Emmanuel Dreyfus + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* These are the values from parsing "remote {}" + block of the config file. */ +#define ISAKMP_FRAG_OFF FLASE /* = 0 */ +#define ISAKMP_FRAG_ON TRUE /* = 1 */ +#define ISAKMP_FRAG_FORCE 2 + +/* IKE fragmentation capabilities */ +#define VENDORID_FRAG_IDENT 0x80000000 +#define VENDORID_FRAG_BASE 0x40000000 +#define VENDORID_FRAG_AGG 0x80000000 + +#define ISAKMP_FRAG_MAXLEN 552 + +struct isakmp_frag_item { + int frag_num; + int frag_last; + struct isakmp_frag_item *frag_next; + vchar_t *frag_packet; +}; + +int isakmp_sendfrags(struct ph1handle *, vchar_t *); +unsigned int vendorid_frag_cap(struct isakmp_gen *); +int isakmp_frag_extract(struct ph1handle *, vchar_t *); +vchar_t *isakmp_frag_reassembly(struct ph1handle *); +vchar_t *isakmp_frag_addcap(vchar_t *, int); diff --git a/ipsec-tools/src/racoon/isakmp_ident.c b/ipsec-tools/src/racoon/isakmp_ident.c new file mode 100644 index 00000000..a9c3a012 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_ident.c @@ -0,0 +1,1900 @@ +/* $NetBSD: isakmp_ident.c,v 1.13 2009/09/18 10:31:11 tteras Exp $ */ + +/* Id: isakmp_ident.c,v 1.21 2006/04/06 16:46:08 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Identity Protecion Exchange (Main Mode) */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "schedule.h" +#include "debug.h" + +#include "localconf.h" +#include "remoteconf.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "evt.h" +#include "oakley.h" +#include "handler.h" +#include "ipsec_doi.h" +#include "crypto_openssl.h" +#include "pfkey.h" +#include "isakmp_ident.h" +#include "isakmp_inf.h" +#include "vendorid.h" + +#ifdef ENABLE_NATT +#include "nattraversal.h" +#endif +#ifdef HAVE_GSSAPI +#include "gssapi.h" +#endif +#ifdef ENABLE_HYBRID +#include +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif +#ifdef ENABLE_FRAG +#include "isakmp_frag.h" +#endif + +static vchar_t *ident_ir2mx __P((struct ph1handle *)); +static vchar_t *ident_ir3mx __P((struct ph1handle *)); +static int ident_recv_n __P((struct ph1handle *, struct isakmp_gen *)); + +/* %%% + * begin Identity Protection Mode as initiator. + */ +/* + * send to responder + * psk: HDR, SA + * sig: HDR, SA + * rsa: HDR, SA + * rev: HDR, SA + */ +int +ident_i1send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; /* must be null */ +{ + struct payload_list *plist = NULL; + int error = -1; +#ifdef ENABLE_NATT + vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL }; + int i; +#endif +#ifdef ENABLE_HYBRID + vchar_t *vid_xauth = NULL; + vchar_t *vid_unity = NULL; +#endif +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; +#endif +#ifdef ENABLE_DPD + vchar_t *vid_dpd = NULL; +#endif + /* validity check */ + if (msg != NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "msg has to be NULL in this function.\n"); + goto end; + } + if (iph1->status != PHASE1ST_START) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* create isakmp index */ + memset(&iph1->index, 0, sizeof(iph1->index)); + isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local); + + /* create SA payload for my proposal */ + iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf, + iph1->rmconf->proposal); + if (iph1->sa == NULL) + goto end; + + /* set SA payload to propose */ + plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA); + +#ifdef ENABLE_NATT + /* set VID payload for NAT-T if NAT-T support allowed in the config file */ + if (iph1->rmconf->nat_traversal) + plist = isakmp_plist_append_natt_vids(plist, vid_natt); +#endif +#ifdef ENABLE_HYBRID + /* Do we need Xauth VID? */ + switch (iph1->rmconf->proposal->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Xauth vendor ID generation failed\n"); + else + plist = isakmp_plist_append(plist, + vid_xauth, ISAKMP_NPTYPE_VID); + + if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Unity vendor ID generation failed\n"); + else + plist = isakmp_plist_append(plist, + vid_unity, ISAKMP_NPTYPE_VID); + break; + default: + break; + } +#endif +#ifdef ENABLE_FRAG + if (iph1->rmconf->ike_frag) { + if ((vid_frag = set_vendorid(VENDORID_FRAG)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Frag vendorID construction failed\n"); + } else { + vid_frag = isakmp_frag_addcap(vid_frag, + VENDORID_FRAG_IDENT); + plist = isakmp_plist_append(plist, + vid_frag, ISAKMP_NPTYPE_VID); + } + } +#endif +#ifdef ENABLE_DPD + if(iph1->rmconf->dpd){ + vid_dpd = set_vendorid(VENDORID_DPD); + if (vid_dpd != NULL) + plist = isakmp_plist_append(plist, vid_dpd, + ISAKMP_NPTYPE_VID); + } +#endif + + iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); +#endif + + /* send the packet, add to the schedule to resend */ + if (isakmp_ph1send(iph1) == -1) + goto end; + + iph1->status = PHASE1ST_MSG1SENT; + + error = 0; + +end: +#ifdef ENABLE_FRAG + if (vid_frag) + vfree(vid_frag); +#endif +#ifdef ENABLE_NATT + for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++) + vfree(vid_natt[i]); +#endif +#ifdef ENABLE_HYBRID + if (vid_xauth != NULL) + vfree(vid_xauth); + if (vid_unity != NULL) + vfree(vid_unity); +#endif +#ifdef ENABLE_DPD + if (vid_dpd != NULL) + vfree(vid_dpd); +#endif + + return error; +} + +/* + * receive from responder + * psk: HDR, SA + * sig: HDR, SA + * rsa: HDR, SA + * rev: HDR, SA + */ +int +ident_i2recv(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + vchar_t *satmp = NULL; + int error = -1; + + /* validity check */ + if (iph1->status != PHASE1ST_MSG1SENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* validate the type of next payload */ + /* + * NOTE: RedCreek(as responder) attaches N[responder-lifetime] here, + * if proposal-lifetime > lifetime-redcreek-wants. + * (see doi-08 4.5.4) + * => According to the seciton 4.6.3 in RFC 2407, This is illegal. + * NOTE: we do not really care about ordering of VID and N. + * does it matters? + * NOTE: even if there's multiple VID/N, we'll ignore them. + */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + pa = (struct isakmp_parse_t *)pbuf->v; + + /* SA payload is fixed postion */ + if (pa->type != ISAKMP_NPTYPE_SA) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "received invalid next payload type %d, " + "expecting %d.\n", + pa->type, ISAKMP_NPTYPE_SA); + goto end; + } + if (isakmp_p2ph(&satmp, pa->ptr) < 0) + goto end; + pa++; + + for (/*nothing*/; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_VID: + handle_vendorid(iph1, pa->ptr); + break; + default: + /* don't send information, see ident_r1recv() */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + +#ifdef ENABLE_NATT + if (NATT_AVAILABLE(iph1)) + plog(LLV_INFO, LOCATION, iph1->remote, + "Selected NAT-T version: %s\n", + vid_string_by_id(iph1->natt_options->version)); +#endif + + /* check SA payload and set approval SA for use */ + if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to get valid proposal.\n"); + /* XXX send information */ + goto end; + } + VPTRINIT(iph1->sa_ret); + + iph1->status = PHASE1ST_MSG2RECEIVED; + + error = 0; + +end: + if (pbuf) + vfree(pbuf); + if (satmp) + vfree(satmp); + return error; +} + +/* + * send to responder + * psk: HDR, KE, Ni + * sig: HDR, KE, Ni + * gssapi: HDR, KE, Ni, GSSi + * rsa: HDR, KE, [ HASH(1), ] PubKey_r, PubKey_r + * rev: HDR, [ HASH(1), ] Pubkey_r, Ke_i, + * Ke_i, [<Ke_i] + */ +int +ident_i2send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + int error = -1; + + /* validity check */ + if (iph1->status != PHASE1ST_MSG2RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* fix isakmp index */ + memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck, + sizeof(cookie_t)); + + /* generate DH public value */ + if (oakley_dh_generate(iph1->approval->dhgrp, + &iph1->dhpub, &iph1->dhpriv) < 0) + goto end; + + /* generate NONCE value */ + iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); + if (iph1->nonce == NULL) + goto end; + +#ifdef HAVE_GSSAPI + if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && + gssapi_get_itoken(iph1, NULL) < 0) + goto end; +#endif + + /* create buffer to send isakmp payload */ + iph1->sendbuf = ident_ir2mx(iph1); + if (iph1->sendbuf == NULL) + goto end; + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); +#endif + + /* send the packet, add to the schedule to resend */ + if (isakmp_ph1send(iph1) == -1) + goto end; + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + iph1->status = PHASE1ST_MSG2SENT; + + error = 0; + +end: + return error; +} + +/* + * receive from responder + * psk: HDR, KE, Nr + * sig: HDR, KE, Nr [, CR ] + * gssapi: HDR, KE, Nr, GSSr + * rsa: HDR, KE, PubKey_i, PubKey_i + * rev: HDR, PubKey_i, Ke_r, Ke_r, + */ +int +ident_i3recv(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + int error = -1; +#ifdef HAVE_GSSAPI + vchar_t *gsstoken = NULL; +#endif +#ifdef ENABLE_NATT + vchar_t *natd_received; + int natd_seq = 0, natd_verified; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG2SENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + + for (pa = (struct isakmp_parse_t *)pbuf->v; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_KE: + if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_NONCE: + if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_VID: + handle_vendorid(iph1, pa->ptr); + break; + case ISAKMP_NPTYPE_CR: + if (oakley_savecr(iph1, pa->ptr) < 0) + goto end; + break; +#ifdef HAVE_GSSAPI + case ISAKMP_NPTYPE_GSS: + if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + goto end; + gssapi_save_received_token(iph1, gsstoken); + break; +#endif + +#ifdef ENABLE_NATT + case ISAKMP_NPTYPE_NATD_DRAFT: + case ISAKMP_NPTYPE_NATD_RFC: + if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL && + pa->type == iph1->natt_options->payload_nat_d) { + natd_received = NULL; + if (isakmp_p2ph (&natd_received, pa->ptr) < 0) + goto end; + + /* set both bits first so that we can clear them + upon verifying hashes */ + if (natd_seq == 0) + iph1->natt_flags |= NAT_DETECTED; + + /* this function will clear appropriate bits bits + from iph1->natt_flags */ + natd_verified = natt_compare_addr_hash (iph1, + natd_received, natd_seq++); + + plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n", + natd_seq - 1, + natd_verified ? "verified" : "doesn't match"); + + vfree (natd_received); + break; + } + /* passthrough to default... */ +#endif + + default: + /* don't send information, see ident_r1recv() */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + +#ifdef ENABLE_NATT + if (NATT_AVAILABLE(iph1)) { + plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n", + iph1->natt_flags & NAT_DETECTED ? + "detected:" : "not detected", + iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "", + iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : ""); + if (iph1->natt_flags & NAT_DETECTED) + natt_float_ports (iph1); + } +#endif + + /* payload existency check */ + if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "few isakmp message received.\n"); + goto end; + } + + if (oakley_checkcr(iph1) < 0) { + /* Ignore this error in order to be interoperability. */ + ; + } + + iph1->status = PHASE1ST_MSG3RECEIVED; + + error = 0; + +end: +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif + if (pbuf) + vfree(pbuf); + if (error) { + VPTRINIT(iph1->dhpub_p); + VPTRINIT(iph1->nonce_p); + VPTRINIT(iph1->id_p); + VPTRINIT(iph1->cr_p); + } + + return error; +} + +/* + * send to responder + * psk: HDR*, IDi1, HASH_I + * sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I + * gssapi: HDR*, IDi1, < Gssi(n) | HASH_I > + * rsa: HDR*, HASH_I + * rev: HDR*, HASH_I + */ +int +ident_i3send(iph1, msg0) + struct ph1handle *iph1; + vchar_t *msg0; +{ + int error = -1; + int dohash = 1; +#ifdef HAVE_GSSAPI + int len; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG3RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* compute sharing secret of DH */ + if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, + iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) + goto end; + + /* generate SKEYIDs & IV & final cipher key */ + if (oakley_skeyid(iph1) < 0) + goto end; + if (oakley_skeyid_dae(iph1) < 0) + goto end; + if (oakley_compute_enckey(iph1) < 0) + goto end; + if (oakley_newiv(iph1) < 0) + goto end; + + /* make ID payload into isakmp status */ + if (ipsecdoi_setid1(iph1) < 0) + goto end; + +#ifdef HAVE_GSSAPI + if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && + gssapi_more_tokens(iph1)) { + plog(LLV_DEBUG, LOCATION, NULL, "calling get_itoken\n"); + if (gssapi_get_itoken(iph1, &len) < 0) + goto end; + if (len != 0) + dohash = 0; + } +#endif + + /* generate HASH to send */ + if (dohash) { + iph1->hash = oakley_ph1hash_common(iph1, GENERATE); + if (iph1->hash == NULL) + goto end; + } else + iph1->hash = NULL; + + /* set encryption flag */ + iph1->flags |= ISAKMP_FLAG_E; + + /* create HDR;ID;HASH payload */ + iph1->sendbuf = ident_ir3mx(iph1); + if (iph1->sendbuf == NULL) + goto end; + + /* send the packet, add to the schedule to resend */ + if (isakmp_ph1send(iph1) == -1) + goto end; + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg0) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + /* see handler.h about IV synchronization. */ + memcpy(iph1->ivm->ive->v, iph1->ivm->iv->v, iph1->ivm->iv->l); + + iph1->status = PHASE1ST_MSG3SENT; + + error = 0; + +end: + return error; +} + +/* + * receive from responder + * psk: HDR*, IDr1, HASH_R + * sig: HDR*, IDr1, [ CERT, ] SIG_R + * gssapi: HDR*, IDr1, < GSSr(n) | HASH_R > + * rsa: HDR*, HASH_R + * rev: HDR*, HASH_R + */ +int +ident_i4recv(iph1, msg0) + struct ph1handle *iph1; + vchar_t *msg0; +{ + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + vchar_t *msg = NULL; + int error = -1; + int type; +#ifdef HAVE_GSSAPI + vchar_t *gsstoken = NULL; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG3SENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* decrypting */ + if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "expecting the packet encrypted.\n"); + goto end; + } + msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive); + if (msg == NULL) + goto end; + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + + iph1->pl_hash = NULL; + + for (pa = (struct isakmp_parse_t *)pbuf->v; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_ID: + if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_HASH: + iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; + break; + case ISAKMP_NPTYPE_CERT: + if (oakley_savecert(iph1, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_SIG: + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) + goto end; + break; +#ifdef HAVE_GSSAPI + case ISAKMP_NPTYPE_GSS: + if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + goto end; + gssapi_save_received_token(iph1, gsstoken); + break; +#endif + case ISAKMP_NPTYPE_VID: + handle_vendorid(iph1, pa->ptr); + break; + case ISAKMP_NPTYPE_N: + ident_recv_n(iph1, pa->ptr); + break; + default: + /* don't send information, see ident_r1recv() */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + + /* payload existency check */ + + /* verify identifier */ + if (ipsecdoi_checkid1(iph1) != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "invalid ID payload.\n"); + goto end; + } + + /* validate authentication value */ +#ifdef HAVE_GSSAPI + if (gsstoken == NULL) { +#endif + type = oakley_validate_auth(iph1); + if (type != 0) { + if (type == -1) { + /* msg printed inner oakley_validate_auth() */ + goto end; + } + evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL); + isakmp_info_send_n1(iph1, type, NULL); + goto end; + } +#ifdef HAVE_GSSAPI + } +#endif + + /* + * XXX: Should we do compare two addresses, ph1handle's and ID + * payload's. + */ + + plog(LLV_DEBUG, LOCATION, iph1->remote, "peer's ID:"); + plogdump(LLV_DEBUG, iph1->id_p->v, iph1->id_p->l); + + /* see handler.h about IV synchronization. */ + memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->ive->l); + + /* + * If we got a GSS token, we need to this roundtrip again. + */ +#ifdef HAVE_GSSAPI + iph1->status = gsstoken != 0 ? PHASE1ST_MSG3RECEIVED : + PHASE1ST_MSG4RECEIVED; +#else + iph1->status = PHASE1ST_MSG4RECEIVED; +#endif + + error = 0; + +end: + if (pbuf) + vfree(pbuf); + if (msg) + vfree(msg); +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif + + if (error) { + VPTRINIT(iph1->id_p); + VPTRINIT(iph1->cert_p); + VPTRINIT(iph1->crl_p); + VPTRINIT(iph1->sig_p); + } + + return error; +} + +/* + * status update and establish isakmp sa. + */ +int +ident_i4send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + int error = -1; + + /* validity check */ + if (iph1->status != PHASE1ST_MSG4RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* see handler.h about IV synchronization. */ + memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l); + + iph1->status = PHASE1ST_ESTABLISHED; + + error = 0; + +end: + return error; +} + +/* + * receive from initiator + * psk: HDR, SA + * sig: HDR, SA + * rsa: HDR, SA + * rev: HDR, SA + */ +int +ident_r1recv(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + int error = -1; + int vid_numeric; + + /* validity check */ + if (iph1->status != PHASE1ST_START) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* validate the type of next payload */ + /* + * NOTE: XXX even if multiple VID, we'll silently ignore those. + */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + pa = (struct isakmp_parse_t *)pbuf->v; + + /* check the position of SA payload */ + if (pa->type != ISAKMP_NPTYPE_SA) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "received invalid next payload type %d, " + "expecting %d.\n", + pa->type, ISAKMP_NPTYPE_SA); + goto end; + } + if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) + goto end; + pa++; + + for (/*nothing*/; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_VID: + vid_numeric = handle_vendorid(iph1, pa->ptr); +#ifdef ENABLE_FRAG + if ((vid_numeric == VENDORID_FRAG) && + (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_IDENT)) + iph1->frag = 1; +#endif + break; + default: + /* + * We don't send information to the peer even + * if we received malformed packet. Because we + * can't distinguish the malformed packet and + * the re-sent packet. And we do same behavior + * when we expect encrypted packet. + */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + +#ifdef ENABLE_NATT + if (NATT_AVAILABLE(iph1)) + plog(LLV_INFO, LOCATION, iph1->remote, + "Selected NAT-T version: %s\n", + vid_string_by_id(iph1->natt_options->version)); +#endif + + /* check SA payload and set approval SA for use */ + if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to get valid proposal.\n"); + /* XXX send information */ + goto end; + } + + iph1->status = PHASE1ST_MSG1RECEIVED; + + error = 0; + +end: + if (pbuf) + vfree(pbuf); + if (error) { + VPTRINIT(iph1->sa); + } + + return error; +} + +/* + * send to initiator + * psk: HDR, SA + * sig: HDR, SA + * rsa: HDR, SA + * rev: HDR, SA + */ +int +ident_r1send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + struct payload_list *plist = NULL; + int error = -1; + vchar_t *gss_sa = NULL; +#ifdef HAVE_GSSAPI + int free_gss_sa = 0; +#endif +#ifdef ENABLE_NATT + vchar_t *vid_natt = NULL; +#endif +#ifdef ENABLE_HYBRID + vchar_t *vid_xauth = NULL; + vchar_t *vid_unity = NULL; +#endif +#ifdef ENABLE_DPD + vchar_t *vid_dpd = NULL; +#endif +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG1RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* set responder's cookie */ + isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local); + +#ifdef HAVE_GSSAPI + if (iph1->approval->gssid != NULL) { + gss_sa = ipsecdoi_setph1proposal(iph1->rmconf, iph1->approval); + if (gss_sa != iph1->sa_ret) + free_gss_sa = 1; + } else +#endif + gss_sa = iph1->sa_ret; + + /* set SA payload to reply */ + plist = isakmp_plist_append(plist, gss_sa, ISAKMP_NPTYPE_SA); + +#ifdef ENABLE_HYBRID + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { + plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n"); + if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot create Xauth vendor ID\n"); + goto end; + } + plist = isakmp_plist_append(plist, + vid_xauth, ISAKMP_NPTYPE_VID); + } + + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) { + if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot create Unity vendor ID\n"); + goto end; + } + plist = isakmp_plist_append(plist, + vid_unity, ISAKMP_NPTYPE_VID); + } +#endif +#ifdef ENABLE_NATT + /* Has the peer announced NAT-T? */ + if (NATT_AVAILABLE(iph1)) + vid_natt = set_vendorid(iph1->natt_options->version); + + if (vid_natt) + plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID); +#endif +#ifdef ENABLE_DPD + if (iph1->dpd_support) { + vid_dpd = set_vendorid(VENDORID_DPD); + if (vid_dpd != NULL) + plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID); + } +#endif +#ifdef ENABLE_FRAG + if (iph1->frag) { + vid_frag = set_vendorid(VENDORID_FRAG); + if (vid_frag != NULL) + vid_frag = isakmp_frag_addcap(vid_frag, + VENDORID_FRAG_IDENT); + if (vid_frag == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Frag vendorID construction failed\n"); + else + plist = isakmp_plist_append(plist, + vid_frag, ISAKMP_NPTYPE_VID); + } +#endif + + iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); +#endif + + /* send the packet, add to the schedule to resend */ + if (isakmp_ph1send(iph1) == -1) + goto end; + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + iph1->status = PHASE1ST_MSG1SENT; + + error = 0; + +end: +#ifdef HAVE_GSSAPI + if (free_gss_sa) + vfree(gss_sa); +#endif +#ifdef ENABLE_NATT + if (vid_natt) + vfree(vid_natt); +#endif +#ifdef ENABLE_HYBRID + if (vid_xauth != NULL) + vfree(vid_xauth); + if (vid_unity != NULL) + vfree(vid_unity); +#endif +#ifdef ENABLE_DPD + if (vid_dpd != NULL) + vfree(vid_dpd); +#endif +#ifdef ENABLE_FRAG + if (vid_frag != NULL) + vfree(vid_frag); +#endif + + return error; +} + +/* + * receive from initiator + * psk: HDR, KE, Ni + * sig: HDR, KE, Ni + * gssapi: HDR, KE, Ni, GSSi + * rsa: HDR, KE, [ HASH(1), ] PubKey_r, PubKey_r + * rev: HDR, [ HASH(1), ] Pubkey_r, Ke_i, + * Ke_i, [<Ke_i] + */ +int +ident_r2recv(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + int error = -1; +#ifdef HAVE_GSSAPI + vchar_t *gsstoken = NULL; +#endif +#ifdef ENABLE_NATT + int natd_seq = 0; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG1SENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + + for (pa = (struct isakmp_parse_t *)pbuf->v; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + switch (pa->type) { + case ISAKMP_NPTYPE_KE: + if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_NONCE: + if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_VID: + handle_vendorid(iph1, pa->ptr); + break; + case ISAKMP_NPTYPE_CR: + plog(LLV_WARNING, LOCATION, iph1->remote, + "CR received, ignore it. " + "It should be in other exchange.\n"); + break; +#ifdef HAVE_GSSAPI + case ISAKMP_NPTYPE_GSS: + if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + goto end; + gssapi_save_received_token(iph1, gsstoken); + break; +#endif + +#ifdef ENABLE_NATT + case ISAKMP_NPTYPE_NATD_DRAFT: + case ISAKMP_NPTYPE_NATD_RFC: + if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL && + pa->type == iph1->natt_options->payload_nat_d) + { + vchar_t *natd_received = NULL; + int natd_verified; + + if (isakmp_p2ph (&natd_received, pa->ptr) < 0) + goto end; + + if (natd_seq == 0) + iph1->natt_flags |= NAT_DETECTED; + + natd_verified = natt_compare_addr_hash (iph1, + natd_received, natd_seq++); + + plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n", + natd_seq - 1, + natd_verified ? "verified" : "doesn't match"); + + vfree (natd_received); + break; + } + /* passthrough to default... */ +#endif + + default: + /* don't send information, see ident_r1recv() */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + +#ifdef ENABLE_NATT + if (NATT_AVAILABLE(iph1)) + plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n", + iph1->natt_flags & NAT_DETECTED ? + "detected:" : "not detected", + iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "", + iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : ""); +#endif + + /* payload existency check */ + if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "few isakmp message received.\n"); + goto end; + } + + iph1->status = PHASE1ST_MSG2RECEIVED; + + error = 0; + +end: + if (pbuf) + vfree(pbuf); +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif + + if (error) { + VPTRINIT(iph1->dhpub_p); + VPTRINIT(iph1->nonce_p); + VPTRINIT(iph1->id_p); + } + + return error; +} + +/* + * send to initiator + * psk: HDR, KE, Nr + * sig: HDR, KE, Nr [, CR ] + * gssapi: HDR, KE, Nr, GSSr + * rsa: HDR, KE, PubKey_i, PubKey_i + * rev: HDR, PubKey_i, Ke_r, Ke_r, + */ +int +ident_r2send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + int error = -1; + + /* validity check */ + if (iph1->status != PHASE1ST_MSG2RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* generate DH public value */ + if (oakley_dh_generate(iph1->approval->dhgrp, + &iph1->dhpub, &iph1->dhpriv) < 0) + goto end; + + /* generate NONCE value */ + iph1->nonce = eay_set_random(RMCONF_NONCE_SIZE(iph1->rmconf)); + if (iph1->nonce == NULL) + goto end; + +#ifdef HAVE_GSSAPI + if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) + gssapi_get_rtoken(iph1, NULL); +#endif + + /* create HDR;KE;NONCE payload */ + iph1->sendbuf = ident_ir2mx(iph1); + if (iph1->sendbuf == NULL) + goto end; + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); +#endif + + /* send the packet, add to the schedule to resend */ + if (isakmp_ph1send(iph1) == -1) + goto end; + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + /* compute sharing secret of DH */ + if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, + iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) + goto end; + + /* generate SKEYIDs & IV & final cipher key */ + if (oakley_skeyid(iph1) < 0) + goto end; + if (oakley_skeyid_dae(iph1) < 0) + goto end; + if (oakley_compute_enckey(iph1) < 0) + goto end; + if (oakley_newiv(iph1) < 0) + goto end; + + iph1->status = PHASE1ST_MSG2SENT; + + error = 0; + +end: + return error; +} + +/* + * receive from initiator + * psk: HDR*, IDi1, HASH_I + * sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I + * gssapi: HDR*, [ IDi1, ] < GSSi(n) | HASH_I > + * rsa: HDR*, HASH_I + * rev: HDR*, HASH_I + */ +int +ident_r3recv(iph1, msg0) + struct ph1handle *iph1; + vchar_t *msg0; +{ + vchar_t *msg = NULL; + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + int error = -1; + int type; +#ifdef HAVE_GSSAPI + vchar_t *gsstoken = NULL; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG2SENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* decrypting */ + if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "reject the packet, " + "expecting the packet encrypted.\n"); + goto end; + } + msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive); + if (msg == NULL) + goto end; + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + + iph1->pl_hash = NULL; + + for (pa = (struct isakmp_parse_t *)pbuf->v; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_ID: + if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) + goto end; + if (resolveph1rmconf(iph1) < 0) + goto end; + break; + case ISAKMP_NPTYPE_HASH: + iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; + break; + case ISAKMP_NPTYPE_CR: + if (oakley_savecr(iph1, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_CERT: + if (oakley_savecert(iph1, pa->ptr) < 0) + goto end; + break; + case ISAKMP_NPTYPE_SIG: + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) + goto end; + break; +#ifdef HAVE_GSSAPI + case ISAKMP_NPTYPE_GSS: + if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + goto end; + gssapi_save_received_token(iph1, gsstoken); + break; +#endif + case ISAKMP_NPTYPE_VID: + handle_vendorid(iph1, pa->ptr); + break; + case ISAKMP_NPTYPE_N: + ident_recv_n(iph1, pa->ptr); + break; + default: + /* don't send information, see ident_r1recv() */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + + /* payload existency check */ + /* XXX same as ident_i4recv(), should be merged. */ + { + int ng = 0; + + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: +#endif + if (iph1->id_p == NULL || iph1->pl_hash == NULL) + ng++; + break; + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: +#endif + if (iph1->id_p == NULL || iph1->sig_p == NULL) + ng++; + break; + case OAKLEY_ATTR_AUTH_METHOD_RSAENC: + case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif + if (iph1->pl_hash == NULL) + ng++; + break; +#ifdef HAVE_GSSAPI + case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: + if (gsstoken == NULL && iph1->pl_hash == NULL) + ng++; + break; +#endif + default: + plog(LLV_ERROR, LOCATION, iph1->remote, + "invalid authmethod %d why ?\n", + iph1->approval->authmethod); + goto end; + } + if (ng) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "few isakmp message received.\n"); + goto end; + } + } + + /* verify identifier */ + if (ipsecdoi_checkid1(iph1) != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "invalid ID payload.\n"); + goto end; + } + + /* validate authentication value */ +#ifdef HAVE_GSSAPI + if (gsstoken == NULL) { +#endif + type = oakley_validate_auth(iph1); + if (type != 0) { + if (type == -1) { + /* msg printed inner oakley_validate_auth() */ + goto end; + } + evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL); + isakmp_info_send_n1(iph1, type, NULL); + goto end; + } +#ifdef HAVE_GSSAPI + } +#endif + + if (oakley_checkcr(iph1) < 0) { + /* Ignore this error in order to be interoperability. */ + ; + } + + /* + * XXX: Should we do compare two addresses, ph1handle's and ID + * payload's. + */ + + plog(LLV_DEBUG, LOCATION, iph1->remote, "peer's ID\n"); + plogdump(LLV_DEBUG, iph1->id_p->v, iph1->id_p->l); + + /* see handler.h about IV synchronization. */ + memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->ive->l); + +#ifdef HAVE_GSSAPI + iph1->status = gsstoken != NULL ? PHASE1ST_MSG2RECEIVED : + PHASE1ST_MSG3RECEIVED; +#else + iph1->status = PHASE1ST_MSG3RECEIVED; +#endif + + error = 0; + +end: + if (pbuf) + vfree(pbuf); + if (msg) + vfree(msg); +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif + + if (error) { + VPTRINIT(iph1->id_p); + VPTRINIT(iph1->cert_p); + VPTRINIT(iph1->crl_p); + VPTRINIT(iph1->sig_p); + VPTRINIT(iph1->cr_p); + } + + return error; +} + +/* + * send to initiator + * psk: HDR*, IDr1, HASH_R + * sig: HDR*, IDr1, [ CERT, ] SIG_R + * gssapi: HDR*, IDr1, < GSSr(n) | HASH_R > + * rsa: HDR*, HASH_R + * rev: HDR*, HASH_R + */ +int +ident_r3send(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ + int error = -1; + int dohash = 1; +#ifdef HAVE_GSSAPI + int len; +#endif + + /* validity check */ + if (iph1->status != PHASE1ST_MSG3RECEIVED) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph1->status); + goto end; + } + + /* make ID payload into isakmp status */ + if (ipsecdoi_setid1(iph1) < 0) + goto end; + +#ifdef HAVE_GSSAPI + if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && + gssapi_more_tokens(iph1)) { + gssapi_get_rtoken(iph1, &len); + if (len != 0) + dohash = 0; + } +#endif + + if (dohash) { + /* generate HASH to send */ + plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n"); + iph1->hash = oakley_ph1hash_common(iph1, GENERATE); + if (iph1->hash == NULL) + goto end; + } else + iph1->hash = NULL; + + /* set encryption flag */ + iph1->flags |= ISAKMP_FLAG_E; + + /* create HDR;ID;HASH payload */ + iph1->sendbuf = ident_ir3mx(iph1); + if (iph1->sendbuf == NULL) + goto end; + + /* send HDR;ID;HASH to responder */ + if (isakmp_send(iph1, iph1->sendbuf) < 0) + goto end; + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + /* see handler.h about IV synchronization. */ + memcpy(iph1->ivm->ive->v, iph1->ivm->iv->v, iph1->ivm->iv->l); + + iph1->status = PHASE1ST_ESTABLISHED; + + error = 0; + +end: + + return error; +} + +/* + * This is used in main mode for: + * initiator's 3rd exchange send to responder + * psk: HDR, KE, Ni + * sig: HDR, KE, Ni + * rsa: HDR, KE, [ HASH(1), ] PubKey_r, PubKey_r + * rev: HDR, [ HASH(1), ] Pubkey_r, Ke_i, + * Ke_i, [<Ke_i] + * responders 2nd exchnage send to initiator + * psk: HDR, KE, Nr + * sig: HDR, KE, Nr [, CR ] + * rsa: HDR, KE, PubKey_i, PubKey_i + * rev: HDR, PubKey_i, Ke_r, Ke_r, + */ +static vchar_t * +ident_ir2mx(iph1) + struct ph1handle *iph1; +{ + vchar_t *buf = 0; + struct payload_list *plist = NULL; + vchar_t *vid = NULL; + int error = -1; +#ifdef HAVE_GSSAPI + vchar_t *gsstoken = NULL; +#endif +#ifdef ENABLE_NATT + vchar_t *natd[2] = { NULL, NULL }; +#endif + +#ifdef HAVE_GSSAPI + if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { + if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Failed to get gssapi token.\n"); + goto end; + } + } +#endif + + /* create isakmp KE payload */ + plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE); + + /* create isakmp NONCE payload */ + plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE); + +#ifdef HAVE_GSSAPI + if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) + plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); +#endif + + /* append vendor id, if needed */ + if (vid) + plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); + + /* create CR if need */ + if (iph1->side == RESPONDER && + oakley_needcr(iph1->approval->authmethod)) + plist = oakley_append_cr(plist, iph1); + +#ifdef ENABLE_NATT + /* generate and append NAT-D payloads */ + if (NATT_AVAILABLE(iph1) && iph1->status == PHASE1ST_MSG2RECEIVED) + { + if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "NAT-D hashing failed for %s\n", saddr2str(iph1->remote)); + goto end; + } + + if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "NAT-D hashing failed for %s\n", saddr2str(iph1->local)); + goto end; + } + + plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n"); + plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d); + plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d); + } +#endif + + buf = isakmp_plist_set_all (&plist, iph1); + + error = 0; + +end: + if (error && buf != NULL) { + vfree(buf); + buf = NULL; + } +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif + if (vid) + vfree(vid); + +#ifdef ENABLE_NATT + if (natd[0]) + vfree(natd[0]); + if (natd[1]) + vfree(natd[1]); +#endif + + return buf; +} + +/* + * This is used in main mode for: + * initiator's 4th exchange send to responder + * psk: HDR*, IDi1, HASH_I + * sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I + * gssapi: HDR*, [ IDi1, ] < GSSi(n) | HASH_I > + * rsa: HDR*, HASH_I + * rev: HDR*, HASH_I + * responders 3rd exchnage send to initiator + * psk: HDR*, IDr1, HASH_R + * sig: HDR*, IDr1, [ CERT, ] SIG_R + * gssapi: HDR*, [ IDr1, ] < GSSr(n) | HASH_R > + * rsa: HDR*, HASH_R + * rev: HDR*, HASH_R + */ +static vchar_t * +ident_ir3mx(iph1) + struct ph1handle *iph1; +{ + struct payload_list *plist = NULL; + vchar_t *buf = NULL, *new = NULL; + int need_cert = 0; + int error = -1; +#ifdef HAVE_GSSAPI + int nptype; + vchar_t *gsstoken = NULL; + vchar_t *gsshash = NULL; +#endif + + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: +#endif + /* create isakmp ID payload */ + plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); + + /* create isakmp HASH payload */ + plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH); + break; + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: +#endif + if (oakley_getmycert(iph1) < 0) + goto end; + + if (oakley_getsign(iph1) < 0) + goto end; + + if (iph1->cert != NULL && iph1->rmconf->send_cert) + need_cert = 1; + + /* add ID payload */ + plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); + + /* add CERT payload if there */ + if (need_cert) + plist = isakmp_plist_append(plist, iph1->cert, + ISAKMP_NPTYPE_CERT); + /* add SIG payload */ + plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG); + + /* create isakmp CR payload */ + if (iph1->side == INITIATOR && + oakley_needcr(iph1->approval->authmethod)) + plist = oakley_append_cr(plist, iph1); + break; +#ifdef HAVE_GSSAPI + case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: + if (iph1->hash != NULL) { + gsshash = gssapi_wraphash(iph1); + if (gsshash == NULL) + goto end; + } else { + if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Failed to get gssapi token.\n"); + goto end; + } + } + + if (!gssapi_id_sent(iph1)) { + /* create isakmp ID payload */ + plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); + gssapi_set_id_sent(iph1); + } + + if (iph1->hash != NULL) + /* create isakmp HASH payload */ + plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH); + else + plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); + break; +#endif + case OAKLEY_ATTR_AUTH_METHOD_RSAENC: + case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif + plog(LLV_ERROR, LOCATION, NULL, + "not supported authentication type %d\n", + iph1->approval->authmethod); + goto end; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid authentication type %d\n", + iph1->approval->authmethod); + goto end; + } + + buf = isakmp_plist_set_all (&plist, iph1); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(buf, iph1->local, iph1->remote, 1); +#endif + + /* encoding */ + new = oakley_do_encrypt(iph1, buf, iph1->ivm->ive, iph1->ivm->iv); + if (new == NULL) + goto end; + + vfree(buf); + + buf = new; + + error = 0; + +end: +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif + if (error && buf != NULL) { + vfree(buf); + buf = NULL; + } + + return buf; +} + +/* + * handle a notification payload inside identity exchange. + * called only when the packet has been verified to be encrypted. + */ +static int +ident_recv_n(iph1, gen) + struct ph1handle *iph1; + struct isakmp_gen *gen; +{ + struct isakmp_pl_n *notify = (struct isakmp_pl_n *) gen; + u_int type; + + type = ntohs(notify->type); + switch (type) { + case ISAKMP_NTYPE_INITIAL_CONTACT: + iph1->initial_contact_received = TRUE; + break; + default: + isakmp_log_notify(iph1, notify, "identity exchange"); + break; + } + return 0; +} + diff --git a/ipsec-tools/src/racoon/isakmp_ident.h b/ipsec-tools/src/racoon/isakmp_ident.h new file mode 100644 index 00000000..ea5595d8 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_ident.h @@ -0,0 +1,52 @@ +/* $NetBSD: isakmp_ident.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: isakmp_ident.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ISAKMP_IDENT_H +#define _ISAKMP_IDENT_H + +extern int ident_i1send __P((struct ph1handle *, vchar_t *)); +extern int ident_i2recv __P((struct ph1handle *, vchar_t *)); +extern int ident_i2send __P((struct ph1handle *, vchar_t *)); +extern int ident_i3recv __P((struct ph1handle *, vchar_t *)); +extern int ident_i3send __P((struct ph1handle *, vchar_t *)); +extern int ident_i4recv __P((struct ph1handle *, vchar_t *)); +extern int ident_i4send __P((struct ph1handle *, vchar_t *)); + +extern int ident_r1recv __P((struct ph1handle *, vchar_t *)); +extern int ident_r1send __P((struct ph1handle *, vchar_t *)); +extern int ident_r2recv __P((struct ph1handle *, vchar_t *)); +extern int ident_r2send __P((struct ph1handle *, vchar_t *)); +extern int ident_r3recv __P((struct ph1handle *, vchar_t *)); +extern int ident_r3send __P((struct ph1handle *, vchar_t *)); + +#endif /* _ISAKMP_IDENT_H */ diff --git a/ipsec-tools/src/racoon/isakmp_inf.c b/ipsec-tools/src/racoon/isakmp_inf.c new file mode 100644 index 00000000..99daffb3 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_inf.c @@ -0,0 +1,1605 @@ +/* $NetBSD: isakmp_inf.c,v 1.47.2.3 2013/04/12 09:53:52 tteras Exp $ */ + +/* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#ifdef ENABLE_HYBRID +#include +#endif + +#include "libpfkey.h" + +#include "var.h" +#include "vmbuf.h" +#include "schedule.h" +#include "str2val.h" +#include "misc.h" +#include "plog.h" +#include "debug.h" + +#include "localconf.h" +#include "remoteconf.h" +#include "sockmisc.h" +#include "handler.h" +#include "policy.h" +#include "proposal.h" +#include "isakmp_var.h" +#include "evt.h" +#include "isakmp.h" +#ifdef ENABLE_HYBRID +#include "isakmp_xauth.h" +#include "isakmp_unity.h" +#include "isakmp_cfg.h" +#endif +#include "isakmp_inf.h" +#include "oakley.h" +#include "ipsec_doi.h" +#include "crypto_openssl.h" +#include "pfkey.h" +#include "policy.h" +#include "algorithm.h" +#include "proposal.h" +#include "admin.h" +#include "strnames.h" +#ifdef ENABLE_NATT +#include "nattraversal.h" +#endif + +/* information exchange */ +static int isakmp_info_recv_n (struct ph1handle *, struct isakmp_pl_n *, u_int32_t, int); +static int isakmp_info_recv_d (struct ph1handle *, struct isakmp_pl_d *, u_int32_t, int); + +#ifdef ENABLE_DPD +static int isakmp_info_recv_r_u __P((struct ph1handle *, + struct isakmp_pl_ru *, u_int32_t)); +static int isakmp_info_recv_r_u_ack __P((struct ph1handle *, + struct isakmp_pl_ru *, u_int32_t)); +static void isakmp_info_send_r_u __P((struct sched *)); +#endif + +static void purge_isakmp_spi __P((int, isakmp_index *, size_t)); + +/* %%% + * Information Exchange + */ +/* + * receive Information + */ +int +isakmp_info_recv(iph1, msg0) + struct ph1handle *iph1; + vchar_t *msg0; +{ + vchar_t *msg = NULL; + vchar_t *pbuf = NULL; + u_int32_t msgid = 0; + int error = -1; + struct isakmp *isakmp; + struct isakmp_gen *gen; + struct isakmp_parse_t *pa, *pap; + void *p; + vchar_t *hash, *payload; + struct isakmp_gen *nd; + u_int8_t np; + int encrypted; + + plog(LLV_DEBUG, LOCATION, NULL, "receive Information.\n"); + + encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E); + msgid = ((struct isakmp *)msg0->v)->msgid; + + /* Use new IV to decrypt Informational message. */ + if (encrypted) { + struct isakmp_ivm *ivm; + + if (iph1->ivm == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "iph1->ivm == NULL\n"); + return -1; + } + + /* compute IV */ + ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid); + if (ivm == NULL) + return -1; + + msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive); + oakley_delivm(ivm); + if (msg == NULL) + return -1; + + } else + msg = vdup(msg0); + + /* Safety check */ + if (msg->l < sizeof(*isakmp) + sizeof(*gen)) { + plog(LLV_ERROR, LOCATION, NULL, + "ignore information because the " + "message is way too short - %zu byte(s).\n", + msg->l); + goto end; + } + + isakmp = (struct isakmp *)msg->v; + gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp)); + np = gen->np; + + if (encrypted) { + if (isakmp->np != ISAKMP_NPTYPE_HASH) { + plog(LLV_ERROR, LOCATION, NULL, + "ignore information because the " + "message has no hash payload.\n"); + goto end; + } + + if (iph1->status != PHASE1ST_ESTABLISHED && + iph1->status != PHASE1ST_DYING) { + plog(LLV_ERROR, LOCATION, NULL, + "ignore information because ISAKMP-SA " + "has not been established yet.\n"); + goto end; + } + + /* Safety check */ + if (msg->l < sizeof(*isakmp) + ntohs(gen->len) + sizeof(*nd)) { + plog(LLV_ERROR, LOCATION, NULL, + "ignore information because the " + "message is too short - %zu byte(s).\n", + msg->l); + goto end; + } + + p = (caddr_t) gen + sizeof(struct isakmp_gen); + nd = (struct isakmp_gen *) ((caddr_t) gen + ntohs(gen->len)); + + /* nd length check */ + if (ntohs(nd->len) > msg->l - (sizeof(struct isakmp) + + ntohs(gen->len))) { + plog(LLV_ERROR, LOCATION, NULL, + "too long payload length (broken message?)\n"); + goto end; + } + + if (ntohs(nd->len) < sizeof(*nd)) { + plog(LLV_ERROR, LOCATION, NULL, + "too short payload length (broken message?)\n"); + goto end; + } + + payload = vmalloc(ntohs(nd->len)); + if (payload == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot allocate memory\n"); + goto end; + } + + memcpy(payload->v, (caddr_t) nd, ntohs(nd->len)); + + /* compute HASH */ + hash = oakley_compute_hash1(iph1, isakmp->msgid, payload); + if (hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot compute hash\n"); + + vfree(payload); + goto end; + } + + if (ntohs(gen->len) - sizeof(struct isakmp_gen) != hash->l) { + plog(LLV_ERROR, LOCATION, NULL, + "ignore information due to hash length mismatch\n"); + + vfree(hash); + vfree(payload); + goto end; + } + + if (memcmp(p, hash->v, hash->l) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "ignore information due to hash mismatch\n"); + + vfree(hash); + vfree(payload); + goto end; + } + + plog(LLV_DEBUG, LOCATION, NULL, "hash validated.\n"); + + vfree(hash); + vfree(payload); + } else { + /* make sure the packet was encrypted after the beginning of phase 1. */ + switch (iph1->etype) { + case ISAKMP_ETYPE_AGG: + case ISAKMP_ETYPE_BASE: + case ISAKMP_ETYPE_IDENT: + if ((iph1->side == INITIATOR && iph1->status < PHASE1ST_MSG3SENT) + || (iph1->side == RESPONDER && iph1->status < PHASE1ST_MSG2SENT)) { + break; + } + /*FALLTHRU*/ + default: + plog(LLV_ERROR, LOCATION, iph1->remote, + "%s message must be encrypted\n", + s_isakmp_nptype(np)); + error = 0; + goto end; + } + } + + if (!(pbuf = isakmp_parse(msg))) { + error = -1; + goto end; + } + + error = 0; + for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type; pa++) { + switch (pa->type) { + case ISAKMP_NPTYPE_HASH: + /* Handled above */ + break; + case ISAKMP_NPTYPE_N: + error = isakmp_info_recv_n(iph1, + (struct isakmp_pl_n *)pa->ptr, + msgid, encrypted); + break; + case ISAKMP_NPTYPE_D: + error = isakmp_info_recv_d(iph1, + (struct isakmp_pl_d *)pa->ptr, + msgid, encrypted); + break; + case ISAKMP_NPTYPE_NONCE: + /* XXX to be 6.4.2 ike-01.txt */ + /* XXX IV is to be synchronized. */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore Acknowledged Informational\n"); + break; + default: + /* don't send information, see isakmp_ident_r1() */ + error = 0; + plog(LLV_ERROR, LOCATION, iph1->remote, + "reject the packet, " + "received unexpected payload type %s.\n", + s_isakmp_nptype(gen->np)); + } + if (error < 0) + break; + } + end: + if (msg != NULL) + vfree(msg); + if (pbuf != NULL) + vfree(pbuf); + return error; +} + + +/* + * log unhandled / unallowed Notification payload + */ +int +isakmp_log_notify(iph1, notify, exchange) + struct ph1handle *iph1; + struct isakmp_pl_n *notify; + const char *exchange; +{ + u_int type; + char *nraw, *ndata, *nhex; + size_t l; + + type = ntohs(notify->type); + if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "invalid spi_size in %s notification in %s.\n", + s_isakmp_notify_msg(type), exchange); + return -1; + } + + plog(LLV_ERROR, LOCATION, iph1->remote, + "notification %s received in %s.\n", + s_isakmp_notify_msg(type), exchange); + + nraw = ((char*) notify) + sizeof(*notify) + notify->spi_size; + l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size; + if (l > 0) { + if (type >= ISAKMP_NTYPE_MINERROR && + type <= ISAKMP_NTYPE_MAXERROR) { + ndata = binsanitize(nraw, l); + if (ndata != NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "error message: '%s'.\n", + ndata); + racoon_free(ndata); + } else { + plog(LLV_ERROR, LOCATION, iph1->remote, + "Cannot allocate memory\n"); + } + } else { + nhex = val2str(nraw, l); + if (nhex != NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "notification payload: %s.\n", + nhex); + racoon_free(nhex); + } else { + plog(LLV_ERROR, LOCATION, iph1->remote, + "Cannot allocate memory\n"); + } + } + } + + return 0; +} + + +/* + * handling of Notification payload + */ +static int +isakmp_info_recv_n(iph1, notify, msgid, encrypted) + struct ph1handle *iph1; + struct isakmp_pl_n *notify; + u_int32_t msgid; + int encrypted; +{ + u_int type; + + type = ntohs(notify->type); + switch (type) { + case ISAKMP_NTYPE_CONNECTED: + case ISAKMP_NTYPE_RESPONDER_LIFETIME: + case ISAKMP_NTYPE_REPLAY_STATUS: +#ifdef ENABLE_HYBRID + case ISAKMP_NTYPE_UNITY_HEARTBEAT: +#endif + /* do something */ + break; + case ISAKMP_NTYPE_INITIAL_CONTACT: + if (encrypted) + return isakmp_info_recv_initialcontact(iph1, NULL); + break; +#ifdef ENABLE_DPD + case ISAKMP_NTYPE_R_U_THERE: + if (encrypted) + return isakmp_info_recv_r_u(iph1, + (struct isakmp_pl_ru *)notify, msgid); + break; + case ISAKMP_NTYPE_R_U_THERE_ACK: + if (encrypted) + return isakmp_info_recv_r_u_ack(iph1, + (struct isakmp_pl_ru *)notify, msgid); + break; +#endif + } + + /* If we receive a error notification we should delete the related + * phase1 / phase2 handle, and send an event to racoonctl. + * However, since phase1 error notifications are not encrypted and + * can not be authenticated, it would allow a DoS attack possibility + * to handle them. + * Phase2 error notifications should be encrypted, so we could handle + * those, but it needs implementing (the old code didn't implement + * that either). + * So we are good to just log the messages here. + */ + if (encrypted) + isakmp_log_notify(iph1, notify, "informational exchange"); + else + isakmp_log_notify(iph1, notify, "unencrypted informational exchange"); + + return 0; +} + +/* + * handling of Deletion payload + */ +static int +isakmp_info_recv_d(iph1, delete, msgid, encrypted) + struct ph1handle *iph1; + struct isakmp_pl_d *delete; + u_int32_t msgid; + int encrypted; +{ + int tlen, num_spi; + vchar_t *pbuf; + int protected = 0; + struct ph1handle *del_ph1; + struct ph2handle *iph2; + union { + u_int32_t spi32; + u_int16_t spi16[2]; + } spi; + + if (ntohl(delete->doi) != IPSEC_DOI) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "delete payload with invalid doi:%d.\n", + ntohl(delete->doi)); +#ifdef ENABLE_HYBRID + /* + * At deconnexion time, Cisco VPN client does this + * with a zero DOI. Don't give up in that situation. + */ + if (((iph1->mode_cfg->flags & + ISAKMP_CFG_VENDORID_UNITY) == 0) || (delete->doi != 0)) + return 0; +#else + return 0; +#endif + } + + num_spi = ntohs(delete->num_spi); + tlen = ntohs(delete->h.len) - sizeof(struct isakmp_pl_d); + + if (tlen != num_spi * delete->spi_size) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "deletion payload with invalid length.\n"); + return 0; + } + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "delete payload for protocol %s\n", + s_ipsecdoi_proto(delete->proto_id)); + + if((iph1 == NULL || !iph1->rmconf->weak_phase1_check) && !encrypted) { + plog(LLV_WARNING, LOCATION, iph1->remote, + "Ignoring unencrypted delete payload " + "(check the weak_phase1_check option)\n"); + return 0; + } + + switch (delete->proto_id) { + case IPSECDOI_PROTO_ISAKMP: + if (delete->spi_size != sizeof(isakmp_index)) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "delete payload with strange spi " + "size %d(proto_id:%d)\n", + delete->spi_size, delete->proto_id); + return 0; + } + + del_ph1=getph1byindex((isakmp_index *)(delete + 1)); + if(del_ph1 != NULL){ + + evt_phase1(iph1, EVT_PHASE1_PEER_DELETED, NULL); + sched_cancel(&del_ph1->scr); + + /* + * Delete also IPsec-SAs if rekeying is enabled. + */ + if (ph1_rekey_enabled(del_ph1)) + purge_remote(del_ph1); + else + isakmp_ph1expire(del_ph1); + } + break; + + case IPSECDOI_PROTO_IPSEC_AH: + case IPSECDOI_PROTO_IPSEC_ESP: + if (delete->spi_size != sizeof(u_int32_t)) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "delete payload with strange spi " + "size %d(proto_id:%d)\n", + delete->spi_size, delete->proto_id); + return 0; + } + purge_ipsec_spi(iph1->remote, delete->proto_id, + (u_int32_t *)(delete + 1), num_spi); + break; + + case IPSECDOI_PROTO_IPCOMP: + /* need to handle both 16bit/32bit SPI */ + memset(&spi, 0, sizeof(spi)); + if (delete->spi_size == sizeof(spi.spi16[1])) { + memcpy(&spi.spi16[1], delete + 1, + sizeof(spi.spi16[1])); + } else if (delete->spi_size == sizeof(spi.spi32)) + memcpy(&spi.spi32, delete + 1, sizeof(spi.spi32)); + else { + plog(LLV_ERROR, LOCATION, iph1->remote, + "delete payload with strange spi " + "size %d(proto_id:%d)\n", + delete->spi_size, delete->proto_id); + return 0; + } + purge_ipsec_spi(iph1->remote, delete->proto_id, + &spi.spi32, num_spi); + break; + + default: + plog(LLV_ERROR, LOCATION, iph1->remote, + "deletion message received, " + "invalid proto_id: %d\n", + delete->proto_id); + return 0; + } + + plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n"); + + return 0; +} + +/* + * send Delete payload (for ISAKMP SA) in Informational exchange. + */ +int +isakmp_info_send_d1(iph1) + struct ph1handle *iph1; +{ + struct isakmp_pl_d *d; + vchar_t *payload = NULL; + int tlen; + int error = 0; + + if (iph1->status != PHASE2ST_ESTABLISHED) + return 0; + + /* create delete payload */ + + /* send SPIs of inbound SAs. */ + /* XXX should send outbound SAs's ? */ + tlen = sizeof(*d) + sizeof(isakmp_index); + payload = vmalloc(tlen); + if (payload == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer for payload.\n"); + return errno; + } + + d = (struct isakmp_pl_d *)payload->v; + d->h.np = ISAKMP_NPTYPE_NONE; + d->h.len = htons(tlen); + d->doi = htonl(IPSEC_DOI); + d->proto_id = IPSECDOI_PROTO_ISAKMP; + d->spi_size = sizeof(isakmp_index); + d->num_spi = htons(1); + memcpy(d + 1, &iph1->index, sizeof(isakmp_index)); + + error = isakmp_info_send_common(iph1, payload, + ISAKMP_NPTYPE_D, 0); + vfree(payload); + + return error; +} + +/* + * send Delete payload (for IPsec SA) in Informational exchange, based on + * pfkey msg. It sends always single SPI. + */ +int +isakmp_info_send_d2(iph2) + struct ph2handle *iph2; +{ + struct ph1handle *iph1; + struct saproto *pr; + struct isakmp_pl_d *d; + vchar_t *payload = NULL; + int tlen; + int error = 0; + u_int8_t *spi; + + if (iph2->status != PHASE2ST_ESTABLISHED) + return 0; + + /* + * don't send delete information if there is no phase 1 handler. + * It's nonsensical to negotiate phase 1 to send the information. + */ + iph1 = getph1byaddr(iph2->src, iph2->dst, 0); + if (iph1 == NULL){ + plog(LLV_DEBUG2, LOCATION, NULL, + "No ph1 handler found, could not send DELETE_SA\n"); + return 0; + } + + /* create delete payload */ + for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { + + /* send SPIs of inbound SAs. */ + /* + * XXX should I send outbound SAs's ? + * I send inbound SAs's SPI only at the moment because I can't + * decode any more if peer send encoded packet without aware of + * deletion of SA. Outbound SAs don't come under the situation. + */ + tlen = sizeof(*d) + pr->spisize; + payload = vmalloc(tlen); + if (payload == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer for payload.\n"); + return errno; + } + + d = (struct isakmp_pl_d *)payload->v; + d->h.np = ISAKMP_NPTYPE_NONE; + d->h.len = htons(tlen); + d->doi = htonl(IPSEC_DOI); + d->proto_id = pr->proto_id; + d->spi_size = pr->spisize; + d->num_spi = htons(1); + /* + * XXX SPI bits are left-filled, for use with IPComp. + * we should be switching to variable-length spi field... + */ + spi = (u_int8_t *)&pr->spi; + spi += sizeof(pr->spi); + spi -= pr->spisize; + memcpy(d + 1, spi, pr->spisize); + + error = isakmp_info_send_common(iph1, payload, + ISAKMP_NPTYPE_D, 0); + vfree(payload); + } + + return error; +} + +/* + * send Notification payload (for without ISAKMP SA) in Informational exchange + */ +int +isakmp_info_send_nx(isakmp, remote, local, type, data) + struct isakmp *isakmp; + struct sockaddr *remote, *local; + int type; + vchar_t *data; +{ + struct ph1handle *iph1 = NULL; + vchar_t *payload = NULL; + int tlen; + int error = -1; + struct isakmp_pl_n *n; + int spisiz = 0; /* see below */ + + /* add new entry to isakmp status table. */ + iph1 = newph1(); + if (iph1 == NULL) + return -1; + + memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t)); + isakmp_newcookie((char *)&iph1->index.r_ck, remote, local); + iph1->status = PHASE1ST_START; + iph1->side = INITIATOR; + iph1->version = isakmp->v; + iph1->flags = 0; + iph1->msgid = 0; /* XXX */ +#ifdef ENABLE_HYBRID + if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) + goto end; +#endif +#ifdef ENABLE_FRAG + iph1->frag = 0; + iph1->frag_chain = NULL; +#endif + + /* copy remote address */ + if (copy_ph1addresses(iph1, NULL, remote, local) < 0) + goto end; + + tlen = sizeof(*n) + spisiz; + if (data) + tlen += data->l; + payload = vmalloc(tlen); + if (payload == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + goto end; + } + + n = (struct isakmp_pl_n *)payload->v; + n->h.np = ISAKMP_NPTYPE_NONE; + n->h.len = htons(tlen); + n->doi = htonl(IPSEC_DOI); + n->proto_id = IPSECDOI_KEY_IKE; + n->spi_size = spisiz; + n->type = htons(type); + if (spisiz) + memset(n + 1, 0, spisiz); /* XXX spisiz is always 0 */ + if (data) + memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); + + error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0); + vfree(payload); + + end: + if (iph1 != NULL) + delph1(iph1); + + return error; +} + +/* + * send Notification payload (for ISAKMP SA) in Informational exchange + */ +int +isakmp_info_send_n1(iph1, type, data) + struct ph1handle *iph1; + int type; + vchar_t *data; +{ + vchar_t *payload = NULL; + int tlen; + int error = 0; + struct isakmp_pl_n *n; + int spisiz; + + /* + * note on SPI size: which description is correct? I have chosen + * this to be 0. + * + * RFC2408 3.1, 2nd paragraph says: ISAKMP SA is identified by + * Initiator/Responder cookie and SPI has no meaning, SPI size = 0. + * RFC2408 3.1, first paragraph on page 40: ISAKMP SA is identified + * by cookie and SPI has no meaning, 0 <= SPI size <= 16. + * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16. + */ + if (type == ISAKMP_NTYPE_INITIAL_CONTACT) + spisiz = sizeof(isakmp_index); + else + spisiz = 0; + + tlen = sizeof(*n) + spisiz; + if (data) + tlen += data->l; + payload = vmalloc(tlen); + if (payload == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + return errno; + } + + n = (struct isakmp_pl_n *)payload->v; + n->h.np = ISAKMP_NPTYPE_NONE; + n->h.len = htons(tlen); + n->doi = htonl(iph1->rmconf->doitype); + n->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX to be configurable ? */ + n->spi_size = spisiz; + n->type = htons(type); + if (spisiz) + memcpy(n + 1, &iph1->index, sizeof(isakmp_index)); + if (data) + memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); + + error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags); + vfree(payload); + + return error; +} + +/* + * send Notification payload (for IPsec SA) in Informational exchange + */ +int +isakmp_info_send_n2(iph2, type, data) + struct ph2handle *iph2; + int type; + vchar_t *data; +{ + struct ph1handle *iph1 = iph2->ph1; + vchar_t *payload = NULL; + int tlen; + int error = 0; + struct isakmp_pl_n *n; + struct saproto *pr; + + if (!iph2->approval) + return EINVAL; + + pr = iph2->approval->head; + + /* XXX must be get proper spi */ + tlen = sizeof(*n) + pr->spisize; + if (data) + tlen += data->l; + payload = vmalloc(tlen); + if (payload == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + return errno; + } + + n = (struct isakmp_pl_n *)payload->v; + n->h.np = ISAKMP_NPTYPE_NONE; + n->h.len = htons(tlen); + n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */ + n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/ + n->spi_size = pr->spisize; + n->type = htons(type); + *(u_int32_t *)(n + 1) = pr->spi; + if (data) + memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l); + + iph2->flags |= ISAKMP_FLAG_E; /* XXX Should we do FLAG_A ? */ + error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags); + vfree(payload); + + return error; +} + +/* + * send Information + * When ph1->skeyid_a == NULL, send message without encoding. + */ +int +isakmp_info_send_common(iph1, payload, np, flags) + struct ph1handle *iph1; + vchar_t *payload; + u_int32_t np; + int flags; +{ + struct ph2handle *iph2 = NULL; + vchar_t *hash = NULL; + struct isakmp *isakmp; + struct isakmp_gen *gen; + char *p; + int tlen; + int error = -1; + + /* add new entry to isakmp status table */ + iph2 = newph2(); + if (iph2 == NULL) + goto end; + + iph2->dst = dupsaddr(iph1->remote); + if (iph2->dst == NULL) { + delph2(iph2); + goto end; + } + iph2->src = dupsaddr(iph1->local); + if (iph2->src == NULL) { + delph2(iph2); + goto end; + } + iph2->side = INITIATOR; + iph2->status = PHASE2ST_START; + iph2->msgid = isakmp_newmsgid2(iph1); + + /* get IV and HASH(1) if skeyid_a was generated. */ + if (iph1->skeyid_a != NULL) { + iph2->ivm = oakley_newiv2(iph1, iph2->msgid); + if (iph2->ivm == NULL) { + delph2(iph2); + goto end; + } + + /* generate HASH(1) */ + hash = oakley_compute_hash1(iph1, iph2->msgid, payload); + if (hash == NULL) { + delph2(iph2); + goto end; + } + + /* initialized total buffer length */ + tlen = hash->l; + tlen += sizeof(*gen); + } else { + /* IKE-SA is not established */ + hash = NULL; + + /* initialized total buffer length */ + tlen = 0; + } + if ((flags & ISAKMP_FLAG_A) == 0) + iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E); + else + iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A); + + insph2(iph2); + bindph12(iph1, iph2); + + tlen += sizeof(*isakmp) + payload->l; + + /* create buffer for isakmp payload */ + iph2->sendbuf = vmalloc(tlen); + if (iph2->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + goto err; + } + + /* create isakmp header */ + isakmp = (struct isakmp *)iph2->sendbuf->v; + memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t)); + memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t)); + isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH; + isakmp->v = iph1->version; + isakmp->etype = ISAKMP_ETYPE_INFO; + isakmp->flags = iph2->flags; + memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid)); + isakmp->len = htonl(tlen); + p = (char *)(isakmp + 1); + + /* create HASH payload */ + if (hash != NULL) { + gen = (struct isakmp_gen *)p; + gen->np = np & 0xff; + gen->len = htons(sizeof(*gen) + hash->l); + p += sizeof(*gen); + memcpy(p, hash->v, hash->l); + p += hash->l; + } + + /* add payload */ + memcpy(p, payload->v, payload->l); + p += payload->l; + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1); +#endif + + /* encoding */ + if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) { + vchar_t *tmp; + + tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive, + iph2->ivm->iv); + VPTRINIT(iph2->sendbuf); + if (tmp == NULL) + goto err; + iph2->sendbuf = tmp; + } + + /* HDR*, HASH(1), N */ + if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { + VPTRINIT(iph2->sendbuf); + goto err; + } + + plog(LLV_DEBUG, LOCATION, NULL, + "sendto Information %s.\n", s_isakmp_nptype(np)); + + /* + * don't resend notify message because peer can use Acknowledged + * Informational if peer requires the reply of the notify message. + */ + + /* XXX If Acknowledged Informational required, don't delete ph2handle */ + error = 0; + VPTRINIT(iph2->sendbuf); + goto err; /* XXX */ + +end: + if (hash) + vfree(hash); + return error; + +err: + remph2(iph2); + delph2(iph2); + goto end; +} + +/* + * add a notify payload to buffer by reallocating buffer. + * If buf == NULL, the function only create a notify payload. + * + * XXX Which is SPI to be included, inbound or outbound ? + */ +vchar_t * +isakmp_add_pl_n(buf0, np_p, type, pr, data) + vchar_t *buf0; + u_int8_t **np_p; + int type; + struct saproto *pr; + vchar_t *data; +{ + vchar_t *buf = NULL; + struct isakmp_pl_n *n; + int tlen; + int oldlen = 0; + + if (*np_p) + **np_p = ISAKMP_NPTYPE_N; + + tlen = sizeof(*n) + pr->spisize; + + if (data) + tlen += data->l; + if (buf0) { + oldlen = buf0->l; + buf = vrealloc(buf0, buf0->l + tlen); + } else + buf = vmalloc(tlen); + if (!buf) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get a payload buffer.\n"); + return NULL; + } + + n = (struct isakmp_pl_n *)(buf->v + oldlen); + n->h.np = ISAKMP_NPTYPE_NONE; + n->h.len = htons(tlen); + n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */ + n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/ + n->spi_size = pr->spisize; + n->type = htons(type); + *(u_int32_t *)(n + 1) = pr->spi; /* XXX */ + if (data) + memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l); + + /* save the pointer of next payload type */ + *np_p = &n->h.np; + + return buf; +} + +static void +purge_isakmp_spi(proto, spi, n) + int proto; + isakmp_index *spi; /*network byteorder*/ + size_t n; +{ + struct ph1handle *iph1; + size_t i; + + for (i = 0; i < n; i++) { + iph1 = getph1byindex(&spi[i]); + if (!iph1) + continue; + + plog(LLV_INFO, LOCATION, NULL, + "purged ISAKMP-SA proto_id=%s spi=%s.\n", + s_ipsecdoi_proto(proto), + isakmp_pindex(&spi[i], 0)); + + iph1->status = PHASE1ST_EXPIRED; + isakmp_ph1delete(iph1); + } +} + + + +void +purge_ipsec_spi(dst0, proto, spi, n) + struct sockaddr *dst0; + int proto; + u_int32_t *spi; /*network byteorder*/ + size_t n; +{ + vchar_t *buf = NULL; + struct sadb_msg *msg, *next, *end; + struct sadb_sa *sa; + struct sadb_lifetime *lt; + struct sockaddr *src, *dst; + struct ph2handle *iph2; + u_int64_t created; + size_t i; + caddr_t mhp[SADB_EXT_MAX + 1]; + unsigned num_purged = 0; + + plog(LLV_DEBUG2, LOCATION, NULL, + "purge_ipsec_spi:\n"); + plog(LLV_DEBUG2, LOCATION, NULL, "dst0: %s\n", saddr2str(dst0)); + plog(LLV_DEBUG2, LOCATION, NULL, "SPI: %08X\n", ntohl(spi[0])); + + buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto)); + if (buf == NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey_dump_sadb returned nothing.\n"); + return; + } + + msg = (struct sadb_msg *)buf->v; + end = (struct sadb_msg *)(buf->v + buf->l); + + while (msg < end) { + if ((msg->sadb_msg_len << 3) < sizeof(*msg)) + break; + next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); + if (msg->sadb_msg_type != SADB_DUMP) { + msg = next; + continue; + } + + if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { + plog(LLV_ERROR, LOCATION, NULL, + "pfkey_check (%s)\n", ipsec_strerror()); + msg = next; + continue; + } + + sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]); + if (!sa + || !mhp[SADB_EXT_ADDRESS_SRC] + || !mhp[SADB_EXT_ADDRESS_DST]) { + msg = next; + continue; + } + pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; + if(lt != NULL) + created = lt->sadb_lifetime_addtime; + else + created = 0; + + if (sa->sadb_sa_state != SADB_SASTATE_MATURE + && sa->sadb_sa_state != SADB_SASTATE_DYING) { + msg = next; + continue; + } + + plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src)); + plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst)); + plog(LLV_DEBUG2, LOCATION, NULL, "spi: %u\n", ntohl(sa->sadb_sa_spi)); + + /* XXX n^2 algorithm, inefficient */ + + /* don't delete inbound SAs at the moment */ + /* XXX should we remove SAs with opposite direction as well? */ + if (cmpsaddr(dst0, dst) != CMPSADDR_MATCH) { + msg = next; + continue; + } + + for (i = 0; i < n; i++) { + plog(LLV_DEBUG, LOCATION, NULL, + "check spi(packet)=%u spi(db)=%u.\n", + ntohl(spi[i]), ntohl(sa->sadb_sa_spi)); + if (spi[i] != sa->sadb_sa_spi) + continue; + + pfkey_send_delete(lcconf->sock_pfkey, + msg->sadb_msg_satype, + IPSEC_MODE_ANY, + src, dst, sa->sadb_sa_spi); + + /* + * delete a relative phase 2 handler. + * continue to process if no relative phase 2 handler + * exists. + */ + iph2 = getph2bysaidx(src, dst, proto, spi[i]); + if(iph2 != NULL){ + delete_spd(iph2, created); + remph2(iph2); + delph2(iph2); + } + + plog(LLV_INFO, LOCATION, NULL, + "purged IPsec-SA proto_id=%s spi=%u.\n", + s_ipsecdoi_proto(proto), + ntohl(spi[i])); + num_purged++; + } + + msg = next; + } + + if (buf) + vfree(buf); + + plog(LLV_DEBUG, LOCATION, NULL, "purged %u SAs.\n", num_purged); +} + +/* + * delete all phase2 sa relatived to the destination address + * (except the phase2 within which the INITIAL-CONTACT was received). + * Don't delete Phase 1 handlers on INITIAL-CONTACT, and don't ignore + * an INITIAL-CONTACT if we have contacted the peer. This matches the + * Sun IKE behavior, and makes rekeying work much better when the peer + * restarts. + */ +int +isakmp_info_recv_initialcontact(iph1, protectedph2) + struct ph1handle *iph1; + struct ph2handle *protectedph2; +{ + vchar_t *buf = NULL; + struct sadb_msg *msg, *next, *end; + struct sadb_sa *sa; + struct sockaddr *src, *dst; + caddr_t mhp[SADB_EXT_MAX + 1]; + int proto_id, i; + struct ph2handle *iph2; +#if 0 + char *loc, *rem; +#endif + + plog(LLV_INFO, LOCATION, iph1->remote, "received INITIAL-CONTACT\n"); + + if (f_local) + return 0; + +#if 0 + loc = racoon_strdup(saddrwop2str(iph1->local)); + rem = racoon_strdup(saddrwop2str(iph1->remote)); + STRDUP_FATAL(loc); + STRDUP_FATAL(rem); + + /* + * Purge all IPSEC-SAs for the peer. We can do this + * the easy way (using a PF_KEY SADB_DELETE extension) + * or we can do it the hard way. + */ + for (i = 0; i < pfkey_nsatypes; i++) { + proto_id = pfkey2ipsecdoi_proto(pfkey_satypes[i].ps_satype); + + plog(LLV_INFO, LOCATION, NULL, + "purging %s SAs for %s -> %s\n", + pfkey_satypes[i].ps_name, loc, rem); + if (pfkey_send_delete_all(lcconf->sock_pfkey, + pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY, + iph1->local, iph1->remote) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "delete_all %s -> %s failed for %s (%s)\n", + loc, rem, + pfkey_satypes[i].ps_name, ipsec_strerror()); + goto the_hard_way; + } + + deleteallph2(iph1->local, iph1->remote, proto_id); + + plog(LLV_INFO, LOCATION, NULL, + "purging %s SAs for %s -> %s\n", + pfkey_satypes[i].ps_name, rem, loc); + if (pfkey_send_delete_all(lcconf->sock_pfkey, + pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY, + iph1->remote, iph1->local) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "delete_all %s -> %s failed for %s (%s)\n", + rem, loc, + pfkey_satypes[i].ps_name, ipsec_strerror()); + goto the_hard_way; + } + + deleteallph2(iph1->remote, iph1->local, proto_id); + } + + racoon_free(loc); + racoon_free(rem); + return 0; + + the_hard_way: + racoon_free(loc); + racoon_free(rem); +#endif + + buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC); + if (buf == NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey_dump_sadb returned nothing.\n"); + return 0; + } + + msg = (struct sadb_msg *)buf->v; + end = (struct sadb_msg *)(buf->v + buf->l); + + for (; msg < end; msg = next) { + if ((msg->sadb_msg_len << 3) < sizeof(*msg)) + break; + + next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); + if (msg->sadb_msg_type != SADB_DUMP) + continue; + + if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { + plog(LLV_ERROR, LOCATION, NULL, + "pfkey_check (%s)\n", ipsec_strerror()); + continue; + } + + if (mhp[SADB_EXT_SA] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL) + continue; + + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; + pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + + if (sa->sadb_sa_state != SADB_SASTATE_MATURE + && sa->sadb_sa_state != SADB_SASTATE_DYING) + continue; + + /* + * RFC2407 4.6.3.3 INITIAL-CONTACT is the message that + * announces the sender of the message was rebooted. + * it is interpreted to delete all SAs which source address + * is the sender of the message. + * racoon only deletes SA which is matched both the + * source address and the destination accress. + */ + + /* + * Check that the IP and port match. But this is not optimal, + * since NAT-T can make the peer have multiple different + * ports. Correct thing to do is delete all entries with + * same identity. -TT + */ + if ((cmpsaddr(iph1->local, src) != CMPSADDR_MATCH || + cmpsaddr(iph1->remote, dst) != CMPSADDR_MATCH) && + (cmpsaddr(iph1->local, dst) != CMPSADDR_MATCH || + cmpsaddr(iph1->remote, src) != CMPSADDR_MATCH)) + continue; + + /* + * Make sure this is an SATYPE that we manage. + * This is gross; too bad we couldn't do it the + * easy way. + */ + for (i = 0; i < pfkey_nsatypes; i++) { + if (pfkey_satypes[i].ps_satype == + msg->sadb_msg_satype) + break; + } + if (i == pfkey_nsatypes) + continue; + + plog(LLV_INFO, LOCATION, NULL, + "purging spi=%u.\n", ntohl(sa->sadb_sa_spi)); + pfkey_send_delete(lcconf->sock_pfkey, + msg->sadb_msg_satype, + IPSEC_MODE_ANY, src, dst, sa->sadb_sa_spi); + + /* + * delete a relative phase 2 handler. + * continue to process if no relative phase 2 handler + * exists. + */ + proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); + iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); + if (iph2 && iph2 != protectedph2) { + delete_spd(iph2, 0); + remph2(iph2); + delph2(iph2); + } + } + + vfree(buf); + return 0; +} + + +#ifdef ENABLE_DPD +static int +isakmp_info_recv_r_u (iph1, ru, msgid) + struct ph1handle *iph1; + struct isakmp_pl_ru *ru; + u_int32_t msgid; +{ + struct isakmp_pl_ru *ru_ack; + vchar_t *payload = NULL; + int tlen; + int error = 0; + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "DPD R-U-There received\n"); + + /* XXX should compare cookies with iph1->index? + Or is this already done by calling function? */ + tlen = sizeof(*ru_ack); + payload = vmalloc(tlen); + if (payload == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + return errno; + } + + ru_ack = (struct isakmp_pl_ru *)payload->v; + ru_ack->h.np = ISAKMP_NPTYPE_NONE; + ru_ack->h.len = htons(tlen); + ru_ack->doi = htonl(IPSEC_DOI); + ru_ack->type = htons(ISAKMP_NTYPE_R_U_THERE_ACK); + ru_ack->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ? */ + ru_ack->spi_size = sizeof(isakmp_index); + memcpy(ru_ack->i_ck, ru->i_ck, sizeof(cookie_t)); + memcpy(ru_ack->r_ck, ru->r_ck, sizeof(cookie_t)); + ru_ack->data = ru->data; + + /* XXX Should we do FLAG_A ? */ + error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, + ISAKMP_FLAG_E); + vfree(payload); + + plog(LLV_DEBUG, LOCATION, NULL, "received a valid R-U-THERE, ACK sent\n"); + + /* Should we mark tunnel as active ? */ + return error; +} + +static int +isakmp_info_recv_r_u_ack (iph1, ru, msgid) + struct ph1handle *iph1; + struct isakmp_pl_ru *ru; + u_int32_t msgid; +{ + u_int32_t seq; + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "DPD R-U-There-Ack received\n"); + + seq = ntohl(ru->data); + if (seq <= iph1->dpd_last_ack || seq > iph1->dpd_seq) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "Wrong DPD sequence number (%d; last_ack=%d, seq=%d).\n", + seq, iph1->dpd_last_ack, iph1->dpd_seq); + return 0; + } + + /* accept cookies in original or reversed order */ + if ((memcmp(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)) || + memcmp(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t))) && + (memcmp(ru->r_ck, iph1->index.i_ck, sizeof(cookie_t)) || + memcmp(ru->i_ck, iph1->index.r_ck, sizeof(cookie_t)))) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "Cookie mismatch in DPD ACK!.\n"); + return 0; + } + + iph1->dpd_fails = 0; + iph1->dpd_last_ack = seq; + sched_cancel(&iph1->dpd_r_u); + isakmp_sched_r_u(iph1, 0); + + plog(LLV_DEBUG, LOCATION, iph1->remote, "received an R-U-THERE-ACK\n"); + + return 0; +} + + + + +/* + * send DPD R-U-THERE payload in Informational exchange. + */ +static void +isakmp_info_send_r_u(sc) + struct sched *sc; +{ + struct ph1handle *iph1 = container_of(sc, struct ph1handle, dpd_r_u); + + /* create R-U-THERE payload */ + struct isakmp_pl_ru *ru; + vchar_t *payload = NULL; + int tlen; + int error = 0; + + plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring....\n"); + + if (iph1->status == PHASE1ST_EXPIRED) { + /* This can happen after removing tunnels from the + * config file and then reloading. + * Such iph1 have rmconf=NULL, so return before the if + * block below. + */ + return; + } + + if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) { + + plog(LLV_INFO, LOCATION, iph1->remote, + "DPD: remote (ISAKMP-SA spi=%s) seems to be dead.\n", + isakmp_pindex(&iph1->index, 0)); + + script_hook(iph1, SCRIPT_PHASE1_DEAD); + evt_phase1(iph1, EVT_PHASE1_DPD_TIMEOUT, NULL); + purge_remote(iph1); + + /* Do not reschedule here: phase1 is deleted, + * DPD will be reactivated when a new ph1 will be negociated + */ + return; + } + + /* TODO: check recent activity to avoid useless sends... */ + + tlen = sizeof(*ru); + payload = vmalloc(tlen); + if (payload == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer for payload.\n"); + return; + } + ru = (struct isakmp_pl_ru *)payload->v; + ru->h.np = ISAKMP_NPTYPE_NONE; + ru->h.len = htons(tlen); + ru->doi = htonl(IPSEC_DOI); + ru->type = htons(ISAKMP_NTYPE_R_U_THERE); + ru->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ?*/ + ru->spi_size = sizeof(isakmp_index); + + memcpy(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)); + memcpy(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t)); + + if (iph1->dpd_seq == 0) { + /* generate a random seq which is not too big */ + iph1->dpd_seq = iph1->dpd_last_ack = rand() & 0x0fff; + } + + iph1->dpd_seq++; + iph1->dpd_fails++; + ru->data = htonl(iph1->dpd_seq); + + error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0); + vfree(payload); + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "DPD R-U-There sent (%d)\n", error); + + /* Reschedule the r_u_there with a short delay, + * will be deleted/rescheduled if ACK received before */ + isakmp_sched_r_u(iph1, 1); + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry); +} + +/* Schedule a new R-U-THERE */ +int +isakmp_sched_r_u(iph1, retry) + struct ph1handle *iph1; + int retry; +{ + if(iph1 == NULL || + iph1->rmconf == NULL) + return 1; + + + if(iph1->dpd_support == 0 || + iph1->rmconf->dpd_interval == 0) + return 0; + + if(retry) + sched_schedule(&iph1->dpd_r_u, iph1->rmconf->dpd_retry, + isakmp_info_send_r_u); + else + sched_schedule(&iph1->dpd_r_u, iph1->rmconf->dpd_interval, + isakmp_info_send_r_u); + + return 0; +} +#endif diff --git a/ipsec-tools/src/racoon/isakmp_inf.h b/ipsec-tools/src/racoon/isakmp_inf.h new file mode 100644 index 00000000..40cdc02d --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_inf.h @@ -0,0 +1,61 @@ +/* $NetBSD: isakmp_inf.h,v 1.5 2008/07/14 05:40:13 tteras Exp $ */ + +/* Id: isakmp_inf.h,v 1.6 2005/05/07 14:15:59 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ISAKMP_INF_H +#define _ISAKMP_INF_H + +struct saproto; +extern int isakmp_info_recv __P((struct ph1handle *, vchar_t *)); +extern int isakmp_info_send_d1 __P((struct ph1handle *)); +extern int isakmp_info_send_d2 __P((struct ph2handle *)); +extern int isakmp_info_send_nx __P((struct isakmp *, + struct sockaddr *, struct sockaddr *, int, vchar_t *)); +extern int isakmp_info_send_n1 __P((struct ph1handle *, int, vchar_t *)); +extern int isakmp_info_send_n2 __P((struct ph2handle *, int, vchar_t *)); +extern int isakmp_info_send_common __P((struct ph1handle *, + vchar_t *, u_int32_t, int)); + +extern vchar_t * isakmp_add_pl_n __P((vchar_t *, u_int8_t **, int, + struct saproto *, vchar_t *)); + +extern int isakmp_log_notify __P((struct ph1handle *, struct isakmp_pl_n *, const char *exchange)); +extern int isakmp_info_recv_initialcontact __P((struct ph1handle *, struct ph2handle *)); + +#ifdef ENABLE_DPD +extern int isakmp_sched_r_u __P((struct ph1handle *, int)); +#endif + +extern void purge_ipsec_spi __P((struct sockaddr *, int, u_int32_t *, size_t)); +extern int tunnel_mode_prop __P((struct saprop *)); + +#endif /* _ISAKMP_INF_H */ diff --git a/ipsec-tools/src/racoon/isakmp_newg.c b/ipsec-tools/src/racoon/isakmp_newg.c new file mode 100644 index 00000000..211e632e --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_newg.c @@ -0,0 +1,232 @@ +/* $NetBSD: isakmp_newg.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* $KAME: isakmp_newg.c,v 1.10 2002/09/27 05:55:52 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "debug.h" + +#include "schedule.h" +#include "cfparse_proto.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "isakmp_newg.h" +#include "oakley.h" +#include "ipsec_doi.h" +#include "crypto_openssl.h" +#include "handler.h" +#include "pfkey.h" +#include "admin.h" +#include "str2val.h" +#include "vendorid.h" + +/* + * New group mode as responder + */ +int +isakmp_newgroup_r(iph1, msg) + struct ph1handle *iph1; + vchar_t *msg; +{ +#if 0 + struct isakmp *isakmp = (struct isakmp *)msg->v; + struct isakmp_pl_hash *hash = NULL; + struct isakmp_pl_sa *sa = NULL; + int error = -1; + vchar_t *buf; + struct oakley_sa *osa; + int len; + + /* validate the type of next payload */ + /* + * ISAKMP_ETYPE_NEWGRP, + * ISAKMP_NPTYPE_HASH, (ISAKMP_NPTYPE_VID), ISAKMP_NPTYPE_SA, + * ISAKMP_NPTYPE_NONE + */ + { + vchar_t *pbuf = NULL; + struct isakmp_parse_t *pa; + + if ((pbuf = isakmp_parse(msg)) == NULL) + goto end; + + for (pa = (struct isakmp_parse_t *)pbuf->v; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_HASH: + if (hash) { + isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); + plog(LLV_ERROR, LOCATION, iph1->remote, + "received multiple payload type %d.\n", + pa->type); + vfree(pbuf); + goto end; + } + hash = (struct isakmp_pl_hash *)pa->ptr; + break; + case ISAKMP_NPTYPE_SA: + if (sa) { + isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); + plog(LLV_ERROR, LOCATION, iph1->remote, + "received multiple payload type %d.\n", + pa->type); + vfree(pbuf); + goto end; + } + sa = (struct isakmp_pl_sa *)pa->ptr; + break; + case ISAKMP_NPTYPE_VID: + (void)check_vendorid(pa->ptr); + break; + default: + isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + vfree(pbuf); + goto end; + } + } + vfree(pbuf); + + if (!hash || !sa) { + isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); + plog(LLV_ERROR, LOCATION, iph1->remote, + "no HASH, or no SA payload.\n"); + goto end; + } + } + + /* validate HASH */ + { + char *r_hash; + vchar_t *my_hash = NULL; + int result; + + plog(LLV_DEBUG, LOCATION, NULL, "validate HASH\n"); + + len = sizeof(isakmp->msgid) + ntohs(sa->h.len); + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + goto end; + } + memcpy(buf->v, &isakmp->msgid, sizeof(isakmp->msgid)); + memcpy(buf->v + sizeof(isakmp->msgid), sa, ntohs(sa->h.len)); + + plog(LLV_DEBUG, LOCATION, NULL, "hash source\n"); + plogdump(LLV_DEBUG, buf->v, buf->l); + + my_hash = isakmp_prf(iph1->skeyid_a, buf, iph1); + vfree(buf); + if (my_hash == NULL) + goto end; + + plog(LLV_DEBUG, LOCATION, NULL, "hash result\n"); + plogdump(LLV_DEBUG, my_hash->v, my_hash->l); + + r_hash = (char *)hash + sizeof(*hash); + + plog(LLV_DEBUG, LOCATION, NULL, "original hash\n")); + plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash))); + + result = memcmp(my_hash->v, r_hash, my_hash->l); + vfree(my_hash); + + if (result) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "HASH mismatch.\n"); + isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_HASH_INFORMATION, NULL); + goto end; + } + } + + /* check SA payload and get new one for use */ + buf = ipsecdoi_get_proposal((struct ipsecdoi_sa *)sa, + OAKLEY_NEWGROUP_MODE); + if (buf == NULL) { + isakmp_info_send_n1(iph1, ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED, NULL); + goto end; + } + + /* save sa parameters */ + osa = ipsecdoi_get_oakley(buf); + if (osa == NULL) { + isakmp_info_send_n1(iph1, ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED, NULL); + goto end; + } + vfree(buf); + + switch (osa->dhgrp) { + case OAKLEY_ATTR_GRP_DESC_MODP768: + case OAKLEY_ATTR_GRP_DESC_MODP1024: + case OAKLEY_ATTR_GRP_DESC_MODP1536: + /*XXX*/ + default: + isakmp_info_send_n1(iph1, ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED, NULL); + plog(LLV_ERROR, LOCATION, NULL, + "dh group %d isn't supported.\n", osa->dhgrp); + goto end; + } + + plog(LLV_INFO, LOCATION, iph1->remote, + "got new dh group %s.\n", isakmp_pindex(&iph1->index, 0)); + + error = 0; + +end: + if (error) { + if (iph1 != NULL) + (void)isakmp_free_ph1(iph1); + } + return error; +#endif + return 0; +} + diff --git a/ipsec-tools/src/racoon/isakmp_newg.h b/ipsec-tools/src/racoon/isakmp_newg.h new file mode 100644 index 00000000..1562c41e --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_newg.h @@ -0,0 +1,39 @@ +/* $NetBSD: isakmp_newg.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: isakmp_newg.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ISAKMP_NEWG_H +#define _ISAKMP_NEWG_H + +extern int isakmp_newgroup_r __P((struct ph1handle *, vchar_t *)); + +#endif /* _ISAKMP_NEWG_H */ diff --git a/ipsec-tools/src/racoon/isakmp_quick.c b/ipsec-tools/src/racoon/isakmp_quick.c new file mode 100644 index 00000000..fa957ebc --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_quick.c @@ -0,0 +1,2605 @@ +/* $NetBSD: isakmp_quick.c,v 1.29 2011/03/14 17:18:13 tteras Exp $ */ + +/* Id: isakmp_quick.c,v 1.29 2006/08/22 18:17:17 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include PATH_IPSEC_H + +#include "var.h" +#include "vmbuf.h" +#include "schedule.h" +#include "misc.h" +#include "plog.h" +#include "debug.h" + +#include "localconf.h" +#include "remoteconf.h" +#include "handler.h" +#include "policy.h" +#include "proposal.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "isakmp_inf.h" +#include "isakmp_quick.h" +#include "oakley.h" +#include "ipsec_doi.h" +#include "crypto_openssl.h" +#include "pfkey.h" +#include "policy.h" +#include "algorithm.h" +#include "sockmisc.h" +#include "proposal.h" +#include "sainfo.h" +#include "admin.h" +#include "strnames.h" + +#ifdef ENABLE_HYBRID +#include +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif + +#ifdef ENABLE_NATT +#include "nattraversal.h" +#endif + +/* quick mode */ +static vchar_t *quick_ir1mx __P((struct ph2handle *, vchar_t *, vchar_t *)); +static int get_sainfo_r __P((struct ph2handle *)); +static int get_proposal_r __P((struct ph2handle *)); +static int ph2_recv_n __P((struct ph2handle *, struct isakmp_gen *)); +static void quick_timeover_stub __P((struct sched *)); +static void quick_timeover __P((struct ph2handle *)); + +/* called from scheduler */ +static void +quick_timeover_stub(p) + struct sched *p; +{ + quick_timeover(container_of(p, struct ph2handle, sce)); +} + +static void +quick_timeover(iph2) + struct ph2handle *iph2; +{ + plog(LLV_ERROR, LOCATION, NULL, + "%s give up to get IPsec-SA due to time up to wait.\n", + saddrwop2str(iph2->dst)); + + /* If initiator side, send error to kernel by SADB_ACQUIRE. */ + if (iph2->side == INITIATOR) + pk_sendeacquire(iph2); + + remph2(iph2); + delph2(iph2); +} + +/* %%% + * Quick Mode + */ +/* + * begin Quick Mode as initiator. send pfkey getspi message to kernel. + */ +int +quick_i1prep(iph2, msg) + struct ph2handle *iph2; + vchar_t *msg; /* must be null pointer */ +{ + int error = ISAKMP_INTERNAL_ERROR; + + /* validity check */ + if (iph2->status != PHASE2ST_STATUS2) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph2->status); + goto end; + } + + iph2->msgid = isakmp_newmsgid2(iph2->ph1); + iph2->ivm = oakley_newiv2(iph2->ph1, iph2->msgid); + if (iph2->ivm == NULL) + return 0; + + iph2->status = PHASE2ST_GETSPISENT; + + /* don't anything if local test mode. */ + if (f_local) { + error = 0; + goto end; + } + + /* send getspi message */ + if (pk_sendgetspi(iph2) < 0) + goto end; + + plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n"); + + sched_schedule(&iph2->sce, lcconf->wait_ph2complete, + quick_timeover_stub); + + error = 0; + +end: + return error; +} + +/* + * send to responder + * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ] + */ +int +quick_i1send(iph2, msg) + struct ph2handle *iph2; + vchar_t *msg; /* must be null pointer */ +{ + vchar_t *body = NULL; + vchar_t *hash = NULL; + struct isakmp_gen *gen; + char *p; + int tlen; + int error = ISAKMP_INTERNAL_ERROR; + int natoa = ISAKMP_NPTYPE_NONE; + int pfsgroup, idci, idcr; + int np; + struct ipsecdoi_id_b *id, *id_p; +#ifdef ENABLE_NATT + vchar_t *nat_oai = NULL; + vchar_t *nat_oar = NULL; +#endif + + /* validity check */ + if (msg != NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "msg has to be NULL in this function.\n"); + goto end; + } + if (iph2->status != PHASE2ST_GETSPIDONE) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph2->status); + goto end; + } + + /* create SA payload for my proposal */ + if (ipsecdoi_setph2proposal(iph2) < 0) + goto end; + + /* generate NONCE value */ + iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size); + if (iph2->nonce == NULL) + goto end; + + /* + * DH value calculation is kicked out into cfparse.y. + * because pfs group can not be negotiated, it's only to be checked + * acceptable. + */ + /* generate KE value if need */ + pfsgroup = iph2->proposal->pfs_group; + if (pfsgroup) { + /* DH group settting if PFS is required. */ + if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set DH value.\n"); + goto end; + } + if (oakley_dh_generate(iph2->pfsgrp, + &iph2->dhpub, &iph2->dhpriv) < 0) { + goto end; + } + } + + /* generate ID value */ + if (ipsecdoi_setid2(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get ID.\n"); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "IDci:\n"); + plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l); + plog(LLV_DEBUG, LOCATION, NULL, "IDcr:\n"); + plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l); + + /* + * we do not attach IDci nor IDcr, under the following condition: + * - all proposals are transport mode + * - no MIP6 or proxy + * - id payload suggests to encrypt all the traffic (no specific + * protocol type) + * - SA endpoints and IKE addresses for the nego are the same + * (iph2->src/dst) + */ + id = (struct ipsecdoi_id_b *)iph2->id->v; + id_p = (struct ipsecdoi_id_b *)iph2->id_p->v; + if (id->proto_id == 0 && + id_p->proto_id == 0 && + iph2->ph1->rmconf->support_proxy == 0 && + iph2->sa_src == NULL && iph2->sa_dst == NULL && + ipsecdoi_transportmode(iph2->proposal)) { + idci = idcr = 0; + } else + idci = idcr = 1; + +#ifdef ENABLE_NATT + /* + * RFC3947 5.2. if we propose UDP-Encapsulated-Transport + * we should send NAT-OA + */ + if (ipsecdoi_transportmode(iph2->proposal) + && (iph2->ph1->natt_flags & NAT_DETECTED)) { + natoa = iph2->ph1->natt_options->payload_nat_oa; + + nat_oai = ipsecdoi_sockaddr2id(iph2->src, + IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY); + nat_oar = ipsecdoi_sockaddr2id(iph2->dst, + IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY); + + if (nat_oai == NULL || nat_oar == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate NAT-OA payload.\n"); + goto end; + } + + plog(LLV_DEBUG, LOCATION, NULL, "NAT-OAi:\n"); + plogdump(LLV_DEBUG, nat_oai->v, nat_oai->l); + plog(LLV_DEBUG, LOCATION, NULL, "NAT-OAr:\n"); + plogdump(LLV_DEBUG, nat_oar->v, nat_oar->l); + } else { + natoa = ISAKMP_NPTYPE_NONE; + } +#endif + + /* create SA;NONCE payload, and KE if need, and IDii, IDir. */ + tlen = + sizeof(*gen) + iph2->sa->l + + sizeof(*gen) + iph2->nonce->l; + if (pfsgroup) + tlen += (sizeof(*gen) + iph2->dhpub->l); + if (idci) + tlen += sizeof(*gen) + iph2->id->l; + if (idcr) + tlen += sizeof(*gen) + iph2->id_p->l; +#ifdef ENABLE_NATT + if (natoa != ISAKMP_NPTYPE_NONE) + tlen += 2 * sizeof(*gen) + nat_oai->l + nat_oar->l; +#endif + + body = vmalloc(tlen); + if (body == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + goto end; + } + + p = body->v; + + /* add SA payload */ + p = set_isakmp_payload(p, iph2->sa, ISAKMP_NPTYPE_NONCE); + + /* add NONCE payload */ + if (pfsgroup) + np = ISAKMP_NPTYPE_KE; + else if (idci || idcr) + np = ISAKMP_NPTYPE_ID; + else + np = natoa; + p = set_isakmp_payload(p, iph2->nonce, np); + + /* add KE payload if need. */ + np = (idci || idcr) ? ISAKMP_NPTYPE_ID : natoa; + if (pfsgroup) + p = set_isakmp_payload(p, iph2->dhpub, np); + + /* IDci */ + np = (idcr) ? ISAKMP_NPTYPE_ID : natoa; + if (idci) + p = set_isakmp_payload(p, iph2->id, np); + + /* IDcr */ + if (idcr) + p = set_isakmp_payload(p, iph2->id_p, natoa); + +#ifdef ENABLE_NATT + /* NAT-OA */ + if (natoa != ISAKMP_NPTYPE_NONE) { + p = set_isakmp_payload(p, nat_oai, natoa); + p = set_isakmp_payload(p, nat_oar, ISAKMP_NPTYPE_NONE); + } +#endif + + /* generate HASH(1) */ + hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body); + if (hash == NULL) + goto end; + + /* send isakmp payload */ + iph2->sendbuf = quick_ir1mx(iph2, body, hash); + if (iph2->sendbuf == NULL) + goto end; + + /* send the packet, add to the schedule to resend */ + if (isakmp_ph2send(iph2) == -1) + goto end; + + /* change status of isakmp status entry */ + iph2->status = PHASE2ST_MSG1SENT; + + error = 0; + +end: + if (body != NULL) + vfree(body); + if (hash != NULL) + vfree(hash); +#ifdef ENABLE_NATT + if (nat_oai != NULL) + vfree(nat_oai); + if (nat_oar != NULL) + vfree(nat_oar); +#endif + + return error; +} + +/* + * receive from responder + * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ] + */ +int +quick_i2recv(iph2, msg0) + struct ph2handle *iph2; + vchar_t *msg0; +{ + vchar_t *msg = NULL; + vchar_t *hbuf = NULL; /* for hash computing. */ + vchar_t *pbuf = NULL; /* for payload parsing */ + vchar_t *idci = NULL; + vchar_t *idcr = NULL; + struct isakmp_parse_t *pa; + struct isakmp *isakmp = (struct isakmp *)msg0->v; + struct isakmp_pl_hash *hash = NULL; + char *p; + int tlen; + int error = ISAKMP_INTERNAL_ERROR; + + /* validity check */ + if (iph2->status != PHASE2ST_MSG1SENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph2->status); + goto end; + } + + /* decrypt packet */ + if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "Packet wasn't encrypted.\n"); + goto end; + } + msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); + if (msg == NULL) + goto end; + + /* create buffer for validating HASH(2) */ + /* + * ordering rule: + * 1. the first one must be HASH + * 2. the second one must be SA (added in isakmp-oakley-05!) + * 3. two IDs must be considered as IDci, then IDcr + */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + pa = (struct isakmp_parse_t *)pbuf->v; + + /* HASH payload is fixed postion */ + if (pa->type != ISAKMP_NPTYPE_HASH) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "received invalid next payload type %d, " + "expecting %d.\n", + pa->type, ISAKMP_NPTYPE_HASH); + goto end; + } + hash = (struct isakmp_pl_hash *)pa->ptr; + pa++; + + /* + * this restriction was introduced in isakmp-oakley-05. + * we do not check this for backward compatibility. + * TODO: command line/config file option to enable/disable this code + */ + /* HASH payload is fixed postion */ + if (pa->type != ISAKMP_NPTYPE_SA) { + plog(LLV_WARNING, LOCATION, iph2->ph1->remote, + "received invalid next payload type %d, " + "expecting %d.\n", + pa->type, ISAKMP_NPTYPE_HASH); + } + + /* allocate buffer for computing HASH(2) */ + tlen = iph2->nonce->l + + ntohl(isakmp->len) - sizeof(*isakmp); + hbuf = vmalloc(tlen); + if (hbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get hash buffer.\n"); + goto end; + } + p = hbuf->v + iph2->nonce->l; /* retain the space for Ni_b */ + + /* + * parse the payloads. + * copy non-HASH payloads into hbuf, so that we can validate HASH. + */ + iph2->sa_ret = NULL; + tlen = 0; /* count payload length except of HASH payload. */ + for (; pa->type; pa++) { + + /* copy to buffer for HASH */ + /* Don't modify the payload */ + memcpy(p, pa->ptr, pa->len); + + switch (pa->type) { + case ISAKMP_NPTYPE_SA: + if (iph2->sa_ret != NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Ignored, multiple SA " + "isn't supported.\n"); + break; + } + if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "duplicate ISAKMP_NPTYPE_SA.\n"); + goto end; + } + break; + + case ISAKMP_NPTYPE_NONCE: + if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "duplicate ISAKMP_NPTYPE_NONCE.\n"); + goto end; + } + break; + + case ISAKMP_NPTYPE_KE: + if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "duplicate ISAKMP_NPTYPE_KE.\n"); + goto end; + } + break; + + case ISAKMP_NPTYPE_ID: + if (idci == NULL) { + if (isakmp_p2ph(&idci, pa->ptr) < 0) + goto end; + } else if (idcr == NULL) { + if (isakmp_p2ph(&idcr, pa->ptr) < 0) + goto end; + } else { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "too many ISAKMP_NPTYPE_ID payloads.\n"); + goto end; + } + break; + + case ISAKMP_NPTYPE_N: + ph2_recv_n(iph2, pa->ptr); + break; + +#ifdef ENABLE_NATT + case ISAKMP_NPTYPE_NATOA_DRAFT: + case ISAKMP_NPTYPE_NATOA_RFC: + { + struct sockaddr_storage addr; + struct sockaddr *daddr; + u_int8_t prefix; + u_int16_t ul_proto; + vchar_t *vp = NULL; + + if (isakmp_p2ph(&vp, pa->ptr) < 0) + goto end; + + error = ipsecdoi_id2sockaddr(vp, + (struct sockaddr *) &addr, + &prefix, &ul_proto); + + vfree(vp); + + if (error) + goto end; + + daddr = dupsaddr((struct sockaddr *) &addr); + if (daddr == NULL) + goto end; + + if (iph2->natoa_src == NULL) + iph2->natoa_src = daddr; + else if (iph2->natoa_dst == NULL) + iph2->natoa_dst = daddr; + else { + racoon_free(daddr); + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "too many ISAKMP_NPTYPE_NATOA payloads.\n"); + goto end; + } + } + break; +#endif + + default: + /* don't send information, see ident_r1recv() */ + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + + p += pa->len; + + /* compute true length of payload. */ + tlen += pa->len; + } + + /* payload existency check */ + if (hash == NULL || iph2->sa_ret == NULL || iph2->nonce_p == NULL) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "few isakmp message received.\n"); + goto end; + } + + /* identity check */ + if (idci != NULL) { + struct sockaddr_storage proposed_addr, got_addr; + u_int8_t proposed_prefix, got_prefix; + u_int16_t proposed_ulproto, got_ulproto; + + error = ipsecdoi_id2sockaddr(iph2->id, + (struct sockaddr *) &proposed_addr, + &proposed_prefix, &proposed_ulproto); + if (error) + goto end; + + error = ipsecdoi_id2sockaddr(idci, + (struct sockaddr *) &got_addr, + &got_prefix, &got_ulproto); + if (error) + goto end; + + if (proposed_prefix != got_prefix + || proposed_ulproto != got_ulproto) { + plog(LLV_DEBUG, LOCATION, NULL, + "IDci prefix/ulproto does not match proposal.\n"); + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED; + goto end; + } +#ifdef ENABLE_NATT + set_port(iph2->natoa_src, + extract_port((struct sockaddr *) &proposed_addr)); +#endif + + if (cmpsaddr((struct sockaddr *) &proposed_addr, + (struct sockaddr *) &got_addr) == CMPSADDR_MATCH) { + plog(LLV_DEBUG, LOCATION, NULL, + "IDci matches proposal.\n"); +#ifdef ENABLE_NATT + } else if (iph2->natoa_src != NULL + && cmpsaddr(iph2->natoa_src, + (struct sockaddr *) &got_addr) == 0) { + plog(LLV_DEBUG, LOCATION, NULL, + "IDci matches NAT-OAi.\n"); +#endif + } else { + plog(LLV_ERROR, LOCATION, NULL, + "mismatched IDci was returned.\n"); + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED; + goto end; + } + } + if (idcr != NULL) { + struct sockaddr_storage proposed_addr, got_addr; + u_int8_t proposed_prefix, got_prefix; + u_int16_t proposed_ulproto, got_ulproto; + + error = ipsecdoi_id2sockaddr(iph2->id_p, + (struct sockaddr *) &proposed_addr, + &proposed_prefix, &proposed_ulproto); + if (error) + goto end; + + error = ipsecdoi_id2sockaddr(idcr, + (struct sockaddr *) &got_addr, + &got_prefix, &got_ulproto); + if (error) + goto end; + + if (proposed_prefix != got_prefix + || proposed_ulproto != got_ulproto) { + plog(LLV_DEBUG, LOCATION, NULL, + "IDcr prefix/ulproto does not match proposal.\n"); + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED; + goto end; + } + +#ifdef ENABLE_NATT + set_port(iph2->natoa_dst, + extract_port((struct sockaddr *) &proposed_addr)); +#endif + + if (cmpsaddr((struct sockaddr *) &proposed_addr, + (struct sockaddr *) &got_addr) == CMPSADDR_MATCH) { + plog(LLV_DEBUG, LOCATION, NULL, + "IDcr matches proposal.\n"); +#ifdef ENABLE_NATT + } else if (iph2->natoa_dst != NULL + && cmpsaddr(iph2->natoa_dst, + (struct sockaddr *) &got_addr) == CMPSADDR_MATCH) { + plog(LLV_DEBUG, LOCATION, NULL, + "IDcr matches NAT-OAr.\n"); +#endif + } else { + plog(LLV_ERROR, LOCATION, NULL, + "mismatched IDcr was returned.\n"); + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED; + goto end; + } + } + + /* Fixed buffer for calculating HASH */ + memcpy(hbuf->v, iph2->nonce->v, iph2->nonce->l); + plog(LLV_DEBUG, LOCATION, NULL, + "HASH allocated:hbuf->l=%zu actual:tlen=%zu\n", + hbuf->l, tlen + iph2->nonce->l); + /* adjust buffer length for HASH */ + hbuf->l = iph2->nonce->l + tlen; + + /* validate HASH(2) */ + { + char *r_hash; + vchar_t *my_hash = NULL; + int result; + + r_hash = (char *)hash + sizeof(*hash); + + plog(LLV_DEBUG, LOCATION, NULL, "HASH(2) received:"); + plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); + + my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf); + if (my_hash == NULL) + goto end; + + result = memcmp(my_hash->v, r_hash, my_hash->l); + vfree(my_hash); + + if (result) { + plog(LLV_DEBUG, LOCATION, iph2->ph1->remote, + "HASH(2) mismatch.\n"); + error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; + goto end; + } + } + + /* validity check SA payload sent from responder */ + if (ipsecdoi_checkph2proposal(iph2) < 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "proposal check failed.\n"); + error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; + goto end; + } + + /* change status of isakmp status entry */ + iph2->status = PHASE2ST_STATUS6; + + error = 0; + +end: + if (hbuf) + vfree(hbuf); + if (pbuf) + vfree(pbuf); + if (msg) + vfree(msg); + if (idci) + vfree(idci); + if (idcr) + vfree(idcr); + + if (error) { + VPTRINIT(iph2->sa_ret); + VPTRINIT(iph2->nonce_p); + VPTRINIT(iph2->dhpub_p); + VPTRINIT(iph2->id); + VPTRINIT(iph2->id_p); +#ifdef ENABLE_NATT + if (iph2->natoa_src) { + racoon_free(iph2->natoa_src); + iph2->natoa_src = NULL; + } + if (iph2->natoa_dst) { + racoon_free(iph2->natoa_dst); + iph2->natoa_dst = NULL; + } +#endif + } + + return error; +} + +/* + * send to responder + * HDR*, HASH(3) + */ +int +quick_i2send(iph2, msg0) + struct ph2handle *iph2; + vchar_t *msg0; +{ + vchar_t *msg = NULL; + vchar_t *buf = NULL; + vchar_t *hash = NULL; + char *p = NULL; + int tlen; + int error = ISAKMP_INTERNAL_ERROR; + + /* validity check */ + if (iph2->status != PHASE2ST_STATUS6) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph2->status); + goto end; + } + + /* generate HASH(3) */ + { + vchar_t *tmp = NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "HASH(3) generate\n"); + + tmp = vmalloc(iph2->nonce->l + iph2->nonce_p->l); + if (tmp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get hash buffer.\n"); + goto end; + } + memcpy(tmp->v, iph2->nonce->v, iph2->nonce->l); + memcpy(tmp->v + iph2->nonce->l, iph2->nonce_p->v, iph2->nonce_p->l); + + hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp); + vfree(tmp); + + if (hash == NULL) + goto end; + } + + /* create buffer for isakmp payload */ + tlen = sizeof(struct isakmp) + + sizeof(struct isakmp_gen) + hash->l; + buf = vmalloc(tlen); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + goto end; + } + + /* create isakmp header */ + p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH); + if (p == NULL) + goto end; + + /* add HASH(3) payload */ + p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_NONE); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1); +#endif + + /* encoding */ + iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); + if (iph2->sendbuf == NULL) + goto end; + + /* if there is commit bit, need resending */ + if (ISSET(iph2->flags, ISAKMP_FLAG_C)) { + /* send the packet, add to the schedule to resend */ + if (isakmp_ph2send(iph2) == -1) + goto end; + } else { + /* send the packet */ + if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) + goto end; + } + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, + iph2->sendbuf, msg0) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + /* compute both of KEYMATs */ + if (oakley_compute_keymat(iph2, INITIATOR) < 0) + goto end; + + iph2->status = PHASE2ST_ADDSA; + + /* don't anything if local test mode. */ + if (f_local) { + error = 0; + goto end; + } + + /* if there is commit bit don't set up SA now. */ + if (ISSET(iph2->flags, ISAKMP_FLAG_C)) { + iph2->status = PHASE2ST_COMMIT; + error = 0; + goto end; + } + + /* Do UPDATE for initiator */ + plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n"); + if (pk_sendupdate(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n"); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n"); + + /* Do ADD for responder */ + if (pk_sendadd(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n"); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n"); + + error = 0; + +end: + if (buf != NULL) + vfree(buf); + if (msg != NULL) + vfree(msg); + if (hash != NULL) + vfree(hash); + + return error; +} + +/* + * receive from responder + * HDR#*, HASH(4), notify + */ +int +quick_i3recv(iph2, msg0) + struct ph2handle *iph2; + vchar_t *msg0; +{ + vchar_t *msg = NULL; + vchar_t *pbuf = NULL; /* for payload parsing */ + struct isakmp_parse_t *pa; + struct isakmp_pl_hash *hash = NULL; + vchar_t *notify = NULL; + int error = ISAKMP_INTERNAL_ERROR; + + /* validity check */ + if (iph2->status != PHASE2ST_COMMIT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph2->status); + goto end; + } + + /* decrypt packet */ + if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "Packet wasn't encrypted.\n"); + goto end; + } + msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); + if (msg == NULL) + goto end; + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + + for (pa = (struct isakmp_parse_t *)pbuf->v; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_HASH: + hash = (struct isakmp_pl_hash *)pa->ptr; + break; + case ISAKMP_NPTYPE_N: + if (notify != NULL) { + plog(LLV_WARNING, LOCATION, NULL, + "Ignoring multiples notifications\n"); + break; + } + ph2_recv_n(iph2, pa->ptr); + notify = vmalloc(pa->len); + if (notify == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get notify buffer.\n"); + goto end; + } + memcpy(notify->v, pa->ptr, notify->l); + break; + default: + /* don't send information, see ident_r1recv() */ + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + + /* payload existency check */ + if (hash == NULL) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "few isakmp message received.\n"); + goto end; + } + + /* validate HASH(4) */ + { + char *r_hash; + vchar_t *my_hash = NULL; + vchar_t *tmp = NULL; + int result; + + r_hash = (char *)hash + sizeof(*hash); + + plog(LLV_DEBUG, LOCATION, NULL, "HASH(4) validate:"); + plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); + + my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify); + vfree(tmp); + if (my_hash == NULL) + goto end; + + result = memcmp(my_hash->v, r_hash, my_hash->l); + vfree(my_hash); + + if (result) { + plog(LLV_DEBUG, LOCATION, iph2->ph1->remote, + "HASH(4) mismatch.\n"); + error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; + goto end; + } + } + + iph2->status = PHASE2ST_ADDSA; + iph2->flags ^= ISAKMP_FLAG_C; /* reset bit */ + + /* don't anything if local test mode. */ + if (f_local) { + error = 0; + goto end; + } + + /* Do UPDATE for initiator */ + plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n"); + if (pk_sendupdate(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n"); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n"); + + /* Do ADD for responder */ + if (pk_sendadd(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n"); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n"); + + error = 0; + +end: + if (msg != NULL) + vfree(msg); + if (pbuf != NULL) + vfree(pbuf); + if (notify != NULL) + vfree(notify); + + return error; +} + +/* + * receive from initiator + * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ] + */ +int +quick_r1recv(iph2, msg0) + struct ph2handle *iph2; + vchar_t *msg0; +{ + vchar_t *msg = NULL; + vchar_t *hbuf = NULL; /* for hash computing. */ + vchar_t *pbuf = NULL; /* for payload parsing */ + struct isakmp_parse_t *pa; + struct isakmp *isakmp = (struct isakmp *)msg0->v; + struct isakmp_pl_hash *hash = NULL; + char *p; + int tlen; + int f_id_order; /* for ID payload detection */ + int error = ISAKMP_INTERNAL_ERROR; + + /* validity check */ + if (iph2->status != PHASE2ST_START) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph2->status); + goto end; + } + + /* decrypting */ + if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "Packet wasn't encrypted.\n"); + error = ISAKMP_NTYPE_PAYLOAD_MALFORMED; + goto end; + } + /* decrypt packet */ + msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); + if (msg == NULL) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "Packet decryption failed.\n"); + goto end; + } + + /* create buffer for using to validate HASH(1) */ + /* + * ordering rule: + * 1. the first one must be HASH + * 2. the second one must be SA (added in isakmp-oakley-05!) + * 3. two IDs must be considered as IDci, then IDcr + */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + pa = (struct isakmp_parse_t *)pbuf->v; + + /* HASH payload is fixed postion */ + if (pa->type != ISAKMP_NPTYPE_HASH) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "received invalid next payload type %d, " + "expecting %d.\n", + pa->type, ISAKMP_NPTYPE_HASH); + error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX; + goto end; + } + hash = (struct isakmp_pl_hash *)pa->ptr; + pa++; + + /* + * this restriction was introduced in isakmp-oakley-05. + * we do not check this for backward compatibility. + * TODO: command line/config file option to enable/disable this code + */ + /* HASH payload is fixed postion */ + if (pa->type != ISAKMP_NPTYPE_SA) { + plog(LLV_WARNING, LOCATION, iph2->ph1->remote, + "received invalid next payload type %d, " + "expecting %d.\n", + pa->type, ISAKMP_NPTYPE_SA); + error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX; + } + + /* allocate buffer for computing HASH(1) */ + tlen = ntohl(isakmp->len) - sizeof(*isakmp); + hbuf = vmalloc(tlen); + if (hbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get hash buffer.\n"); + goto end; + } + p = hbuf->v; + + /* + * parse the payloads. + * copy non-HASH payloads into hbuf, so that we can validate HASH. + */ + iph2->sa = NULL; /* we don't support multi SAs. */ + iph2->nonce_p = NULL; + iph2->dhpub_p = NULL; + iph2->id_p = NULL; + iph2->id = NULL; + tlen = 0; /* count payload length except of HASH payload. */ + + /* + * IDi2 MUST be immediatelly followed by IDr2. We allowed the + * illegal case, but logged. First ID payload is to be IDi2. + * And next ID payload is to be IDr2. + */ + f_id_order = 0; + + for (; pa->type; pa++) { + + /* copy to buffer for HASH */ + /* Don't modify the payload */ + memcpy(p, pa->ptr, pa->len); + + if (pa->type != ISAKMP_NPTYPE_ID) + f_id_order = 0; + + switch (pa->type) { + case ISAKMP_NPTYPE_SA: + if (iph2->sa != NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Multi SAs isn't supported.\n"); + goto end; + } + if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "duplicate ISAKMP_NPTYPE_SA.\n"); + goto end; + } + break; + + case ISAKMP_NPTYPE_NONCE: + if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "duplicate ISAKMP_NPTYPE_NONCE.\n"); + goto end; + } + break; + + case ISAKMP_NPTYPE_KE: + if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "duplicate ISAKMP_NPTYPE_KE.\n"); + goto end; + } + break; + + case ISAKMP_NPTYPE_ID: + if (iph2->id_p == NULL) { + /* for IDci */ + f_id_order++; + + if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0) + goto end; + + } else if (iph2->id == NULL) { + /* for IDcr */ + if (f_id_order == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "IDr2 payload is not " + "immediatelly followed " + "by IDi2. We allowed.\n"); + /* XXX we allowed in this case. */ + } + + if (isakmp_p2ph(&iph2->id, pa->ptr) < 0) + goto end; + } else { + plog(LLV_ERROR, LOCATION, NULL, + "received too many ID payloads.\n"); + plogdump(LLV_ERROR, iph2->id->v, iph2->id->l); + error = ISAKMP_NTYPE_INVALID_ID_INFORMATION; + goto end; + } + break; + + case ISAKMP_NPTYPE_N: + ph2_recv_n(iph2, pa->ptr); + break; + +#ifdef ENABLE_NATT + case ISAKMP_NPTYPE_NATOA_DRAFT: + case ISAKMP_NPTYPE_NATOA_RFC: + { + struct sockaddr_storage addr; + struct sockaddr *daddr; + u_int8_t prefix; + u_int16_t ul_proto; + vchar_t *vp = NULL; + + if (isakmp_p2ph(&vp, pa->ptr) < 0) + goto end; + + error = ipsecdoi_id2sockaddr(vp, + (struct sockaddr *) &addr, + &prefix, &ul_proto); + + vfree(vp); + + if (error) + goto end; + + daddr = dupsaddr((struct sockaddr *) &addr); + if (daddr == NULL) + goto end; + + if (iph2->natoa_dst == NULL) + iph2->natoa_dst = daddr; + else if (iph2->natoa_src == NULL) + iph2->natoa_src = daddr; + else { + racoon_free(daddr); + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "received too many NAT-OA payloads.\n"); + error = ISAKMP_NTYPE_PAYLOAD_MALFORMED; + goto end; + } + } + break; +#endif + + default: + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + error = ISAKMP_NTYPE_PAYLOAD_MALFORMED; + goto end; + } + + p += pa->len; + + /* compute true length of payload. */ + tlen += pa->len; + } + + /* payload existency check */ + if (hash == NULL || iph2->sa == NULL || iph2->nonce_p == NULL) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "few isakmp message received.\n"); + error = ISAKMP_NTYPE_PAYLOAD_MALFORMED; + goto end; + } + + if (iph2->id_p) { + plog(LLV_DEBUG, LOCATION, NULL, "received IDci2:"); + plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l); + } + if (iph2->id) { + plog(LLV_DEBUG, LOCATION, NULL, "received IDcr2:"); + plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l); + } + + /* adjust buffer length for HASH */ + hbuf->l = tlen; + + /* validate HASH(1) */ + { + char *r_hash; + vchar_t *my_hash = NULL; + int result; + + r_hash = (caddr_t)hash + sizeof(*hash); + + plog(LLV_DEBUG, LOCATION, NULL, "HASH(1) validate:"); + plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); + + my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf); + if (my_hash == NULL) + goto end; + + result = memcmp(my_hash->v, r_hash, my_hash->l); + vfree(my_hash); + + if (result) { + plog(LLV_DEBUG, LOCATION, iph2->ph1->remote, + "HASH(1) mismatch.\n"); + error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; + goto end; + } + } + + /* get sainfo */ + error = get_sainfo_r(iph2); + if (error) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get sainfo.\n"); + goto end; + } + + + /* check the existence of ID payload and create responder's proposal */ + error = get_proposal_r(iph2); + switch (error) { + case -2: + /* generate a policy template from peer's proposal */ + if (set_proposal_from_proposal(iph2)) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate a proposal template " + "from client's proposal.\n"); + error = ISAKMP_INTERNAL_ERROR; + goto end; + } + /*FALLTHROUGH*/ + case 0: + /* select single proposal or reject it. */ + if (ipsecdoi_selectph2proposal(iph2) < 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "no proposal chosen.\n"); + error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; + goto end; + } + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "failed to get proposal for responder.\n"); + goto end; + } + + /* check KE and attribute of PFS */ + if (iph2->dhpub_p != NULL && iph2->approval->pfs_group == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "no PFS is specified, but peer sends KE.\n"); + error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; + goto end; + } + if (iph2->dhpub_p == NULL && iph2->approval->pfs_group != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "PFS is specified, but peer doesn't sends KE.\n"); + error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; + goto end; + } + + /* + * save the packet from the initiator in order to resend the + * responder's first packet against this packet. + */ + iph2->msg1 = vdup(msg0); + + /* change status of isakmp status entry */ + iph2->status = PHASE2ST_STATUS2; + + error = 0; + +end: + if (hbuf) + vfree(hbuf); + if (msg) + vfree(msg); + if (pbuf) + vfree(pbuf); + + if (error) { + VPTRINIT(iph2->sa); + VPTRINIT(iph2->nonce_p); + VPTRINIT(iph2->dhpub_p); + VPTRINIT(iph2->id); + VPTRINIT(iph2->id_p); +#ifdef ENABLE_NATT + if (iph2->natoa_src) { + racoon_free(iph2->natoa_src); + iph2->natoa_src = NULL; + } + if (iph2->natoa_dst) { + racoon_free(iph2->natoa_dst); + iph2->natoa_dst = NULL; + } +#endif + } + + return error; +} + +/* + * call pfkey_getspi. + */ +int +quick_r1prep(iph2, msg) + struct ph2handle *iph2; + vchar_t *msg; +{ + int error = ISAKMP_INTERNAL_ERROR; + + /* validity check */ + if (iph2->status != PHASE2ST_STATUS2) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph2->status); + goto end; + } + + iph2->status = PHASE2ST_GETSPISENT; + + /* send getspi message */ + if (pk_sendgetspi(iph2) < 0) + goto end; + + plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n"); + + sched_schedule(&iph2->sce, lcconf->wait_ph2complete, + quick_timeover_stub); + + error = 0; + +end: + return error; +} + +/* + * send to initiator + * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ] + */ +int +quick_r2send(iph2, msg) + struct ph2handle *iph2; + vchar_t *msg; +{ + vchar_t *body = NULL; + vchar_t *hash = NULL; + struct isakmp_gen *gen; + char *p; + int tlen; + int error = ISAKMP_INTERNAL_ERROR; + int natoa = ISAKMP_NPTYPE_NONE; + int pfsgroup; + u_int8_t *np_p = NULL; +#ifdef ENABLE_NATT + vchar_t *nat_oai = NULL; + vchar_t *nat_oar = NULL; +#endif + + /* validity check */ + if (msg != NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "msg has to be NULL in this function.\n"); + goto end; + } + if (iph2->status != PHASE2ST_GETSPIDONE) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph2->status); + goto end; + } + + /* update responders SPI */ + if (ipsecdoi_updatespi(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "failed to update spi.\n"); + goto end; + } + + /* generate NONCE value */ + iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size); + if (iph2->nonce == NULL) + goto end; + + /* generate KE value if need */ + pfsgroup = iph2->approval->pfs_group; + if (iph2->dhpub_p != NULL && pfsgroup != 0) { + /* DH group settting if PFS is required. */ + if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set DH value.\n"); + goto end; + } + /* generate DH public value */ + if (oakley_dh_generate(iph2->pfsgrp, + &iph2->dhpub, &iph2->dhpriv) < 0) { + goto end; + } + } + +#ifdef ENABLE_NATT + /* + * RFC3947 5.2. if we chose UDP-Encapsulated-Transport + * we should send NAT-OA + */ + if (ipsecdoi_transportmode(iph2->proposal) + && (iph2->ph1->natt_flags & NAT_DETECTED)) { + natoa = iph2->ph1->natt_options->payload_nat_oa; + + nat_oai = ipsecdoi_sockaddr2id(iph2->dst, + IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY); + nat_oar = ipsecdoi_sockaddr2id(iph2->src, + IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY); + + if (nat_oai == NULL || nat_oar == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate NAT-OA payload.\n"); + goto end; + } + + plog(LLV_DEBUG, LOCATION, NULL, "NAT-OAi:\n"); + plogdump(LLV_DEBUG, nat_oai->v, nat_oai->l); + plog(LLV_DEBUG, LOCATION, NULL, "NAT-OAr:\n"); + plogdump(LLV_DEBUG, nat_oar->v, nat_oar->l); + } +#endif + + /* create SA;NONCE payload, and KE and ID if need */ + tlen = sizeof(*gen) + iph2->sa_ret->l + + sizeof(*gen) + iph2->nonce->l; + if (iph2->dhpub_p != NULL && pfsgroup != 0) + tlen += (sizeof(*gen) + iph2->dhpub->l); + if (iph2->id_p != NULL) + tlen += (sizeof(*gen) + iph2->id_p->l + + sizeof(*gen) + iph2->id->l); +#ifdef ENABLE_NATT + if (natoa != ISAKMP_NPTYPE_NONE) + tlen += 2 * sizeof(*gen) + nat_oai->l + nat_oar->l; +#endif + + body = vmalloc(tlen); + if (body == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + goto end; + } + p = body->v; + + /* make SA payload */ + p = set_isakmp_payload(body->v, iph2->sa_ret, ISAKMP_NPTYPE_NONCE); + + /* add NONCE payload */ + np_p = &((struct isakmp_gen *)p)->np; /* XXX */ + p = set_isakmp_payload(p, iph2->nonce, + (iph2->dhpub_p != NULL && pfsgroup != 0) + ? ISAKMP_NPTYPE_KE + : (iph2->id_p != NULL + ? ISAKMP_NPTYPE_ID + : natoa)); + + /* add KE payload if need. */ + if (iph2->dhpub_p != NULL && pfsgroup != 0) { + np_p = &((struct isakmp_gen *)p)->np; /* XXX */ + p = set_isakmp_payload(p, iph2->dhpub, + (iph2->id_p == NULL) + ? natoa + : ISAKMP_NPTYPE_ID); + } + + /* add ID payloads received. */ + if (iph2->id_p != NULL) { + /* IDci */ + p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID); + /* IDcr */ + np_p = &((struct isakmp_gen *)p)->np; /* XXX */ + p = set_isakmp_payload(p, iph2->id, natoa); + } + +#ifdef ENABLE_NATT + /* NAT-OA */ + if (natoa != ISAKMP_NPTYPE_NONE) { + p = set_isakmp_payload(p, nat_oai, natoa); + p = set_isakmp_payload(p, nat_oar, ISAKMP_NPTYPE_NONE); + } +#endif + + /* add a RESPONDER-LIFETIME notify payload if needed */ + { + vchar_t *data = NULL; + struct saprop *pp = iph2->approval; + struct saproto *pr; + + if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_SEC) { + u_int32_t v = htonl((u_int32_t)pp->lifetime); + data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE, + IPSECDOI_ATTR_SA_LD_TYPE_SEC); + if (!data) + goto end; + data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD, + (caddr_t)&v, sizeof(v)); + if (!data) + goto end; + } + if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_KB) { + u_int32_t v = htonl((u_int32_t)pp->lifebyte); + data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE, + IPSECDOI_ATTR_SA_LD_TYPE_KB); + if (!data) + goto end; + data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD, + (caddr_t)&v, sizeof(v)); + if (!data) + goto end; + } + + /* + * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message + * in the case of SA bundle ? + */ + if (data) { + for (pr = pp->head; pr; pr = pr->next) { + body = isakmp_add_pl_n(body, &np_p, + ISAKMP_NTYPE_RESPONDER_LIFETIME, pr, data); + if (!body) { + vfree(data); + return error; /* XXX */ + } + } + vfree(data); + } + } + + /* generate HASH(2) */ + { + vchar_t *tmp; + + tmp = vmalloc(iph2->nonce_p->l + body->l); + if (tmp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get hash buffer.\n"); + goto end; + } + memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l); + memcpy(tmp->v + iph2->nonce_p->l, body->v, body->l); + + hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, tmp); + vfree(tmp); + + if (hash == NULL) + goto end; + } + + /* send isakmp payload */ + iph2->sendbuf = quick_ir1mx(iph2, body, hash); + if (iph2->sendbuf == NULL) + goto end; + + /* send the packet, add to the schedule to resend */ + if (isakmp_ph2send(iph2) == -1) + goto end; + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + /* change status of isakmp status entry */ + iph2->status = PHASE2ST_MSG1SENT; + + error = 0; + +end: + if (body != NULL) + vfree(body); + if (hash != NULL) + vfree(hash); +#ifdef ENABLE_NATT + if (nat_oai != NULL) + vfree(nat_oai); + if (nat_oar != NULL) + vfree(nat_oar); +#endif + + return error; +} + +/* + * receive from initiator + * HDR*, HASH(3) + + */ +int +quick_r3recv(iph2, msg0) + struct ph2handle *iph2; + vchar_t *msg0; +{ + vchar_t *msg = NULL; + vchar_t *pbuf = NULL; /* for payload parsing */ + struct isakmp_parse_t *pa; + struct isakmp_pl_hash *hash = NULL; + int error = ISAKMP_INTERNAL_ERROR; + + /* validity check */ + if (iph2->status != PHASE2ST_MSG1SENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph2->status); + goto end; + } + + /* decrypt packet */ + if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "Packet wasn't encrypted.\n"); + goto end; + } + msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); + if (msg == NULL) + goto end; + + /* validate the type of next payload */ + pbuf = isakmp_parse(msg); + if (pbuf == NULL) + goto end; + + for (pa = (struct isakmp_parse_t *)pbuf->v; + pa->type != ISAKMP_NPTYPE_NONE; + pa++) { + + switch (pa->type) { + case ISAKMP_NPTYPE_HASH: + hash = (struct isakmp_pl_hash *)pa->ptr; + break; + case ISAKMP_NPTYPE_N: + ph2_recv_n(iph2, pa->ptr); + break; + default: + /* don't send information, see ident_r1recv() */ + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "ignore the packet, " + "received unexpecting payload type %d.\n", + pa->type); + goto end; + } + } + + /* payload existency check */ + if (hash == NULL) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "few isakmp message received.\n"); + goto end; + } + + /* validate HASH(3) */ + /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */ + { + char *r_hash; + vchar_t *my_hash = NULL; + vchar_t *tmp = NULL; + int result; + + r_hash = (char *)hash + sizeof(*hash); + + plog(LLV_DEBUG, LOCATION, NULL, "HASH(3) validate:"); + plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); + + tmp = vmalloc(iph2->nonce_p->l + iph2->nonce->l); + if (tmp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get hash buffer.\n"); + goto end; + } + memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l); + memcpy(tmp->v + iph2->nonce_p->l, iph2->nonce->v, iph2->nonce->l); + + my_hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp); + vfree(tmp); + if (my_hash == NULL) + goto end; + + result = memcmp(my_hash->v, r_hash, my_hash->l); + vfree(my_hash); + + if (result) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "HASH(3) mismatch.\n"); + error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; + goto end; + } + } + + /* if there is commit bit, don't set up SA now. */ + if (ISSET(iph2->flags, ISAKMP_FLAG_C)) { + iph2->status = PHASE2ST_COMMIT; + } else + iph2->status = PHASE2ST_STATUS6; + + error = 0; + +end: + if (pbuf != NULL) + vfree(pbuf); + if (msg != NULL) + vfree(msg); + + return error; +} + +/* + * send to initiator + * HDR#*, HASH(4), notify + */ +int +quick_r3send(iph2, msg0) + struct ph2handle *iph2; + vchar_t *msg0; +{ + vchar_t *buf = NULL; + vchar_t *myhash = NULL; + struct isakmp_pl_n *n; + vchar_t *notify = NULL; + char *p; + int tlen; + int error = ISAKMP_INTERNAL_ERROR; + + /* validity check */ + if (iph2->status != PHASE2ST_COMMIT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph2->status); + goto end; + } + + /* generate HASH(4) */ + /* XXX What can I do in the case of multiple different SA */ + plog(LLV_DEBUG, LOCATION, NULL, "HASH(4) generate\n"); + + /* XXX What should I do if there are multiple SAs ? */ + tlen = sizeof(struct isakmp_pl_n) + iph2->approval->head->spisize; + notify = vmalloc(tlen); + if (notify == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get notify buffer.\n"); + goto end; + } + n = (struct isakmp_pl_n *)notify->v; + n->h.np = ISAKMP_NPTYPE_NONE; + n->h.len = htons(tlen); + n->doi = htonl(IPSEC_DOI); + n->proto_id = iph2->approval->head->proto_id; + n->spi_size = sizeof(iph2->approval->head->spisize); + n->type = htons(ISAKMP_NTYPE_CONNECTED); + memcpy(n + 1, &iph2->approval->head->spi, iph2->approval->head->spisize); + + myhash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify); + if (myhash == NULL) + goto end; + + /* create buffer for isakmp payload */ + tlen = sizeof(struct isakmp) + + sizeof(struct isakmp_gen) + myhash->l + + notify->l; + buf = vmalloc(tlen); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + goto end; + } + + /* create isakmp header */ + p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH); + if (p == NULL) + goto end; + + /* add HASH(4) payload */ + p = set_isakmp_payload(p, myhash, ISAKMP_NPTYPE_N); + + /* add notify payload */ + memcpy(p, notify->v, notify->l); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1); +#endif + + /* encoding */ + iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); + if (iph2->sendbuf == NULL) + goto end; + + /* send the packet */ + if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) + goto end; + + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + goto end; + } + + iph2->status = PHASE2ST_COMMIT; + + error = 0; + +end: + if (buf != NULL) + vfree(buf); + if (myhash != NULL) + vfree(myhash); + if (notify != NULL) + vfree(notify); + + return error; +} + +int +tunnel_mode_prop(p) + struct saprop *p; +{ + struct saproto *pr; + + for (pr = p->head; pr; pr = pr->next) + if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) + return 1; + return 0; +} + +/* + * set SA to kernel. + */ +int +quick_r3prep(iph2, msg0) + struct ph2handle *iph2; + vchar_t *msg0; +{ + int error = ISAKMP_INTERNAL_ERROR; + + /* validity check */ + if (iph2->status != PHASE2ST_STATUS6) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatched %d.\n", iph2->status); + goto end; + } + + /* compute both of KEYMATs */ + if (oakley_compute_keymat(iph2, RESPONDER) < 0) + goto end; + + iph2->status = PHASE2ST_ADDSA; + iph2->flags ^= ISAKMP_FLAG_C; /* reset bit */ + + /* don't anything if local test mode. */ + if (f_local) { + error = 0; + goto end; + } + + /* Do UPDATE as responder */ + plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n"); + if (pk_sendupdate(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n"); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n"); + + /* Do ADD for responder */ + if (pk_sendadd(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n"); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n"); + + /* + * set policies into SPD if the policy is generated + * from peer's policy. + */ + if (iph2->spidx_gen) { + + struct policyindex *spidx; + struct sockaddr_storage addr; + u_int8_t pref; + struct sockaddr *src = iph2->src; + struct sockaddr *dst = iph2->dst; + + /* make inbound policy */ + iph2->src = dst; + iph2->dst = src; + if (pk_sendspdupdate2(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "pfkey spdupdate2(inbound) failed.\n"); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey spdupdate2(inbound) sent.\n"); + + spidx = (struct policyindex *)iph2->spidx_gen; +#ifdef HAVE_POLICY_FWD + /* make forward policy if required */ + if (tunnel_mode_prop(iph2->approval)) { + spidx->dir = IPSEC_DIR_FWD; + if (pk_sendspdupdate2(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "pfkey spdupdate2(forward) failed.\n"); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey spdupdate2(forward) sent.\n"); + } +#endif + + /* make outbound policy */ + iph2->src = src; + iph2->dst = dst; + spidx->dir = IPSEC_DIR_OUTBOUND; + addr = spidx->src; + spidx->src = spidx->dst; + spidx->dst = addr; + pref = spidx->prefs; + spidx->prefs = spidx->prefd; + spidx->prefd = pref; + + if (pk_sendspdupdate2(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "pfkey spdupdate2(outbound) failed.\n"); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey spdupdate2(outbound) sent.\n"); + + /* spidx_gen is unnecessary any more */ + delsp_bothdir((struct policyindex *)iph2->spidx_gen); + racoon_free(iph2->spidx_gen); + iph2->spidx_gen = NULL; + iph2->generated_spidx=1; + } + + error = 0; + +end: + return error; +} + +/* + * create HASH, body (SA, NONCE) payload with isakmp header. + */ +static vchar_t * +quick_ir1mx(iph2, body, hash) + struct ph2handle *iph2; + vchar_t *body, *hash; +{ + struct isakmp *isakmp; + vchar_t *buf = NULL, *new = NULL; + char *p; + int tlen; + struct isakmp_gen *gen; + int error = ISAKMP_INTERNAL_ERROR; + + /* create buffer for isakmp payload */ + tlen = sizeof(*isakmp) + + sizeof(*gen) + hash->l + + body->l; + buf = vmalloc(tlen); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send.\n"); + goto end; + } + + /* re-set encryption flag, for serurity. */ + iph2->flags |= ISAKMP_FLAG_E; + + /* set isakmp header */ + p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH); + if (p == NULL) + goto end; + + /* add HASH payload */ + /* XXX is next type always SA ? */ + p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_SA); + + /* add body payload */ + memcpy(p, body->v, body->l); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1); +#endif + + /* encoding */ + new = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); + + if (new == NULL) + goto end; + + vfree(buf); + + buf = new; + + error = 0; + +end: + if (error && buf != NULL) { + vfree(buf); + buf = NULL; + } + + return buf; +} + +/* + * get remote's sainfo. + * NOTE: this function is for responder. + */ +static int +get_sainfo_r(iph2) + struct ph2handle *iph2; +{ + vchar_t *idsrc = NULL, *iddst = NULL, *client = NULL; + int error = ISAKMP_INTERNAL_ERROR; + + if (iph2->id == NULL) { + idsrc = ipsecdoi_sockaddr2id(iph2->src, IPSECDOI_PREFIX_HOST, + IPSEC_ULPROTO_ANY); + } else { + idsrc = vdup(iph2->id); + } + if (idsrc == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set ID for source.\n"); + goto end; + } + + if (iph2->id_p == NULL) { + iddst = ipsecdoi_sockaddr2id(iph2->dst, IPSECDOI_PREFIX_HOST, + IPSEC_ULPROTO_ANY); + } else { + iddst = vdup(iph2->id_p); + } + if (iddst == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set ID for destination.\n"); + goto end; + } + +#ifdef ENABLE_HYBRID + + /* clientaddr check : obtain modecfg address */ + if (iph2->ph1->mode_cfg != NULL) { + if ((iph2->ph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) || + (iph2->ph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)){ + struct sockaddr saddr; + saddr.sa_family = AF_INET; +#ifndef __linux__ + saddr.sa_len = sizeof(struct sockaddr_in); +#endif + ((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY; + memcpy(&((struct sockaddr_in *)&saddr)->sin_addr, + &iph2->ph1->mode_cfg->addr4, sizeof(struct in_addr)); + client = ipsecdoi_sockaddr2id(&saddr, 32, IPSEC_ULPROTO_ANY); + } + } + + /* clientaddr check, fallback to peer address */ + if (client == NULL) + { + client = ipsecdoi_sockaddr2id(iph2->dst, IPSECDOI_PREFIX_HOST, + IPSEC_ULPROTO_ANY); + } +#endif + + /* obtain a matching sainfo section */ + iph2->sainfo = getsainfo(idsrc, iddst, iph2->ph1->id_p, client, iph2->ph1->rmconf->ph1id); + if (iph2->sainfo == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get sainfo.\n"); + goto end; + } + +#ifdef ENABLE_HYBRID + /* xauth group inclusion check */ + if (iph2->sainfo->group != NULL) + if(group_check(iph2->ph1,&iph2->sainfo->group->v,1)) + goto end; +#endif + + plog(LLV_DEBUG, LOCATION, NULL, + "selected sainfo: %s\n", sainfo2str(iph2->sainfo)); + + error = 0; +end: + if (idsrc) + vfree(idsrc); + if (iddst) + vfree(iddst); + if (client) + vfree(client); + + return error; +} + +/* + * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types + * are IP address and same address family. + * Then get remote's policy from SPD copied from kernel. + * If the type of ID payload is address or subnet type, then the index is + * made from the payload. If there is no ID payload, or the type of ID + * payload is NOT address type, then the index is made from the address + * pair of phase 1. + * NOTE: This function is only for responder. + */ +static int +get_proposal_r(iph2) + struct ph2handle *iph2; +{ + struct policyindex spidx; + struct secpolicy *sp_in, *sp_out; + int idi2type = 0; /* switch whether copy IDs into id[src,dst]. */ + int error = ISAKMP_INTERNAL_ERROR; + + /* check the existence of ID payload */ + if ((iph2->id_p != NULL && iph2->id == NULL) + || (iph2->id_p == NULL && iph2->id != NULL)) { + plog(LLV_ERROR, LOCATION, NULL, + "Both IDs wasn't found in payload.\n"); + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + } + + /* make sure if sa_[src, dst] are null. */ + if (iph2->sa_src || iph2->sa_dst) { + plog(LLV_ERROR, LOCATION, NULL, + "Why do ID[src,dst] exist already.\n"); + return ISAKMP_INTERNAL_ERROR; + } + + memset(&spidx, 0, sizeof(spidx)); + +#define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type + + /* make a spidx; a key to search SPD */ + spidx.dir = IPSEC_DIR_INBOUND; + spidx.ul_proto = 0; + + /* + * make destination address in spidx from either ID payload + * or phase 1 address into a address in spidx. + */ + if (iph2->id != NULL + && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR + || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR + || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET + || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { + /* get a destination address of a policy */ + error = ipsecdoi_id2sockaddr(iph2->id, + (struct sockaddr *)&spidx.dst, + &spidx.prefd, &spidx.ul_proto); + if (error) + return error; + +#ifdef INET6 + /* + * get scopeid from the SA address. + * note that the phase 1 source address is used as + * a destination address to search for a inbound policy entry + * because rcoon is responder. + */ + if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) { + error = setscopeid((struct sockaddr *)&spidx.dst, + iph2->src); + if (error) + return error; + } +#endif + + if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR + || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) + idi2type = _XIDT(iph2->id); + + } else { + + plog(LLV_DEBUG, LOCATION, NULL, + "get a destination address of SP index " + "from phase1 address " + "due to no ID payloads found " + "OR because ID type is not address.\n"); + + /* + * copy the SOURCE address of IKE into the DESTINATION address + * of the key to search the SPD because the direction of policy + * is inbound. + */ + memcpy(&spidx.dst, iph2->src, sysdep_sa_len(iph2->src)); + switch (spidx.dst.ss_family) { + case AF_INET: + spidx.prefd = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + spidx.prefd = sizeof(struct in6_addr) << 3; + break; +#endif + default: + spidx.prefd = 0; + break; + } + } + + /* make source address in spidx */ + if (iph2->id_p != NULL + && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR + || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR + || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET + || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { + /* get a source address of inbound SA */ + error = ipsecdoi_id2sockaddr(iph2->id_p, + (struct sockaddr *)&spidx.src, + &spidx.prefs, &spidx.ul_proto); + if (error) + return error; + +#ifdef INET6 + /* + * get scopeid from the SA address. + * for more detail, see above of this function. + */ + if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) { + error = setscopeid((struct sockaddr *)&spidx.src, + iph2->dst); + if (error) + return error; + } +#endif + + /* Before setting iph2->[sa_src, sa_dst] with the addresses + * provided in ID payloads, we check: + * - they are both addresses of same family + * - sainfo has not been selected only based on ID payload + * information but also based on specific Phase 1 + * credentials (iph2->sainfo->id_i is defined), i.e. + * local configuration _explicitly_ expect that user + * (e.g. from asn1dn "C=FR, ...") with those IDs) */ + if (_XIDT(iph2->id_p) == idi2type && + spidx.dst.ss_family == spidx.src.ss_family && + iph2->sainfo && iph2->sainfo->id_i) { + + iph2->sa_src = dupsaddr((struct sockaddr *)&spidx.dst); + if (iph2->sa_src == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "buffer allocation failed.\n"); + return ISAKMP_INTERNAL_ERROR; + } + + iph2->sa_dst = dupsaddr((struct sockaddr *)&spidx.src); + if (iph2->sa_dst == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "buffer allocation failed.\n"); + return ISAKMP_INTERNAL_ERROR; + } + } else { + plog(LLV_DEBUG, LOCATION, NULL, + "Either family (%d - %d), types (%d - %d) of ID " + "from initiator differ or matching sainfo " + "has no id_i defined for the peer. Not filling " + "iph2->sa_src and iph2->sa_dst.\n", + spidx.src.ss_family, spidx.dst.ss_family, + _XIDT(iph2->id_p),idi2type); + } + } else { + plog(LLV_DEBUG, LOCATION, NULL, + "get a source address of SP index from Phase 1" + "addresses due to no ID payloads found" + "OR because ID type is not address.\n"); + + /* see above comment. */ + memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst)); + switch (spidx.src.ss_family) { + case AF_INET: + spidx.prefs = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + spidx.prefs = sizeof(struct in6_addr) << 3; + break; +#endif + default: + spidx.prefs = 0; + break; + } + } + +#undef _XIDT + + plog(LLV_DEBUG, LOCATION, NULL, + "get src address from ID payload " + "%s prefixlen=%u ul_proto=%u\n", + saddr2str((struct sockaddr *)&spidx.src), + spidx.prefs, spidx.ul_proto); + plog(LLV_DEBUG, LOCATION, NULL, + "get dst address from ID payload " + "%s prefixlen=%u ul_proto=%u\n", + saddr2str((struct sockaddr *)&spidx.dst), + spidx.prefd, spidx.ul_proto); + + /* + * convert the ul_proto if it is 0 + * because 0 in ID payload means a wild card. + */ + if (spidx.ul_proto == 0) + spidx.ul_proto = IPSEC_ULPROTO_ANY; + +#ifdef HAVE_SECCTX + /* + * Need to use security context in spidx to ensure the correct + * policy is selected. The only way to get the security context + * is to look into the proposal sent by peer ahead of time. + */ + if (get_security_context(iph2->sa, &spidx)) { + plog(LLV_ERROR, LOCATION, NULL, + "error occurred trying to get security context.\n"); + return ISAKMP_INTERNAL_ERROR; + } +#endif /* HAVE_SECCTX */ + + /* get inbound policy */ + sp_in = getsp_r(&spidx); + if (sp_in == NULL) { + if (iph2->ph1->rmconf->gen_policy) { + plog(LLV_INFO, LOCATION, NULL, + "no policy found, " + "try to generate the policy : %s\n", + spidx2str(&spidx)); + iph2->spidx_gen = racoon_malloc(sizeof(spidx)); + if (!iph2->spidx_gen) { + plog(LLV_ERROR, LOCATION, NULL, + "buffer allocation failed.\n"); + return ISAKMP_INTERNAL_ERROR; + } + memcpy(iph2->spidx_gen, &spidx, sizeof(spidx)); + return -2; /* special value */ + } + plog(LLV_ERROR, LOCATION, NULL, + "no policy found: %s\n", spidx2str(&spidx)); + return ISAKMP_INTERNAL_ERROR; + } + /* Refresh existing generated policies + */ + if (iph2->ph1->rmconf->gen_policy) { + plog(LLV_INFO, LOCATION, NULL, + "Update the generated policy : %s\n", + spidx2str(&spidx)); + iph2->spidx_gen = racoon_malloc(sizeof(spidx)); + if (!iph2->spidx_gen) { + plog(LLV_ERROR, LOCATION, NULL, + "buffer allocation failed.\n"); + return ISAKMP_INTERNAL_ERROR; + } + memcpy(iph2->spidx_gen, &spidx, sizeof(spidx)); + } + + /* get outbound policy */ + { + struct sockaddr_storage addr; + u_int8_t pref; + + spidx.dir = IPSEC_DIR_OUTBOUND; + addr = spidx.src; + spidx.src = spidx.dst; + spidx.dst = addr; + pref = spidx.prefs; + spidx.prefs = spidx.prefd; + spidx.prefd = pref; + + sp_out = getsp_r(&spidx); + if (!sp_out) { + plog(LLV_WARNING, LOCATION, NULL, + "no outbound policy found: %s\n", + spidx2str(&spidx)); + } + } + + plog(LLV_DEBUG, LOCATION, NULL, + "suitable SP found:%s\n", spidx2str(&spidx)); + + /* + * In the responder side, the inbound policy should be using IPsec. + * outbound policy is not checked currently. + */ + if (sp_in->policy != IPSEC_POLICY_IPSEC) { + plog(LLV_ERROR, LOCATION, NULL, + "policy found, but no IPsec required: %s\n", + spidx2str(&spidx)); + return ISAKMP_INTERNAL_ERROR; + } + + /* set new proposal derived from a policy into the iph2->proposal. */ + if (set_proposal_from_policy(iph2, sp_in, sp_out) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to create saprop.\n"); + return ISAKMP_INTERNAL_ERROR; + } + +#ifdef HAVE_SECCTX + if (spidx.sec_ctx.ctx_str) { + set_secctx_in_proposal(iph2, spidx); + } +#endif /* HAVE_SECCTX */ + + iph2->spid = sp_in->id; + + return 0; +} + +/* + * handle a notification payload inside phase2 exchange. + * phase2 is always encrypted, so it does not need to be checked + * for explicitely. + */ +static int +ph2_recv_n(iph2, gen) + struct ph2handle *iph2; + struct isakmp_gen *gen; +{ + struct ph1handle *iph1 = iph2->ph1; + struct isakmp_pl_n *notify = (struct isakmp_pl_n *) gen; + u_int type; + int check_level; + + type = ntohs(notify->type); + switch (type) { + case ISAKMP_NTYPE_CONNECTED: + break; + case ISAKMP_NTYPE_INITIAL_CONTACT: + return isakmp_info_recv_initialcontact(iph1, iph2); + case ISAKMP_NTYPE_RESPONDER_LIFETIME: + ipsecdoi_parse_responder_lifetime(notify, + &iph2->lifetime_secs, &iph2->lifetime_kb); + + if (iph1 != NULL && iph1->rmconf != NULL) { + check_level = iph1->rmconf->pcheck_level; + } else { + if (iph1 != NULL) + plog(LLV_DEBUG, LOCATION, NULL, + "No phase1 rmconf found !\n"); + else + plog(LLV_DEBUG, LOCATION, NULL, + "No phase1 found !\n"); + check_level = PROP_CHECK_EXACT; + } + + switch (check_level) { + case PROP_CHECK_OBEY: + break; + case PROP_CHECK_STRICT: + case PROP_CHECK_CLAIM: + if (iph2->sainfo == NULL + || iph2->sainfo->lifetime <= iph2->lifetime_secs) { + plog(LLV_WARNING, LOCATION, NULL, + "RESPONDER-LIFETIME: lifetime mismatch\n"); + iph2->lifetime_secs = 0; + } + break; + case PROP_CHECK_EXACT: + if (iph2->sainfo == NULL + || iph2->sainfo->lifetime != iph2->lifetime_secs) { + plog(LLV_WARNING, LOCATION, NULL, + "RESPONDER-LIFETIME: lifetime mismatch\n"); + iph2->lifetime_secs = 0; + } + break; + } + break; + default: + isakmp_log_notify(iph2->ph1, notify, "phase2 exchange"); + isakmp_info_send_n2(iph2, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, + NULL); + break; + } + return 0; +} + diff --git a/ipsec-tools/src/racoon/isakmp_quick.h b/ipsec-tools/src/racoon/isakmp_quick.h new file mode 100644 index 00000000..71eeecf1 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_quick.h @@ -0,0 +1,50 @@ +/* $NetBSD: isakmp_quick.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: isakmp_quick.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ISAKMP_QUICK_H +#define _ISAKMP_QUICK_H + +extern int quick_i1prep __P((struct ph2handle *, vchar_t *)); +extern int quick_i1send __P((struct ph2handle *, vchar_t *)); +extern int quick_i2recv __P((struct ph2handle *, vchar_t *)); +extern int quick_i2send __P((struct ph2handle *, vchar_t *)); +extern int quick_i3recv __P((struct ph2handle *, vchar_t *)); + +extern int quick_r1recv __P((struct ph2handle *, vchar_t *)); +extern int quick_r1prep __P((struct ph2handle *, vchar_t *)); +extern int quick_r2send __P((struct ph2handle *, vchar_t *)); +extern int quick_r3recv __P((struct ph2handle *, vchar_t *)); +extern int quick_r3send __P((struct ph2handle *, vchar_t *)); +extern int quick_r3prep __P((struct ph2handle *, vchar_t *)); + +#endif /* _ISAKMP_QUICK_H */ diff --git a/ipsec-tools/src/racoon/isakmp_unity.c b/ipsec-tools/src/racoon/isakmp_unity.c new file mode 100644 index 00000000..440dc671 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_unity.c @@ -0,0 +1,422 @@ +/* $NetBSD: isakmp_unity.c,v 1.9.18.1 2012/01/01 17:32:04 tteras Exp $ */ + +/* Id: isakmp_unity.c,v 1.10 2006/07/31 04:49:23 manubsd Exp */ + +/* + * Copyright (C) 2004 Emmanuel Dreyfus + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "schedule.h" +#include "debug.h" + +#include "isakmp_var.h" +#include "isakmp.h" +#include "handler.h" +#include "isakmp_xauth.h" +#include "isakmp_unity.h" +#include "isakmp_cfg.h" +#include "strnames.h" + +static vchar_t *isakmp_cfg_split(struct ph1handle *, + struct isakmp_data *, struct unity_netentry*,int); + +vchar_t * +isakmp_unity_req(iph1, attr) + struct ph1handle *iph1; + struct isakmp_data *attr; +{ + int type; + vchar_t *reply_attr = NULL; + + if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Unity mode config request but the peer " + "did not declare itself as unity compliant\n"); + return NULL; + } + + type = ntohs(attr->type); + + /* Handle short attributes */ + if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { + type &= ~ISAKMP_GEN_MASK; + + plog(LLV_DEBUG, LOCATION, NULL, + "Short attribute %s = %d\n", + s_isakmp_cfg_type(type), ntohs(attr->lorv)); + + switch (type) { + default: + plog(LLV_DEBUG, LOCATION, NULL, + "Ignored short attribute %s\n", + s_isakmp_cfg_type(type)); + break; + } + + return reply_attr; + } + + switch(type) { + case UNITY_BANNER: { +#define MAXMOTD 65536 + char buf[MAXMOTD + 1]; + int fd; + char *filename = &isakmp_cfg_config.motd[0]; + int len; + + if ((fd = open(filename, O_RDONLY, 0)) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot open \"%s\"\n", filename); + return NULL; + } + + if ((len = read(fd, buf, MAXMOTD)) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot read \"%s\"\n", filename); + close(fd); + return NULL; + } + close(fd); + + buf[len] = '\0'; + reply_attr = isakmp_cfg_string(iph1, attr, buf); + + break; + } + + case UNITY_PFS: + reply_attr = isakmp_cfg_short(iph1, attr, + isakmp_cfg_config.pfs_group); + break; + + case UNITY_SAVE_PASSWD: + reply_attr = isakmp_cfg_short(iph1, attr, + isakmp_cfg_config.save_passwd); + break; + + case UNITY_DDNS_HOSTNAME: + reply_attr = isakmp_cfg_copy(iph1, attr); + break; + + case UNITY_DEF_DOMAIN: + reply_attr = isakmp_cfg_string(iph1, + attr, isakmp_cfg_config.default_domain); + break; + + case UNITY_SPLIT_INCLUDE: + if(isakmp_cfg_config.splitnet_type == UNITY_SPLIT_INCLUDE) + reply_attr = isakmp_cfg_split(iph1, attr, + isakmp_cfg_config.splitnet_list, + isakmp_cfg_config.splitnet_count); + else + return NULL; + break; + case UNITY_LOCAL_LAN: + if(isakmp_cfg_config.splitnet_type == UNITY_LOCAL_LAN) + reply_attr = isakmp_cfg_split(iph1, attr, + isakmp_cfg_config.splitnet_list, + isakmp_cfg_config.splitnet_count); + else + return NULL; + break; + case UNITY_SPLITDNS_NAME: + reply_attr = isakmp_cfg_varlen(iph1, attr, + isakmp_cfg_config.splitdns_list, + isakmp_cfg_config.splitdns_len); + break; + case UNITY_FW_TYPE: + case UNITY_NATT_PORT: + case UNITY_BACKUP_SERVERS: + default: + plog(LLV_DEBUG, LOCATION, NULL, + "Ignored attribute %s\n", s_isakmp_cfg_type(type)); + return NULL; + break; + } + + return reply_attr; +} + +void +isakmp_unity_reply(iph1, attr) + struct ph1handle *iph1; + struct isakmp_data *attr; +{ + int type = ntohs(attr->type); + int alen = ntohs(attr->lorv); + + struct unity_network *network = (struct unity_network *)(attr + 1); + int index = 0; + int count = 0; + + switch(type) { + case UNITY_SPLIT_INCLUDE: + { + if (alen) + count = alen / sizeof(struct unity_network); + + for(;index < count; index++) + splitnet_list_add( + &iph1->mode_cfg->split_include, + &network[index], + &iph1->mode_cfg->include_count); + + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_SPLIT_INCLUDE; + break; + } + case UNITY_LOCAL_LAN: + { + if (alen) + count = alen / sizeof(struct unity_network); + + for(;index < count; index++) + splitnet_list_add( + &iph1->mode_cfg->split_local, + &network[index], + &iph1->mode_cfg->local_count); + + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_SPLIT_LOCAL; + break; + } + case UNITY_SPLITDNS_NAME: + case UNITY_BANNER: + case UNITY_SAVE_PASSWD: + case UNITY_NATT_PORT: + case UNITY_PFS: + case UNITY_FW_TYPE: + case UNITY_BACKUP_SERVERS: + case UNITY_DDNS_HOSTNAME: + default: + plog(LLV_WARNING, LOCATION, NULL, + "Ignored attribute %s\n", + s_isakmp_cfg_type(type)); + break; + } + return; +} + +static vchar_t * +isakmp_cfg_split(iph1, attr, netentry, count) + struct ph1handle *iph1; + struct isakmp_data *attr; + struct unity_netentry *netentry; + int count; +{ + vchar_t *buffer; + struct isakmp_data *new; + struct unity_network * network; + size_t len; + int index = 0; + + char tmp1[40]; + char tmp2[40]; + + len = sizeof(struct unity_network) * count; + if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + return NULL; + } + + new = (struct isakmp_data *)buffer->v; + new->type = attr->type; + new->lorv = htons(len); + + network = (struct unity_network *)(new + 1); + for (; index < count; index++) { + + memcpy(&network[index], + &netentry->network, + sizeof(struct unity_network)); + + inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40); + inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40); + plog(LLV_DEBUG, LOCATION, NULL, "splitnet: %s/%s\n", tmp1, tmp2); + + netentry = netentry->next; + } + + return buffer; +} + +int splitnet_list_add(list, network, count) + struct unity_netentry ** list; + struct unity_network * network; + int *count; +{ + struct unity_netentry * nentry; + + /* + * search for network in current list + * to avoid adding duplicates + */ + for (nentry = *list; nentry != NULL; nentry = nentry->next) + if (memcmp(&nentry->network, network, + sizeof(struct unity_network)) == 0) + return 0; /* it's a dupe */ + + /* + * allocate new netentry and copy + * new splitnet network data + */ + nentry = (struct unity_netentry *) + racoon_malloc(sizeof(struct unity_netentry)); + if (nentry == NULL) + return -1; + + memcpy(&nentry->network,network, + sizeof(struct unity_network)); + nentry->next = NULL; + + /* + * locate the last netentry in our + * splitnet list and add our entry + */ + if (*list == NULL) + *list = nentry; + else { + struct unity_netentry * tmpentry = *list; + while (tmpentry->next != NULL) + tmpentry = tmpentry->next; + tmpentry->next = nentry; + } + + (*count)++; + + return 0; +} + +void splitnet_list_free(list, count) + struct unity_netentry * list; + int *count; +{ + struct unity_netentry * netentry = list; + struct unity_netentry * delentry; + + *count = 0; + + while (netentry != NULL) { + delentry = netentry; + netentry = netentry->next; + racoon_free(delentry); + } +} + +char * splitnet_list_2str(list, splitnet_ipaddr) + struct unity_netentry * list; + enum splinet_ipaddr splitnet_ipaddr; +{ + struct unity_netentry * netentry; + char tmp1[40]; + char tmp2[40]; + char * str; + int len; + + /* determine string length */ + len = 0; + netentry = list; + while (netentry != NULL) { + + inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40); + inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40); + len += strlen(tmp1); + len += strlen(tmp2); + len += 2; + + netentry = netentry->next; + } + + /* allocate network list string; we need the extra byte temporarily + * as sprintf() will write trailing 0-byte after the space. */ + str = racoon_malloc(len + 1); + if (str == NULL) + return NULL; + + /* create network list string */ + len = 0; + netentry = list; + while (netentry != NULL) { + + inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40); + inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40); + if (splitnet_ipaddr == CIDR) { + uint32_t tmp3; + int cidrmask; + + tmp3 = ntohl(netentry->network.mask4.s_addr); + for (cidrmask = 0; tmp3 != 0; cidrmask++) + tmp3 <<= 1; + len += sprintf(str+len, "%s/%d ", tmp1, cidrmask); + } else { + len += sprintf(str+len, "%s/%s ", tmp1, tmp2); + } + + netentry = netentry->next; + } + + /* trim the string to not have trailing spaces */ + str[len-1]=0; + + return str; +} diff --git a/ipsec-tools/src/racoon/isakmp_unity.h b/ipsec-tools/src/racoon/isakmp_unity.h new file mode 100644 index 00000000..3667d0d6 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_unity.h @@ -0,0 +1,74 @@ +/* $NetBSD: isakmp_unity.h,v 1.5 2007/10/19 03:37:19 manu Exp $ */ + +/* $KAME$ */ + +/* + * Copyright (C) 2004 Emmanuel Dreyfus + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +enum splinet_ipaddr { NETMASK, CIDR }; + +/* ISAKMP notifies specific to the Unity vendor Id */ +/* Sent during xauth if the user types his password too slowly */ +#define ISAKMP_NTYPE_UNITY_HEARTBEAT 40500 + +/* ISAKMP mode config attributes specific to the Unity vendor Id */ +#define UNITY_BANNER 28672 +#define UNITY_SAVE_PASSWD 28673 +#define UNITY_DEF_DOMAIN 28674 +#define UNITY_SPLITDNS_NAME 28675 +#define UNITY_SPLIT_INCLUDE 28676 +#define UNITY_NATT_PORT 28677 +#define UNITY_LOCAL_LAN 28678 +#define UNITY_PFS 28679 +#define UNITY_FW_TYPE 28680 +#define UNITY_BACKUP_SERVERS 28681 +#define UNITY_DDNS_HOSTNAME 28682 + +/* + * Unity adress/mask lists + * XXX : the padding is probably there for something ! + */ + +struct unity_network { + struct in_addr addr4; + struct in_addr mask4; + char padding[6]; +} __attribute__((__packed__)); + +struct unity_netentry { + struct unity_network network; + struct unity_netentry *next; +}; + +int splitnet_list_add(struct unity_netentry **, struct unity_network *, int *); +void splitnet_list_free(struct unity_netentry *, int *); +char * splitnet_list_2str(struct unity_netentry *, enum splinet_ipaddr); + +vchar_t *isakmp_unity_req(struct ph1handle *, struct isakmp_data *); +void isakmp_unity_reply(struct ph1handle *, struct isakmp_data *); diff --git a/ipsec-tools/src/racoon/isakmp_var.h b/ipsec-tools/src/racoon/isakmp_var.h new file mode 100644 index 00000000..09e4e7f2 --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_var.h @@ -0,0 +1,144 @@ +/* $NetBSD: isakmp_var.h,v 1.17 2010/11/12 10:36:37 tteras Exp $ */ + +/* Id: isakmp_var.h,v 1.12 2005/05/07 14:45:31 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ISAKMP_VAR_H +#define _ISAKMP_VAR_H + +#include "vmbuf.h" +#include "policy.h" + +#define PORT_ISAKMP 500 +#define PORT_ISAKMP_NATT 4500 + +#define DEFAULT_NONCE_SIZE 16 + +typedef u_char cookie_t[8]; +typedef u_char msgid_t[4]; + +typedef struct { /* i_cookie + r_cookie */ + cookie_t i_ck; + cookie_t r_ck; +} isakmp_index; + +struct isakmp_gen; +struct sched; + +struct sockaddr; +struct ph1handle; +struct ph2handle; +struct remoteconf; +struct ipsecdoi_pl_id; /* XXX */ +struct isakmp_pl_ke; /* XXX */ +struct isakmp_pl_nonce; /* XXX */ + +extern struct ph1handle *isakmp_ph1begin_i __P((struct remoteconf *, + struct sockaddr *, struct sockaddr *)); + +extern vchar_t *isakmp_parsewoh __P((int, struct isakmp_gen *, int)); +extern vchar_t *isakmp_parse __P((vchar_t *)); + +extern int isakmp_init __P((void)); +extern const char *isakmp_pindex __P((const isakmp_index *, const u_int32_t)); +extern int isakmp_open __P((struct sockaddr *, int)); +extern void isakmp_close __P((int fd)); +extern int isakmp_send __P((struct ph1handle *, vchar_t *)); + +extern int isakmp_ph1send __P((struct ph1handle *)); +extern int isakmp_ph2send __P((struct ph2handle *)); +extern void isakmp_ph1dying_stub __P((struct sched *)); +extern void isakmp_ph1dying __P((struct ph1handle *)); +extern void isakmp_ph1expire_stub __P((struct sched *)); +extern void isakmp_ph1expire __P((struct ph1handle *)); +extern void isakmp_ph1delete_stub __P((struct sched *)); +extern void isakmp_ph1delete __P((struct ph1handle *)); +extern void isakmp_ph2expire_stub __P((struct sched *)); +extern void isakmp_ph2expire __P((struct ph2handle *)); +extern void isakmp_ph2delete_stub __P((struct sched *)); +extern void isakmp_ph2delete __P((struct ph2handle *)); + +extern int isakmp_get_sainfo __P((struct ph2handle *, struct secpolicy *, struct secpolicy *)); +extern int isakmp_post_acquire __P((struct ph2handle *, struct ph1handle *, int)); +extern int isakmp_post_getspi __P((struct ph2handle *)); +extern void isakmp_chkph1there_stub __P((struct sched *)); +extern void isakmp_chkph1there __P((struct ph2handle *)); + +extern caddr_t isakmp_set_attr_v __P((caddr_t, int, caddr_t, int)); +extern caddr_t isakmp_set_attr_l __P((caddr_t, int, u_int32_t)); +extern vchar_t *isakmp_add_attr_v __P((vchar_t *, int, caddr_t, int)); +extern vchar_t *isakmp_add_attr_l __P((vchar_t *, int, u_int32_t)); + +extern int isakmp_newcookie __P((caddr_t, struct sockaddr *, struct sockaddr *)); + +extern int isakmp_p2ph __P((vchar_t **, struct isakmp_gen *)); + +extern u_int32_t isakmp_newmsgid2 __P((struct ph1handle *)); +extern caddr_t set_isakmp_header1 __P((vchar_t *, struct ph1handle *, int)); +extern caddr_t set_isakmp_header2 __P((vchar_t *, struct ph2handle *, int)); +extern caddr_t set_isakmp_payload __P((caddr_t, vchar_t *, int)); + +extern struct payload_list *isakmp_plist_append_full __P(( + struct payload_list *plist, vchar_t *payload, + u_int8_t payload_type, u_int8_t free)); + +static inline struct payload_list *isakmp_plist_append(plist, payload, payload_type) + struct payload_list *plist; + vchar_t *payload; + u_int8_t payload_type; +{ + return isakmp_plist_append_full(plist, payload, payload_type, 0); +} + + +extern vchar_t *isakmp_plist_set_all __P((struct payload_list **plist, + struct ph1handle *iph1)); + +#ifdef HAVE_PRINT_ISAKMP_C +extern void isakmp_printpacket __P((vchar_t *, struct sockaddr *, + struct sockaddr *, int)); +#endif + +extern int copy_ph1addresses __P(( struct ph1handle *, + struct remoteconf *, struct sockaddr *, struct sockaddr *)); +extern void log_ph1established __P((const struct ph1handle *)); + +extern void script_hook __P((struct ph1handle *, int)); +extern int script_env_append __P((char ***, int *, char *, char *)); +extern int script_exec __P((char *, int, char * const *)); + +void purge_remote __P((struct ph1handle *)); +void delete_spd __P((struct ph2handle *, u_int64_t)); +#ifdef INET6 +u_int32_t setscopeid __P((struct sockaddr *, struct sockaddr *)); +#endif + +#endif /* _ISAKMP_VAR_H */ diff --git a/ipsec-tools/src/racoon/isakmp_xauth.c b/ipsec-tools/src/racoon/isakmp_xauth.c new file mode 100644 index 00000000..94c72d6d --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_xauth.c @@ -0,0 +1,1809 @@ +/* $NetBSD: isakmp_xauth.c,v 1.22.2.1 2013/02/05 06:23:42 tteras Exp $ */ + +/* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */ + +/* + * Copyright (C) 2004-2005 Emmanuel Dreyfus + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include + +#ifdef HAVE_SHADOW_H +#include +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "schedule.h" +#include "debug.h" + +#include "crypto_openssl.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "admin.h" +#include "privsep.h" +#include "evt.h" +#include "handler.h" +#include "throttle.h" +#include "remoteconf.h" +#include "isakmp_inf.h" +#include "isakmp_xauth.h" +#include "isakmp_unity.h" +#include "isakmp_cfg.h" +#include "strnames.h" +#include "ipsec_doi.h" +#include "remoteconf.h" +#include "localconf.h" + +#ifdef HAVE_LIBRADIUS +#include +struct rad_handle *radius_auth_state = NULL; +struct rad_handle *radius_acct_state = NULL; +struct xauth_rad_config xauth_rad_config; +#endif + +#ifdef HAVE_LIBPAM +#include + +static char *PAM_usr = NULL; +static char *PAM_pwd = NULL; +static int PAM_conv(int, const struct pam_message **, + struct pam_response **, void *); +static struct pam_conv PAM_chat = { &PAM_conv, NULL }; +#endif + +#ifdef HAVE_LIBLDAP +#include "ldap.h" +#include +struct xauth_ldap_config xauth_ldap_config; +#endif + +void +xauth_sendreq(iph1) + struct ph1handle *iph1; +{ + vchar_t *buffer; + struct isakmp_pl_attr *attr; + struct isakmp_data *typeattr; + struct isakmp_data *usrattr; + struct isakmp_data *pwdattr; + struct xauth_state *xst = &iph1->mode_cfg->xauth; + size_t tlen; + + /* Status checks */ + if (iph1->status < PHASE1ST_ESTABLISHED) { + plog(LLV_ERROR, LOCATION, NULL, + "Xauth request while phase 1 is not completed\n"); + return; + } + + if (xst->status != XAUTHST_NOTYET) { + plog(LLV_ERROR, LOCATION, NULL, + "Xauth request whith Xauth state %d\n", xst->status); + return; + } + + plog(LLV_INFO, LOCATION, NULL, "Sending Xauth request\n"); + + tlen = sizeof(*attr) + + + sizeof(*typeattr) + + + sizeof(*usrattr) + + + sizeof(*pwdattr); + + if ((buffer = vmalloc(tlen)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n"); + return; + } + + attr = (struct isakmp_pl_attr *)buffer->v; + memset(attr, 0, tlen); + + attr->h.len = htons(tlen); + attr->type = ISAKMP_CFG_REQUEST; + attr->id = htons(eay_random()); + + typeattr = (struct isakmp_data *)(attr + 1); + typeattr->type = htons(XAUTH_TYPE | ISAKMP_GEN_TV); + typeattr->lorv = htons(XAUTH_TYPE_GENERIC); + + usrattr = (struct isakmp_data *)(typeattr + 1); + usrattr->type = htons(XAUTH_USER_NAME | ISAKMP_GEN_TLV); + usrattr->lorv = htons(0); + + pwdattr = (struct isakmp_data *)(usrattr + 1); + pwdattr->type = htons(XAUTH_USER_PASSWORD | ISAKMP_GEN_TLV); + pwdattr->lorv = htons(0); + + isakmp_cfg_send(iph1, buffer, + ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1); + + vfree(buffer); + + xst->status = XAUTHST_REQSENT; + + return; +} + +int +xauth_attr_reply(iph1, attr, id) + struct ph1handle *iph1; + struct isakmp_data *attr; + int id; +{ + char **outlet = NULL; + size_t alen = 0; + int type; + struct xauth_state *xst = &iph1->mode_cfg->xauth; + + if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Xauth reply but peer did not declare " + "itself as Xauth capable\n"); + return -1; + } + + if (xst->status != XAUTHST_REQSENT) { + plog(LLV_ERROR, LOCATION, NULL, + "Xauth reply while Xauth state is %d\n", xst->status); + return -1; + } + + type = ntohs(attr->type) & ~ISAKMP_GEN_MASK; + switch (type) { + case XAUTH_TYPE: + switch (ntohs(attr->lorv)) { + case XAUTH_TYPE_GENERIC: + xst->authtype = XAUTH_TYPE_GENERIC; + break; + default: + plog(LLV_WARNING, LOCATION, NULL, + "Unexpected authentication type %d\n", + ntohs(type)); + return -1; + } + break; + + case XAUTH_USER_NAME: + outlet = &xst->authdata.generic.usr; + break; + + case XAUTH_USER_PASSWORD: + outlet = &xst->authdata.generic.pwd; + break; + + default: + plog(LLV_WARNING, LOCATION, NULL, + "ignored Xauth attribute %d\n", type); + break; + } + + if (outlet != NULL) { + alen = ntohs(attr->lorv); + + if ((*outlet = racoon_malloc(alen + 1)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory for Xauth Data\n"); + return -1; + } + + memcpy(*outlet, attr + 1, alen); + (*outlet)[alen] = '\0'; + outlet = NULL; + } + + + if ((xst->authdata.generic.usr != NULL) && + (xst->authdata.generic.pwd != NULL)) { + int port; + int res; + char *usr = xst->authdata.generic.usr; + char *pwd = xst->authdata.generic.pwd; + time_t throttle_delay = 0; + +#if 0 /* Real debug, don't do that at home */ + plog(LLV_DEBUG, LOCATION, NULL, + "Got username \"%s\", password \"%s\"\n", usr, pwd); +#endif + strncpy(iph1->mode_cfg->login, usr, LOGINLEN); + iph1->mode_cfg->login[LOGINLEN] = '\0'; + + res = -1; + if ((port = isakmp_cfg_getport(iph1)) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "Port pool depleted\n"); + goto skip_auth; + } + + switch (isakmp_cfg_config.authsource) { + case ISAKMP_CFG_AUTH_SYSTEM: + res = privsep_xauth_login_system(usr, pwd); + break; +#ifdef HAVE_LIBRADIUS + case ISAKMP_CFG_AUTH_RADIUS: + res = xauth_login_radius(iph1, usr, pwd); + break; +#endif +#ifdef HAVE_LIBPAM + case ISAKMP_CFG_AUTH_PAM: + res = privsep_xauth_login_pam(iph1->mode_cfg->port, + iph1->remote, usr, pwd); + break; +#endif +#ifdef HAVE_LIBLDAP + case ISAKMP_CFG_AUTH_LDAP: + res = xauth_login_ldap(iph1, usr, pwd); + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "Unexpected authentication source\n"); + res = -1; + break; + } + + /* + * Optional group authentication + */ + if (!res && (isakmp_cfg_config.groupcount)) + res = group_check(iph1, + isakmp_cfg_config.grouplist, + isakmp_cfg_config.groupcount); + + /* + * On failure, throttle the connexion for the remote host + * in order to make password attacks more difficult. + */ + throttle_delay = throttle_host(iph1->remote, res); + if (throttle_delay > 0) { + char *str; + + str = saddrwop2str(iph1->remote); + + plog(LLV_ERROR, LOCATION, NULL, + "Throttling in action for %s: delay %lds\n", + str, (unsigned long)throttle_delay); + res = -1; + } else { + throttle_delay = 0; + } + +skip_auth: + if (throttle_delay != 0) { + struct xauth_reply_arg *xra; + + if ((xra = racoon_calloc(1, sizeof(*xra))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "malloc failed, bypass throttling\n"); + return xauth_reply(iph1, port, id, res); + } + + /* + * We need to store the ph1, but it might have + * disapeared when xauth_reply is called, so + * store the index instead. + */ + xra->index = iph1->index; + xra->port = port; + xra->id = id; + xra->res = res; + sched_schedule(&xra->sc, throttle_delay, + xauth_reply_stub); + } else { + return xauth_reply(iph1, port, id, res); + } + } + + return 0; +} + +void +xauth_reply_stub(sc) + struct sched *sc; +{ + struct xauth_reply_arg *xra = container_of(sc, struct xauth_reply_arg, sc); + struct ph1handle *iph1; + + if ((iph1 = getph1byindex(&xra->index)) != NULL) + (void)xauth_reply(iph1, xra->port, xra->id, xra->res); + else + plog(LLV_ERROR, LOCATION, NULL, + "Delayed Xauth reply: phase 1 no longer exists.\n"); + + racoon_free(xra); +} + +int +xauth_reply(iph1, port, id, res) + struct ph1handle *iph1; + int port; + int id; +{ + struct xauth_state *xst = &iph1->mode_cfg->xauth; + char *usr = xst->authdata.generic.usr; + + if (res != 0) { + if (port != -1) + isakmp_cfg_putport(iph1, port); + + plog(LLV_INFO, LOCATION, NULL, + "login failed for user \"%s\"\n", usr); + + xauth_sendstatus(iph1, XAUTH_STATUS_FAIL, id); + xst->status = XAUTHST_NOTYET; + + /* Delete Phase 1 SA */ + if (iph1->status >= PHASE1ST_ESTABLISHED) + isakmp_info_send_d1(iph1); + remph1(iph1); + delph1(iph1); + + return -1; + } + + xst->status = XAUTHST_OK; + plog(LLV_INFO, LOCATION, NULL, + "login succeeded for user \"%s\"\n", usr); + + xauth_sendstatus(iph1, XAUTH_STATUS_OK, id); + + return 0; +} + +void +xauth_sendstatus(iph1, status, id) + struct ph1handle *iph1; + int status; + int id; +{ + vchar_t *buffer; + struct isakmp_pl_attr *attr; + struct isakmp_data *stattr; + size_t tlen; + + tlen = sizeof(*attr) + + + sizeof(*stattr); + + if ((buffer = vmalloc(tlen)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n"); + return; + } + + attr = (struct isakmp_pl_attr *)buffer->v; + memset(attr, 0, tlen); + + attr->h.len = htons(tlen); + attr->type = ISAKMP_CFG_SET; + attr->id = htons(id); + + stattr = (struct isakmp_data *)(attr + 1); + stattr->type = htons(XAUTH_STATUS | ISAKMP_GEN_TV); + stattr->lorv = htons(status); + + isakmp_cfg_send(iph1, buffer, + ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1); + + vfree(buffer); + + return; +} + +#ifdef HAVE_LIBRADIUS +int +xauth_radius_init_conf(int free) +{ + /* free radius config resources */ + if (free) { + int i; + for (i = 0; i < xauth_rad_config.auth_server_count; i++) { + vfree(xauth_rad_config.auth_server_list[i].host); + vfree(xauth_rad_config.auth_server_list[i].secret); + } + for (i = 0; i < xauth_rad_config.acct_server_count; i++) { + vfree(xauth_rad_config.acct_server_list[i].host); + vfree(xauth_rad_config.acct_server_list[i].secret); + } + if (radius_auth_state != NULL) { + rad_close(radius_auth_state); + radius_auth_state = NULL; + } + if (radius_acct_state != NULL) { + rad_close(radius_acct_state); + radius_acct_state = NULL; + } + } + + /* initialize radius config */ + memset(&xauth_rad_config, 0, sizeof(xauth_rad_config)); + return 0; +} + +int +xauth_radius_init(void) +{ + /* For first time use, initialize Radius */ + if ((isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_RADIUS) && + (radius_auth_state == NULL)) { + if ((radius_auth_state = rad_auth_open()) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot init libradius\n"); + return -1; + } + + int auth_count = xauth_rad_config.auth_server_count; + int auth_added = 0; + if (auth_count) { + int i; + for (i = 0; i < auth_count; i++) { + if(!rad_add_server( + radius_auth_state, + xauth_rad_config.auth_server_list[i].host->v, + xauth_rad_config.auth_server_list[i].port, + xauth_rad_config.auth_server_list[i].secret->v, + xauth_rad_config.timeout, + xauth_rad_config.retries )) + auth_added++; + else + plog(LLV_WARNING, LOCATION, NULL, + "could not add radius auth server %s\n", + xauth_rad_config.auth_server_list[i].host->v); + } + } + + if (!auth_added) { + if (rad_config(radius_auth_state, NULL) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot open libradius config file: %s\n", + rad_strerror(radius_auth_state)); + rad_close(radius_auth_state); + radius_auth_state = NULL; + return -1; + } + } + } + + if ((isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) && + (radius_acct_state == NULL)) { + if ((radius_acct_state = rad_acct_open()) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot init libradius\n"); + return -1; + } + + int acct_count = xauth_rad_config.acct_server_count; + int acct_added = 0; + if (acct_count) { + int i; + for (i = 0; i < acct_count; i++) { + if(!rad_add_server( + radius_acct_state, + xauth_rad_config.acct_server_list[i].host->v, + xauth_rad_config.acct_server_list[i].port, + xauth_rad_config.acct_server_list[i].secret->v, + xauth_rad_config.timeout, + xauth_rad_config.retries )) + acct_added++; + else + plog(LLV_WARNING, LOCATION, NULL, + "could not add radius account server %s\n", + xauth_rad_config.acct_server_list[i].host->v); + } + } + + if (!acct_added) { + if (rad_config(radius_acct_state, NULL) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot open libradius config file: %s\n", + rad_strerror(radius_acct_state)); + rad_close(radius_acct_state); + radius_acct_state = NULL; + return -1; + } + } + } + + return 0; +} + +int +xauth_login_radius(iph1, usr, pwd) + struct ph1handle *iph1; + char *usr; + char *pwd; +{ + int res; + const void *data; + size_t len; + int type; + + if (rad_create_request(radius_auth_state, RAD_ACCESS_REQUEST) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_create_request failed: %s\n", + rad_strerror(radius_auth_state)); + return -1; + } + + if (rad_put_string(radius_auth_state, RAD_USER_NAME, usr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_put_string failed: %s\n", + rad_strerror(radius_auth_state)); + return -1; + } + + if (rad_put_string(radius_auth_state, RAD_USER_PASSWORD, pwd) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "rad_put_string failed: %s\n", + rad_strerror(radius_auth_state)); + return -1; + } + + if (isakmp_cfg_radius_common(radius_auth_state, iph1->mode_cfg->port) != 0) + return -1; + + switch (res = rad_send_request(radius_auth_state)) { + case RAD_ACCESS_ACCEPT: + while ((type = rad_get_attr(radius_auth_state, &data, &len)) != 0) { + switch (type) { + case RAD_FRAMED_IP_ADDRESS: + iph1->mode_cfg->addr4 = rad_cvt_addr(data); + iph1->mode_cfg->flags + |= ISAKMP_CFG_ADDR4_EXTERN; + break; + + case RAD_FRAMED_IP_NETMASK: + iph1->mode_cfg->mask4 = rad_cvt_addr(data); + iph1->mode_cfg->flags + |= ISAKMP_CFG_MASK4_EXTERN; + break; + + default: + plog(LLV_INFO, LOCATION, NULL, + "Unexpected attribute: %d\n", type); + break; + } + } + + return 0; + break; + + case RAD_ACCESS_REJECT: + return -1; + break; + + case -1: + plog(LLV_ERROR, LOCATION, NULL, + "rad_send_request failed: %s\n", + rad_strerror(radius_auth_state)); + return -1; + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "rad_send_request returned %d\n", res); + return -1; + break; + } + + return -1; +} +#endif + +#ifdef HAVE_LIBPAM +static int +PAM_conv(msg_count, msg, rsp, dontcare) + int msg_count; + const struct pam_message **msg; + struct pam_response **rsp; + void *dontcare; +{ + int i; + int replies = 0; + struct pam_response *reply = NULL; + + if ((reply = racoon_malloc(sizeof(*reply) * msg_count)) == NULL) + return PAM_CONV_ERR; + bzero(reply, sizeof(*reply) * msg_count); + + for (i = 0; i < msg_count; i++) { + switch (msg[i]->msg_style) { + case PAM_PROMPT_ECHO_ON: + /* Send the username, libpam frees resp */ + reply[i].resp_retcode = PAM_SUCCESS; + if ((reply[i].resp = strdup(PAM_usr)) == NULL) { + plog(LLV_ERROR, LOCATION, + NULL, "strdup failed\n"); + exit(1); + } + break; + + case PAM_PROMPT_ECHO_OFF: + /* Send the password, libpam frees resp */ + reply[i].resp_retcode = PAM_SUCCESS; + if ((reply[i].resp = strdup(PAM_pwd)) == NULL) { + plog(LLV_ERROR, LOCATION, + NULL, "strdup failed\n"); + exit(1); + } + break; + + case PAM_TEXT_INFO: + case PAM_ERROR_MSG: + reply[i].resp_retcode = PAM_SUCCESS; + reply[i].resp = NULL; + break; + + default: + if (reply != NULL) + racoon_free(reply); + return PAM_CONV_ERR; + break; + } + } + + if (reply != NULL) + *rsp = reply; + + return PAM_SUCCESS; +} + +int +xauth_login_pam(port, raddr, usr, pwd) + int port; + struct sockaddr *raddr; + char *usr; + char *pwd; +{ + int error; + int res; + const void *data; + size_t len; + int type; + char *remote = NULL; + pam_handle_t *pam = NULL; + + if (isakmp_cfg_config.port_pool == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "isakmp_cfg_config.port_pool == NULL\n"); + return -1; + } + + if ((error = pam_start("racoon", usr, + &PAM_chat, &isakmp_cfg_config.port_pool[port].pam)) != 0) { + if (isakmp_cfg_config.port_pool[port].pam == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "pam_start failed\n"); + return -1; + } else { + plog(LLV_ERROR, LOCATION, NULL, + "pam_start failed: %s\n", + pam_strerror(isakmp_cfg_config.port_pool[port].pam, + error)); + goto out; + } + } + pam = isakmp_cfg_config.port_pool[port].pam; + + if ((remote = strdup(saddrwop2str(raddr))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot allocate memory: %s\n", strerror(errno)); + goto out; + } + + if ((error = pam_set_item(pam, PAM_RHOST, remote)) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "pam_set_item failed: %s\n", + pam_strerror(pam, error)); + goto out; + } + + if ((error = pam_set_item(pam, PAM_RUSER, usr)) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "pam_set_item failed: %s\n", + pam_strerror(pam, error)); + goto out; + } + + PAM_usr = usr; + PAM_pwd = pwd; + error = pam_authenticate(pam, 0); + PAM_usr = NULL; + PAM_pwd = NULL; + if (error != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "pam_authenticate failed: %s\n", + pam_strerror(pam, error)); + goto out; + } + + if ((error = pam_acct_mgmt(pam, 0)) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "pam_acct_mgmt failed: %s\n", + pam_strerror(pam, error)); + goto out; + } + + if ((error = pam_setcred(pam, 0)) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "pam_setcred failed: %s\n", + pam_strerror(pam, error)); + goto out; + } + + if (remote != NULL) + free(remote); + + return 0; + +out: + pam_end(pam, error); + isakmp_cfg_config.port_pool[port].pam = NULL; + if (remote != NULL) + free(remote); + return -1; +} +#endif + +#ifdef HAVE_LIBLDAP +int +xauth_ldap_init_conf(void) +{ + int tmplen; + int error = -1; + + xauth_ldap_config.pver = 3; + xauth_ldap_config.host = NULL; + xauth_ldap_config.port = LDAP_PORT; + xauth_ldap_config.base = NULL; + xauth_ldap_config.subtree = 0; + xauth_ldap_config.bind_dn = NULL; + xauth_ldap_config.bind_pw = NULL; + xauth_ldap_config.auth_type = LDAP_AUTH_SIMPLE; + xauth_ldap_config.attr_user = NULL; + xauth_ldap_config.attr_addr = NULL; + xauth_ldap_config.attr_mask = NULL; + xauth_ldap_config.attr_group = NULL; + xauth_ldap_config.attr_member = NULL; + + /* set default host */ + tmplen = strlen(LDAP_DFLT_HOST); + xauth_ldap_config.host = vmalloc(tmplen); + if (xauth_ldap_config.host == NULL) + goto out; + memcpy(xauth_ldap_config.host->v, LDAP_DFLT_HOST, tmplen); + + /* set default user naming attribute */ + tmplen = strlen(LDAP_DFLT_USER); + xauth_ldap_config.attr_user = vmalloc(tmplen); + if (xauth_ldap_config.attr_user == NULL) + goto out; + memcpy(xauth_ldap_config.attr_user->v, LDAP_DFLT_USER, tmplen); + + /* set default address attribute */ + tmplen = strlen(LDAP_DFLT_ADDR); + xauth_ldap_config.attr_addr = vmalloc(tmplen); + if (xauth_ldap_config.attr_addr == NULL) + goto out; + memcpy(xauth_ldap_config.attr_addr->v, LDAP_DFLT_ADDR, tmplen); + + /* set default netmask attribute */ + tmplen = strlen(LDAP_DFLT_MASK); + xauth_ldap_config.attr_mask = vmalloc(tmplen); + if (xauth_ldap_config.attr_mask == NULL) + goto out; + memcpy(xauth_ldap_config.attr_mask->v, LDAP_DFLT_MASK, tmplen); + + /* set default group naming attribute */ + tmplen = strlen(LDAP_DFLT_GROUP); + xauth_ldap_config.attr_group = vmalloc(tmplen); + if (xauth_ldap_config.attr_group == NULL) + goto out; + memcpy(xauth_ldap_config.attr_group->v, LDAP_DFLT_GROUP, tmplen); + + /* set default member attribute */ + tmplen = strlen(LDAP_DFLT_MEMBER); + xauth_ldap_config.attr_member = vmalloc(tmplen); + if (xauth_ldap_config.attr_member == NULL) + goto out; + memcpy(xauth_ldap_config.attr_member->v, LDAP_DFLT_MEMBER, tmplen); + + error = 0; +out: + if (error != 0) + plog(LLV_ERROR, LOCATION, NULL, "cannot allocate memory\n"); + + return error; +} + +int +xauth_login_ldap(iph1, usr, pwd) + struct ph1handle *iph1; + char *usr; + char *pwd; +{ + int rtn = -1; + int res = -1; + LDAP *ld = NULL; + LDAPMessage *lr = NULL; + LDAPMessage *le = NULL; + struct berval cred; + struct berval **bv = NULL; + struct timeval timeout; + char *init = NULL; + char *filter = NULL; + char *atlist[3]; + char *basedn = NULL; + char *userdn = NULL; + int tmplen = 0; + int ecount = 0; + int scope = LDAP_SCOPE_ONE; + + atlist[0] = NULL; + atlist[1] = NULL; + atlist[2] = NULL; + + /* build our initialization url */ + tmplen = strlen("ldap://:") + 17; + tmplen += strlen(xauth_ldap_config.host->v); + init = racoon_malloc(tmplen); + if (init == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to alloc ldap init url\n"); + goto ldap_end; + } + sprintf(init,"ldap://%s:%d", + xauth_ldap_config.host->v, + xauth_ldap_config.port ); + + /* initialize the ldap handle */ + res = ldap_initialize(&ld, init); + if (res != LDAP_SUCCESS) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_initialize failed: %s\n", + ldap_err2string(res)); + goto ldap_end; + } + + /* initialize the protocol version */ + ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, + &xauth_ldap_config.pver); + + /* + * attempt to bind to the ldap server. + * default to anonymous bind unless a + * user dn and password has been + * specified in our configuration + */ + if ((xauth_ldap_config.bind_dn != NULL)&& + (xauth_ldap_config.bind_pw != NULL)) + { + cred.bv_val = xauth_ldap_config.bind_pw->v; + cred.bv_len = strlen( cred.bv_val ); + res = ldap_sasl_bind_s(ld, + xauth_ldap_config.bind_dn->v, NULL, &cred, + NULL, NULL, NULL); + } + else + { + res = ldap_sasl_bind_s(ld, + NULL, NULL, NULL, + NULL, NULL, NULL); + } + + if (res!=LDAP_SUCCESS) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_sasl_bind_s (search) failed: %s\n", + ldap_err2string(res)); + goto ldap_end; + } + + /* build an ldap user search filter */ + tmplen = strlen(xauth_ldap_config.attr_user->v); + tmplen += 1; + tmplen += strlen(usr); + tmplen += 1; + filter = racoon_malloc(tmplen); + if (filter == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to alloc ldap search filter buffer\n"); + goto ldap_end; + } + sprintf(filter, "%s=%s", + xauth_ldap_config.attr_user->v, usr); + + /* build our return attribute list */ + tmplen = strlen(xauth_ldap_config.attr_addr->v) + 1; + atlist[0] = racoon_malloc(tmplen); + tmplen = strlen(xauth_ldap_config.attr_mask->v) + 1; + atlist[1] = racoon_malloc(tmplen); + if ((atlist[0] == NULL)||(atlist[1] == NULL)) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to alloc ldap attrib list buffer\n"); + goto ldap_end; + } + strcpy(atlist[0],xauth_ldap_config.attr_addr->v); + strcpy(atlist[1],xauth_ldap_config.attr_mask->v); + + /* attempt to locate the user dn */ + if (xauth_ldap_config.base != NULL) + basedn = xauth_ldap_config.base->v; + if (xauth_ldap_config.subtree) + scope = LDAP_SCOPE_SUBTREE; + timeout.tv_sec = 15; + timeout.tv_usec = 0; + res = ldap_search_ext_s(ld, basedn, scope, + filter, atlist, 0, NULL, NULL, + &timeout, 2, &lr); + if (res != LDAP_SUCCESS) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_search_ext_s failed: %s\n", + ldap_err2string(res)); + goto ldap_end; + } + + /* check the number of ldap entries returned */ + ecount = ldap_count_entries(ld, lr); + if (ecount < 1) { + plog(LLV_WARNING, LOCATION, NULL, + "no ldap results for filter \'%s\'\n", + filter); + goto ldap_end; + } + if (ecount > 1) { + plog(LLV_WARNING, LOCATION, NULL, + "multiple (%i) ldap results for filter \'%s\'\n", + ecount, filter); + } + + /* obtain the dn from the first result */ + le = ldap_first_entry(ld, lr); + if (le == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_first_entry failed: invalid entry returned\n"); + goto ldap_end; + } + userdn = ldap_get_dn(ld, le); + if (userdn == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_get_dn failed: invalid string returned\n"); + goto ldap_end; + } + + /* cache the user dn in the xauth state */ + iph1->mode_cfg->xauth.udn = racoon_malloc(strlen(userdn)+1); + strcpy(iph1->mode_cfg->xauth.udn,userdn); + + /* retrieve modecfg address */ + bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_addr->v); + if (bv != NULL) { + char tmpaddr[16]; + /* sanity check for address value */ + if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) { + plog(LLV_DEBUG, LOCATION, NULL, + "ldap returned invalid modecfg address\n"); + ldap_value_free_len(bv); + goto ldap_end; + } + memcpy(tmpaddr,bv[0]->bv_val,bv[0]->bv_len); + tmpaddr[bv[0]->bv_len]=0; + iph1->mode_cfg->addr4.s_addr = inet_addr(tmpaddr); + iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_EXTERN; + plog(LLV_INFO, LOCATION, NULL, + "ldap returned modecfg address %s\n", tmpaddr); + ldap_value_free_len(bv); + } + + /* retrieve modecfg netmask */ + bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_mask->v); + if (bv != NULL) { + char tmpmask[16]; + /* sanity check for netmask value */ + if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) { + plog(LLV_DEBUG, LOCATION, NULL, + "ldap returned invalid modecfg netmask\n"); + ldap_value_free_len(bv); + goto ldap_end; + } + memcpy(tmpmask,bv[0]->bv_val,bv[0]->bv_len); + tmpmask[bv[0]->bv_len]=0; + iph1->mode_cfg->mask4.s_addr = inet_addr(tmpmask); + iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_EXTERN; + plog(LLV_INFO, LOCATION, NULL, + "ldap returned modecfg netmask %s\n", tmpmask); + ldap_value_free_len(bv); + } + + /* + * finally, use the dn and the xauth + * password to check the users given + * credentials by attempting to bind + * to the ldap server + */ + plog(LLV_INFO, LOCATION, NULL, + "attempting ldap bind for dn \'%s\'\n", userdn); + cred.bv_val = pwd; + cred.bv_len = strlen( cred.bv_val ); + res = ldap_sasl_bind_s(ld, + userdn, NULL, &cred, + NULL, NULL, NULL); + if(res==LDAP_SUCCESS) + rtn = 0; + +ldap_end: + + /* free ldap resources */ + if (userdn != NULL) + ldap_memfree(userdn); + if (atlist[0] != NULL) + racoon_free(atlist[0]); + if (atlist[1] != NULL) + racoon_free(atlist[1]); + if (filter != NULL) + racoon_free(filter); + if (lr != NULL) + ldap_msgfree(lr); + if (init != NULL) + racoon_free(init); + + ldap_unbind_ext_s(ld, NULL, NULL); + + return rtn; +} + +int +xauth_group_ldap(udn, grp) + char * udn; + char * grp; +{ + int rtn = -1; + int res = -1; + LDAP *ld = NULL; + LDAPMessage *lr = NULL; + LDAPMessage *le = NULL; + struct berval cred; + struct timeval timeout; + char *init = NULL; + char *filter = NULL; + char *basedn = NULL; + char *groupdn = NULL; + int tmplen = 0; + int ecount = 0; + int scope = LDAP_SCOPE_ONE; + + /* build our initialization url */ + tmplen = strlen("ldap://:") + 17; + tmplen += strlen(xauth_ldap_config.host->v); + init = racoon_malloc(tmplen); + if (init == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to alloc ldap init url\n"); + goto ldap_group_end; + } + sprintf(init,"ldap://%s:%d", + xauth_ldap_config.host->v, + xauth_ldap_config.port ); + + /* initialize the ldap handle */ + res = ldap_initialize(&ld, init); + if (res != LDAP_SUCCESS) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_initialize failed: %s\n", + ldap_err2string(res)); + goto ldap_group_end; + } + + /* initialize the protocol version */ + ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, + &xauth_ldap_config.pver); + + /* + * attempt to bind to the ldap server. + * default to anonymous bind unless a + * user dn and password has been + * specified in our configuration + */ + if ((xauth_ldap_config.bind_dn != NULL)&& + (xauth_ldap_config.bind_pw != NULL)) + { + cred.bv_val = xauth_ldap_config.bind_pw->v; + cred.bv_len = strlen( cred.bv_val ); + res = ldap_sasl_bind_s(ld, + xauth_ldap_config.bind_dn->v, NULL, &cred, + NULL, NULL, NULL); + } + else + { + res = ldap_sasl_bind_s(ld, + NULL, NULL, NULL, + NULL, NULL, NULL); + } + + if (res!=LDAP_SUCCESS) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_sasl_bind_s (search) failed: %s\n", + ldap_err2string(res)); + goto ldap_group_end; + } + + /* build an ldap group search filter */ + tmplen = strlen("(&(=)(=))") + 1; + tmplen += strlen(xauth_ldap_config.attr_group->v); + tmplen += strlen(grp); + tmplen += strlen(xauth_ldap_config.attr_member->v); + tmplen += strlen(udn); + filter = racoon_malloc(tmplen); + if (filter == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to alloc ldap search filter buffer\n"); + goto ldap_group_end; + } + sprintf(filter, "(&(%s=%s)(%s=%s))", + xauth_ldap_config.attr_group->v, grp, + xauth_ldap_config.attr_member->v, udn); + + /* attempt to locate the group dn */ + if (xauth_ldap_config.base != NULL) + basedn = xauth_ldap_config.base->v; + if (xauth_ldap_config.subtree) + scope = LDAP_SCOPE_SUBTREE; + timeout.tv_sec = 15; + timeout.tv_usec = 0; + res = ldap_search_ext_s(ld, basedn, scope, + filter, NULL, 0, NULL, NULL, + &timeout, 2, &lr); + if (res != LDAP_SUCCESS) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_search_ext_s failed: %s\n", + ldap_err2string(res)); + goto ldap_group_end; + } + + /* check the number of ldap entries returned */ + ecount = ldap_count_entries(ld, lr); + if (ecount < 1) { + plog(LLV_WARNING, LOCATION, NULL, + "no ldap results for filter \'%s\'\n", + filter); + goto ldap_group_end; + } + + /* success */ + rtn = 0; + + /* obtain the dn from the first result */ + le = ldap_first_entry(ld, lr); + if (le == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_first_entry failed: invalid entry returned\n"); + goto ldap_group_end; + } + groupdn = ldap_get_dn(ld, le); + if (groupdn == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_get_dn failed: invalid string returned\n"); + goto ldap_group_end; + } + + plog(LLV_INFO, LOCATION, NULL, + "ldap membership group returned \'%s\'\n", groupdn); +ldap_group_end: + + /* free ldap resources */ + if (groupdn != NULL) + ldap_memfree(groupdn); + if (filter != NULL) + racoon_free(filter); + if (lr != NULL) + ldap_msgfree(lr); + if (init != NULL) + racoon_free(init); + + ldap_unbind_ext_s(ld, NULL, NULL); + + return rtn; +} + +#endif + +int +xauth_login_system(usr, pwd) + char *usr; + char *pwd; +{ + struct passwd *pw; + char *cryptpwd; + char *syscryptpwd; +#ifdef HAVE_SHADOW_H + struct spwd *spw; + + if ((spw = getspnam(usr)) == NULL) + return -1; + + syscryptpwd = spw->sp_pwdp; +#endif + + if ((pw = getpwnam(usr)) == NULL) + return -1; + +#ifndef HAVE_SHADOW_H + syscryptpwd = pw->pw_passwd; +#endif + + /* No root login. Ever. */ + if (pw->pw_uid == 0) + return -1; + + if ((cryptpwd = crypt(pwd, syscryptpwd)) == NULL) + return -1; + + if (strcmp(cryptpwd, syscryptpwd) == 0) + return 0; + + return -1; +} + +int +xauth_group_system(usr, grp) + char * usr; + char * grp; +{ + struct group * gr; + char * member; + int index = 0; + + gr = getgrnam(grp); + if (gr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "the system group name \'%s\' is unknown\n", + grp); + return -1; + } + + while ((member = gr->gr_mem[index++])!=NULL) { + if (!strcmp(member,usr)) { + plog(LLV_INFO, LOCATION, NULL, + "membership validated\n"); + return 0; + } + } + + return -1; +} + +int +xauth_check(iph1) + struct ph1handle *iph1; +{ + struct xauth_state *xst = &iph1->mode_cfg->xauth; + + /* + * Only the server side (edge device) really check for Xauth + * status. It does it if the chose authmethod is using Xauth. + * On the client side (roadwarrior), we don't check anything. + */ + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + /* The following are not yet implemented */ + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: + if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Hybrid auth negotiated but peer did not " + "announced as Xauth capable\n"); + return -1; + } + + if (xst->status != XAUTHST_OK) { + plog(LLV_ERROR, LOCATION, NULL, + "Hybrid auth negotiated but peer did not " + "succeed Xauth exchange\n"); + return -1; + } + + return 0; + break; + default: + return 0; + break; + } + + return 0; +} + +int +group_check(iph1, grp_list, grp_count) + struct ph1handle *iph1; + char **grp_list; + int grp_count; +{ + int res = -1; + int grp_index = 0; + char * usr = NULL; + + /* check for presence of modecfg data */ + + if(iph1->mode_cfg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "xauth group specified but modecfg not found\n"); + return res; + } + + /* loop through our group list */ + + for(; grp_index < grp_count; grp_index++) { + + /* check for presence of xauth data */ + + usr = iph1->mode_cfg->xauth.authdata.generic.usr; + + if(usr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "xauth group specified but xauth not found\n"); + return res; + } + + /* call appropriate group validation funtion */ + + switch (isakmp_cfg_config.groupsource) { + + case ISAKMP_CFG_GROUP_SYSTEM: + res = xauth_group_system( + usr, + grp_list[grp_index]); + break; + +#ifdef HAVE_LIBLDAP + case ISAKMP_CFG_GROUP_LDAP: + res = xauth_group_ldap( + iph1->mode_cfg->xauth.udn, + grp_list[grp_index]); + break; +#endif + + default: + /* we should never get here */ + plog(LLV_ERROR, LOCATION, NULL, + "Unknown group auth source\n"); + break; + } + + if( !res ) { + plog(LLV_INFO, LOCATION, NULL, + "user \"%s\" is a member of group \"%s\"\n", + usr, + grp_list[grp_index]); + break; + } else { + plog(LLV_INFO, LOCATION, NULL, + "user \"%s\" is not a member of group \"%s\"\n", + usr, + grp_list[grp_index]); + } + } + + return res; +} + +vchar_t * +isakmp_xauth_req(iph1, attr) + struct ph1handle *iph1; + struct isakmp_data *attr; +{ + int type; + size_t dlen = 0; + int ashort = 0; + int value = 0; + vchar_t *buffer = NULL; + char *mraw = NULL, *mdata; + char *data; + vchar_t *usr = NULL; + vchar_t *pwd = NULL; + size_t skip = 0; + int freepwd = 0; + + if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Xauth mode config request but peer " + "did not declare itself as Xauth capable\n"); + return NULL; + } + + type = ntohs(attr->type) & ~ISAKMP_GEN_MASK; + + /* Sanity checks */ + switch(type) { + case XAUTH_TYPE: + if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Unexpected long XAUTH_TYPE attribute\n"); + return NULL; + } + if (ntohs(attr->lorv) != XAUTH_TYPE_GENERIC) { + plog(LLV_ERROR, LOCATION, NULL, + "Unsupported Xauth authentication %d\n", + ntohs(attr->lorv)); + return NULL; + } + ashort = 1; + dlen = 0; + value = XAUTH_TYPE_GENERIC; + break; + + case XAUTH_USER_NAME: + if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) { + plog(LLV_ERROR, LOCATION, NULL, "Xauth performed " + "with no login supplied\n"); + return NULL; + } + + dlen = iph1->rmconf->xauth->login->l - 1; + iph1->rmconf->xauth->state |= XAUTH_SENT_USERNAME; + break; + + case XAUTH_USER_PASSWORD: + if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) + return NULL; + + skip = sizeof(struct ipsecdoi_id_b); + usr = vmalloc(iph1->rmconf->xauth->login->l - 1 + skip); + if (usr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory\n"); + return NULL; + } + memset(usr->v, 0, skip); + memcpy(usr->v + skip, + iph1->rmconf->xauth->login->v, + iph1->rmconf->xauth->login->l - 1); + + if (iph1->rmconf->xauth->pass) { + /* A key given through racoonctl */ + pwd = iph1->rmconf->xauth->pass; + } else { + if ((pwd = getpskbyname(usr)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "No password was found for login %s\n", + iph1->rmconf->xauth->login->v); + vfree(usr); + return NULL; + } + /* We have to free it before returning */ + freepwd = 1; + } + vfree(usr); + + iph1->rmconf->xauth->state |= XAUTH_SENT_PASSWORD; + dlen = pwd->l; + + break; + case XAUTH_MESSAGE: + if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) { + dlen = ntohs(attr->lorv); + if (dlen > 0) { + mraw = (char*)(attr + 1); + mdata = binsanitize(mraw, dlen); + if (mdata == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "Cannot allocate memory\n"); + return NULL; + } + plog(LLV_NOTIFY,LOCATION, iph1->remote, + "XAUTH Message: '%s'.\n", + mdata); + racoon_free(mdata); + } + } + return NULL; + default: + plog(LLV_WARNING, LOCATION, NULL, + "Ignored attribute %s\n", s_isakmp_cfg_type(type)); + return NULL; + break; + } + + if ((buffer = vmalloc(sizeof(*attr) + dlen)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory\n"); + goto out; + } + + attr = (struct isakmp_data *)buffer->v; + if (ashort) { + attr->type = htons(type | ISAKMP_GEN_TV); + attr->lorv = htons(value); + goto out; + } + + attr->type = htons(type | ISAKMP_GEN_TLV); + attr->lorv = htons(dlen); + data = (char *)(attr + 1); + + switch(type) { + case XAUTH_USER_NAME: + /* + * iph1->rmconf->xauth->login->v is valid, + * we just checked it in the previous switch case + */ + memcpy(data, iph1->rmconf->xauth->login->v, dlen); + break; + case XAUTH_USER_PASSWORD: + memcpy(data, pwd->v, dlen); + break; + default: + break; + } + +out: + if (freepwd) + vfree(pwd); + + return buffer; +} + +vchar_t * +isakmp_xauth_set(iph1, attr) + struct ph1handle *iph1; + struct isakmp_data *attr; +{ + int type; + vchar_t *buffer = NULL; + char *data; + struct xauth_state *xst; + size_t dlen = 0; + char* mraw = NULL, *mdata; + + if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Xauth mode config set but peer " + "did not declare itself as Xauth capable\n"); + return NULL; + } + + type = ntohs(attr->type) & ~ISAKMP_GEN_MASK; + + switch(type) { + case XAUTH_STATUS: + /* + * We should only receive ISAKMP mode_cfg SET XAUTH_STATUS + * when running as a client (initiator). + */ + xst = &iph1->mode_cfg->xauth; + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + /* Not implemented ... */ + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "Unexpected XAUTH_STATUS_OK\n"); + return NULL; + break; + } + + /* If we got a failure, delete iph1 */ + if (ntohs(attr->lorv) != XAUTH_STATUS_OK) { + plog(LLV_ERROR, LOCATION, NULL, + "Xauth authentication failed\n"); + + evt_phase1(iph1, EVT_PHASE1_XAUTH_FAILED, NULL); + + iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1; + } else { + evt_phase1(iph1, EVT_PHASE1_XAUTH_SUCCESS, NULL); + } + + + /* We acknowledge it */ + break; + case XAUTH_MESSAGE: + if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) { + dlen = ntohs(attr->lorv); + if (dlen > 0) { + mraw = (char*)(attr + 1); + mdata = binsanitize(mraw, dlen); + if (mdata == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "Cannot allocate memory\n"); + return NULL; + } + plog(LLV_NOTIFY,LOCATION, iph1->remote, + "XAUTH Message: '%s'.\n", + mdata); + racoon_free(mdata); + } + } + + default: + plog(LLV_WARNING, LOCATION, NULL, + "Ignored attribute %s\n", s_isakmp_cfg_type(type)); + return NULL; + break; + } + + if ((buffer = vmalloc(sizeof(*attr))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory\n"); + return NULL; + } + + attr = (struct isakmp_data *)buffer->v; + attr->type = htons(type | ISAKMP_GEN_TV); + attr->lorv = htons(0); + + return buffer; +} + + +void +xauth_rmstate(xst) + struct xauth_state *xst; +{ + switch (xst->authtype) { + case XAUTH_TYPE_GENERIC: + if (xst->authdata.generic.usr) + racoon_free(xst->authdata.generic.usr); + + if (xst->authdata.generic.pwd) + racoon_free(xst->authdata.generic.pwd); + + break; + + case XAUTH_TYPE_CHAP: + case XAUTH_TYPE_OTP: + case XAUTH_TYPE_SKEY: + plog(LLV_WARNING, LOCATION, NULL, + "Unsupported authtype %d\n", xst->authtype); + break; + + default: + plog(LLV_WARNING, LOCATION, NULL, + "Unexpected authtype %d\n", xst->authtype); + break; + } + +#ifdef HAVE_LIBLDAP + if (xst->udn != NULL) + racoon_free(xst->udn); +#endif + return; +} + +int +xauth_rmconf_used(xauth_rmconf) + struct xauth_rmconf **xauth_rmconf; +{ + if (*xauth_rmconf == NULL) { + *xauth_rmconf = racoon_malloc(sizeof(**xauth_rmconf)); + if (*xauth_rmconf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "xauth_rmconf_used: malloc failed\n"); + return -1; + } + + (*xauth_rmconf)->login = NULL; + (*xauth_rmconf)->pass = NULL; + (*xauth_rmconf)->state = 0; + } + + return 0; +} + +void +xauth_rmconf_delete(xauth_rmconf) + struct xauth_rmconf **xauth_rmconf; +{ + if (*xauth_rmconf != NULL) { + if ((*xauth_rmconf)->login != NULL) + vfree((*xauth_rmconf)->login); + if ((*xauth_rmconf)->pass != NULL) + vfree((*xauth_rmconf)->pass); + + racoon_free(*xauth_rmconf); + *xauth_rmconf = NULL; + } + + return; +} + +struct xauth_rmconf * +xauth_rmconf_dup(xauth_rmconf) + struct xauth_rmconf *xauth_rmconf; +{ + struct xauth_rmconf *new; + + if (xauth_rmconf != NULL) { + new = racoon_malloc(sizeof(*new)); + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "xauth_rmconf_dup: malloc failed\n"); + return NULL; + } + + memcpy(new, xauth_rmconf, sizeof(*new)); + + if (xauth_rmconf->login != NULL) { + new->login = vdup(xauth_rmconf->login); + if (new->login == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "xauth_rmconf_dup: malloc failed (login)\n"); + return NULL; + } + } + if (xauth_rmconf->pass != NULL) { + new->pass = vdup(xauth_rmconf->pass); + if (new->pass == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "xauth_rmconf_dup: malloc failed (password)\n"); + return NULL; + } + } + + return new; + } + + return NULL; +} diff --git a/ipsec-tools/src/racoon/isakmp_xauth.h b/ipsec-tools/src/racoon/isakmp_xauth.h new file mode 100644 index 00000000..f9e778fa --- /dev/null +++ b/ipsec-tools/src/racoon/isakmp_xauth.h @@ -0,0 +1,182 @@ +/* $NetBSD: isakmp_xauth.h,v 1.7 2011/03/14 15:50:36 vanhu Exp $ */ + +/* $KAME$ */ + +/* + * Copyright (C) 2004 Emmanuel Dreyfus + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ISAKMP_XAUTH_H +#define _ISAKMP_XAUTH_H + +#include "schedule.h" + +/* ISAKMP mode config attribute types specific to the Xauth vendor ID */ +#define XAUTH_TYPE 16520 +#define XAUTH_USER_NAME 16521 +#define XAUTH_USER_PASSWORD 16522 +#define XAUTH_PASSCODE 16523 +#define XAUTH_MESSAGE 16524 +#define XAUTH_CHALLENGE 16525 +#define XAUTH_DOMAIN 16526 +#define XAUTH_STATUS 16527 +#define XAUTH_NEXT_PIN 16528 +#define XAUTH_ANSWER 16529 + +/* Types for XAUTH_TYPE */ +#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 + +/* For phase 1 Xauth status */ +struct xauth_state { + int status; /* authentication status, used only on server side */ + int vendorid; + int authtype; + union { + struct authgeneric { + char *usr; + char *pwd; + } generic; + } authdata; +#ifdef HAVE_LIBLDAP + char *udn; /* ldap user dn */ +#endif +}; + +/* What's been sent */ +#define XAUTH_SENT_USERNAME 1 +#define XAUTH_SENT_PASSWORD 2 +#define XAUTH_SENT_EVERYTHING (XAUTH_SENT_USERNAME | XAUTH_SENT_PASSWORD) + +/* For rmconf Xauth data */ +struct xauth_rmconf { + vchar_t *login; /* xauth login */ + vchar_t *pass; /* xauth password */ + int state; /* what's been sent */ +}; + +/* status */ +#define XAUTHST_NOTYET 0 +#define XAUTHST_REQSENT 1 +#define XAUTHST_OK 2 + +struct xauth_reply_arg { + struct sched sc; + isakmp_index index; + int port; + int id; + int res; +}; + +struct ph1handle; +struct isakmp_data; +void xauth_sendreq(struct ph1handle *); +int xauth_attr_reply(struct ph1handle *, struct isakmp_data *, int); +int xauth_login_system(char *, char *); +void xauth_sendstatus(struct ph1handle *, int, int); +int xauth_check(struct ph1handle *); +int group_check(struct ph1handle *, char **, int); +vchar_t *isakmp_xauth_req(struct ph1handle *, struct isakmp_data *); +vchar_t *isakmp_xauth_set(struct ph1handle *, struct isakmp_data *); +void xauth_rmstate(struct xauth_state *); +void xauth_reply_stub(struct sched *); +int xauth_reply(struct ph1handle *, int, int, int); +int xauth_rmconf_used(struct xauth_rmconf **); +void xauth_rmconf_delete(struct xauth_rmconf **); +struct xauth_rmconf * xauth_rmconf_dup(struct xauth_rmconf *); + +#ifdef HAVE_LIBPAM +int xauth_login_pam(int, struct sockaddr *, char *, char *); +#endif + +#ifdef HAVE_LIBRADIUS + +#define RADIUS_MAX_SERVERS 5 + +struct rad_serv { + vchar_t *host; + int port; + vchar_t *secret; +}; + +struct xauth_rad_config { + struct rad_serv auth_server_list[RADIUS_MAX_SERVERS]; + int auth_server_count; + struct rad_serv acct_server_list[RADIUS_MAX_SERVERS]; + int acct_server_count; + int timeout; + int retries; +}; + +extern struct xauth_rad_config xauth_rad_config; + +int xauth_radius_init_conf(int free); +int xauth_radius_init(void); +int xauth_login_radius(struct ph1handle *, char *, char *); + +#endif + +#ifdef HAVE_LIBLDAP + +#define LDAP_DFLT_HOST "localhost" +#define LDAP_DFLT_USER "cn" +#define LDAP_DFLT_ADDR "racoon-address" +#define LDAP_DFLT_MASK "racoon-netmask" +#define LDAP_DFLT_GROUP "cn" +#define LDAP_DFLT_MEMBER "member" + +struct xauth_ldap_config { + int pver; + vchar_t *host; + int port; + vchar_t *base; + int subtree; + vchar_t *bind_dn; + vchar_t *bind_pw; + int auth_type; + vchar_t *attr_user; + vchar_t *attr_addr; + vchar_t *attr_mask; + vchar_t *attr_group; + vchar_t *attr_member; +}; + +extern struct xauth_ldap_config xauth_ldap_config; + +int xauth_ldap_init_conf(void); +int xauth_login_ldap(struct ph1handle *, char *, char *); + +#endif + +#endif /* _ISAKMP_XAUTH_H */ diff --git a/ipsec-tools/src/racoon/kmpstat.c b/ipsec-tools/src/racoon/kmpstat.c new file mode 100644 index 00000000..50c478dd --- /dev/null +++ b/ipsec-tools/src/racoon/kmpstat.c @@ -0,0 +1,233 @@ +/* $NetBSD: kmpstat.c,v 1.7 2010/11/12 09:08:26 tteras Exp $ */ + +/* $KAME: kmpstat.c,v 1.33 2004/08/16 08:20:28 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include + +#include "libpfkey.h" + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "debug.h" +#include "sockmisc.h" + +#include "racoonctl.h" +#include "admin.h" +#include "schedule.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "isakmp_xauth.h" +#include "isakmp_var.h" +#include "isakmp_cfg.h" +#include "oakley.h" +#include "handler.h" +#include "pfkey.h" +#include "admin.h" +#include "evt.h" +#include "admin_var.h" +#include "ipsec_doi.h" + +u_int32_t racoonctl_interface = RACOONCTL_INTERFACE; +u_int32_t racoonctl_interface_major = RACOONCTL_INTERFACE_MAJOR; + +static int so; +u_int32_t loglevel = 0; + +int +com_init() +{ + struct sockaddr_un name; + + memset(&name, 0, sizeof(name)); + name.sun_family = AF_UNIX; + snprintf(name.sun_path, sizeof(name.sun_path), + "%s", adminsock_path); + + so = socket(AF_UNIX, SOCK_STREAM, 0); + if (so < 0) + return -1; + + if (connect(so, (struct sockaddr *)&name, sizeof(name)) < 0) { + (void)close(so); + return -1; + } + + return 0; +} + +int +com_send(combuf) + vchar_t *combuf; +{ + int len; + + if ((len = send(so, combuf->v, combuf->l, 0)) == -1) { + perror("send"); + (void)close(so); + return -1; + } + + return 0; +} + +int +com_recv(combufp) + vchar_t **combufp; +{ + struct admin_com h, *com; + caddr_t buf; + int len, rlen; + int l = 0; + caddr_t p; + + if (combufp == NULL) + return -1; + + /* receive by PEEK */ + if ((len = recv(so, &h, sizeof(h), MSG_PEEK)) == -1) + goto bad1; + + /* sanity check */ + if (len < sizeof(h)) + goto bad1; + + if (h.ac_errno && !(h.ac_cmd & ADMIN_FLAG_LONG_REPLY)) { + errno = h.ac_errno; + goto bad1; + } + + /* real length */ + if (h.ac_cmd & ADMIN_FLAG_LONG_REPLY) + rlen = ((u_int32_t)h.ac_len) + (((u_int32_t)h.ac_len_high) << 16); + else + rlen = h.ac_len; + + /* allocate buffer */ + if ((*combufp = vmalloc(rlen)) == NULL) + goto bad1; + + /* read real message */ + p = (*combufp)->v; + while (l < rlen) { + if ((len = recv(so, p, rlen - l, 0)) < 0) { + perror("recv"); + goto bad2; + } + l += len; + p += len; + } + + return 0; + +bad2: + vfree(*combufp); +bad1: + *combufp = NULL; + return -1; +} + +/* + * Dumb plog functions (used by sockmisc.c) + */ +void +_plog(int pri, const char *func, struct sockaddr *sa, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); +} + +void +plogdump(pri, data, len) + int pri; + void *data; + size_t len; +{ + return; +} + +struct sockaddr * +get_sockaddr(family, name, port) + int family; + char *name, *port; +{ + struct addrinfo hint, *ai; + int error; + + memset(&hint, 0, sizeof(hint)); + hint.ai_family = PF_UNSPEC; + hint.ai_family = family; + hint.ai_socktype = SOCK_STREAM; + + error = getaddrinfo(name, port, &hint, &ai); + if (error != 0) { + printf("%s: %s/%s\n", gai_strerror(error), name, port); + return NULL; + } + + return ai->ai_addr; +} diff --git a/ipsec-tools/src/racoon/localconf.c b/ipsec-tools/src/racoon/localconf.c new file mode 100644 index 00000000..a512953b --- /dev/null +++ b/ipsec-tools/src/racoon/localconf.c @@ -0,0 +1,358 @@ +/* $NetBSD: localconf.c,v 1.7 2008/12/23 14:04:42 tteras Exp $ */ + +/* $KAME: localconf.c,v 1.33 2001/08/09 07:32:19 sakane Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "debug.h" + +#include "localconf.h" +#include "algorithm.h" +#include "admin.h" +#include "privsep.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "ipsec_doi.h" +#include "grabmyaddr.h" +#include "vendorid.h" +#include "str2val.h" +#include "safefile.h" +#include "admin.h" +#include "gcmalloc.h" + +struct localconf *lcconf; + +static void setdefault __P((void)); + +void +initlcconf() +{ + lcconf = racoon_calloc(1, sizeof(*lcconf)); + if (lcconf == NULL) + errx(1, "failed to allocate local conf."); + + setdefault(); + + lcconf->racoon_conf = LC_DEFAULT_CF; +} + +void +flushlcconf() +{ + int i; + + setdefault(); + myaddr_flush(); + + for (i = 0; i < LC_PATHTYPE_MAX; i++) { + if (lcconf->pathinfo[i]) { + racoon_free(lcconf->pathinfo[i]); + lcconf->pathinfo[i] = NULL; + } + } +} + +static void +setdefault() +{ + lcconf->uid = 0; + lcconf->gid = 0; + lcconf->chroot = NULL; + lcconf->port_isakmp = PORT_ISAKMP; + lcconf->port_isakmp_natt = PORT_ISAKMP_NATT; + lcconf->default_af = AF_INET; + lcconf->pad_random = LC_DEFAULT_PAD_RANDOM; + lcconf->pad_randomlen = LC_DEFAULT_PAD_RANDOMLEN; + lcconf->pad_maxsize = LC_DEFAULT_PAD_MAXSIZE; + lcconf->pad_strict = LC_DEFAULT_PAD_STRICT; + lcconf->pad_excltail = LC_DEFAULT_PAD_EXCLTAIL; + lcconf->retry_counter = LC_DEFAULT_RETRY_COUNTER; + lcconf->retry_interval = LC_DEFAULT_RETRY_INTERVAL; + lcconf->count_persend = LC_DEFAULT_COUNT_PERSEND; + lcconf->secret_size = LC_DEFAULT_SECRETSIZE; + lcconf->retry_checkph1 = LC_DEFAULT_RETRY_CHECKPH1; + lcconf->wait_ph2complete = LC_DEFAULT_WAIT_PH2COMPLETE; + lcconf->strict_address = FALSE; + lcconf->complex_bundle = TRUE; /*XXX FALSE;*/ + lcconf->gss_id_enc = LC_GSSENC_UTF16LE; /* Windows compatibility */ + lcconf->natt_ka_interval = LC_DEFAULT_NATT_KA_INTERVAL; + lcconf->pfkey_buffer_size = LC_DEFAULT_PFKEY_BUFFER_SIZE; +} + +/* + * get PSK by string. + */ +vchar_t * +getpskbyname(id0) + vchar_t *id0; +{ + char *id; + vchar_t *key = NULL; + + id = racoon_calloc(1, 1 + id0->l - sizeof(struct ipsecdoi_id_b)); + if (id == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get psk buffer.\n"); + goto end; + } + memcpy(id, id0->v + sizeof(struct ipsecdoi_id_b), + id0->l - sizeof(struct ipsecdoi_id_b)); + id[id0->l - sizeof(struct ipsecdoi_id_b)] = '\0'; + + key = privsep_getpsk(id, id0->l - sizeof(struct ipsecdoi_id_b)); + +end: + if (id) + racoon_free(id); + return key; +} + +/* + * get PSK by address. + */ +vchar_t * +getpskbyaddr(remote) + struct sockaddr *remote; +{ + vchar_t *key = NULL; + char addr[NI_MAXHOST], port[NI_MAXSERV]; + + GETNAMEINFO(remote, addr, port); + + key = privsep_getpsk(addr, strlen(addr)); + + return key; +} + +vchar_t * +getpsk(str, len) + const char *str; + const int len; +{ + FILE *fp; + char buf[1024]; /* XXX how is variable length ? */ + vchar_t *key = NULL; + char *p, *q; + size_t keylen; + char *k = NULL; + + if (safefile(lcconf->pathinfo[LC_PATHTYPE_PSK], 1) == 0) + fp = fopen(lcconf->pathinfo[LC_PATHTYPE_PSK], "r"); + else + fp = NULL; + if (fp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to open pre_share_key file %s\n", + lcconf->pathinfo[LC_PATHTYPE_PSK]); + return NULL; + } + + while (fgets(buf, sizeof(buf), fp) != NULL) { + /* comment line */ + if (buf[0] == '#') + continue; + + /* search the end of 1st string. */ + for (p = buf; *p != '\0' && !isspace((int)*p); p++) + ; + if (*p == '\0') + continue; /* no 2nd parameter */ + *p = '\0'; + /* search the 1st of 2nd string. */ + while (isspace((int)*++p)) + ; + if (*p == '\0') + continue; /* no 2nd parameter */ + p--; + if (strncmp(buf, str, len) == 0 && buf[len] == '\0') { + p++; + keylen = 0; + for (q = p; *q != '\0' && *q != '\n'; q++) + keylen++; + *q = '\0'; + + /* fix key if hex string */ + if (strncmp(p, "0x", 2) == 0) { + k = str2val(p + 2, 16, &keylen); + if (k == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get psk buffer.\n"); + goto end; + } + p = k; + } + + key = vmalloc(keylen); + if (key == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate key buffer.\n"); + goto end; + } + memcpy(key->v, p, key->l); + if (k) + racoon_free(k); + goto end; + } + } + +end: + fclose(fp); + return key; +} + +/* + * get a file name of a type specified. + */ +void +getpathname(path, len, type, name) + char *path; + int len, type; + const char *name; +{ + snprintf(path, len, "%s%s%s", + name[0] == '/' ? "" : lcconf->pathinfo[type], + name[0] == '/' ? "" : "/", + name); + + plog(LLV_DEBUG, LOCATION, NULL, "filename: %s\n", path); +} + +#if 0 /* DELETEIT */ +static int lc_doi2idtype[] = { + -1, + -1, + LC_IDENTTYPE_FQDN, + LC_IDENTTYPE_USERFQDN, + -1, + -1, + -1, + -1, + -1, + LC_IDENTTYPE_CERTNAME, + -1, + LC_IDENTTYPE_KEYID, +}; + +/* + * convert DOI value to idtype + * OUT -1 : NG + * other: converted. + */ +int +doi2idtype(idtype) + int idtype; +{ + if (ARRAYLEN(lc_doi2idtype) > idtype) + return lc_doi2idtype[idtype]; + return -1; +} +#endif + +static int lc_sittype2doi[] = { + IPSECDOI_SIT_IDENTITY_ONLY, + IPSECDOI_SIT_SECRECY, + IPSECDOI_SIT_INTEGRITY, +}; + +/* + * convert sittype to DOI value. + * OUT -1 : NG + * other: converted. + */ +int +sittype2doi(sittype) + int sittype; +{ + if (ARRAYLEN(lc_sittype2doi) > sittype) + return lc_sittype2doi[sittype]; + return -1; +} + +static int lc_doitype2doi[] = { + IPSEC_DOI, +}; + +/* + * convert doitype to DOI value. + * OUT -1 : NG + * other: converted. + */ +int +doitype2doi(doitype) + int doitype; +{ + if (ARRAYLEN(lc_doitype2doi) > doitype) + return lc_doitype2doi[doitype]; + return -1; +} + + + +static void +saverestore_params(f) + int f; +{ + static u_int16_t s_port_isakmp; + + /* 0: save, 1: restore */ + if (f) { + lcconf->port_isakmp = s_port_isakmp; + } else { + s_port_isakmp = lcconf->port_isakmp; + } +} + +void +restore_params() +{ + saverestore_params(1); +} + +void +save_params() +{ + saverestore_params(0); +} diff --git a/ipsec-tools/src/racoon/localconf.h b/ipsec-tools/src/racoon/localconf.h new file mode 100644 index 00000000..04ac8e49 --- /dev/null +++ b/ipsec-tools/src/racoon/localconf.h @@ -0,0 +1,132 @@ +/* $NetBSD: localconf.h,v 1.7 2008/12/23 14:04:42 tteras Exp $ */ + +/* Id: localconf.h,v 1.13 2005/11/06 18:13:18 monas Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _LOCALCONF_H +#define _LOCALCONF_H + +/* local configuration */ + +#define LC_DEFAULT_CF SYSCONFDIR "/racoon.conf" + +#define LC_PATHTYPE_INCLUDE 0 +#define LC_PATHTYPE_PSK 1 +#define LC_PATHTYPE_CERT 2 +#define LC_PATHTYPE_BACKUPSA 3 +#define LC_PATHTYPE_SCRIPT 4 +#define LC_PATHTYPE_PIDFILE 5 +#define LC_PATHTYPE_MAX 6 + +#define LC_DEFAULT_PAD_MAXSIZE 20 +#define LC_DEFAULT_PAD_RANDOM TRUE +#define LC_DEFAULT_PAD_RANDOMLEN FALSE +#define LC_DEFAULT_PAD_STRICT FALSE +#define LC_DEFAULT_PAD_EXCLTAIL TRUE +#define LC_DEFAULT_RETRY_COUNTER 5 +#define LC_DEFAULT_RETRY_INTERVAL 10 +#define LC_DEFAULT_COUNT_PERSEND 1 +#define LC_DEFAULT_RETRY_CHECKPH1 30 +#define LC_DEFAULT_WAIT_PH2COMPLETE 30 +#define LC_DEFAULT_NATT_KA_INTERVAL 20 +#define LC_DEFAULT_PFKEY_BUFFER_SIZE 0 + +#define LC_DEFAULT_SECRETSIZE 16 /* 128 bits */ + +#define LC_GSSENC_UTF16LE 0 /* GSS ID in UTF-16LE */ +#define LC_GSSENC_LATIN1 1 /* GSS ID in ISO-Latin-1 */ +#define LC_GSSENC_MAX 2 + +struct localconf { + char *racoon_conf; /* configuration filename */ + + uid_t uid; + gid_t gid; + char *chroot; /* chroot path */ + u_int16_t port_isakmp; /* port for isakmp as default */ + u_int16_t port_isakmp_natt; /* port for NAT-T use */ + int default_af; /* default address family */ + + int sock_admin; + int sock_pfkey; + int rtsock; /* routing socket */ + + char *pathinfo[LC_PATHTYPE_MAX]; + + int pad_random; + int pad_randomlen; + int pad_maxsize; + int pad_strict; + int pad_excltail; + + int retry_counter; /* times to retry. */ + int retry_interval; /* interval each retry. */ + int count_persend; /* the number of packets each retry. */ + /* above 3 values are copied into a handler. */ + + int retry_checkph1; + int wait_ph2complete; + + int natt_ka_interval; /* NAT-T keepalive interval. */ + + int secret_size; + int strict_address; /* strictly check addresses. */ + + int complex_bundle; + /* + * If we want to make a packet "IP2 AH ESP IP1 ULP", + * the SPD in KAME expresses AH transport + ESP tunnel. + * So racoon sent the proposal contained such the order. + * But lots of implementation interprets AH tunnel + ESP + * tunnel in this case. racoon has changed the format, + * usually uses this format. If the option, 'complex_bundle' + * is enable, racoon uses old format. + */ + + int gss_id_enc; /* GSS ID encoding to use */ + int pfkey_buffer_size; /* Set socket buffer size for pfkey */ +}; + +extern struct localconf *lcconf; + +extern void initlcconf __P((void)); +extern void flushlcconf __P((void)); +extern vchar_t *getpskbyname __P((vchar_t *)); +extern vchar_t *getpskbyaddr __P((struct sockaddr *)); +extern void getpathname __P((char *, int, int, const char *)); +extern int sittype2doi __P((int)); +extern int doitype2doi __P((int)); +extern vchar_t *getpsk __P((const char *, const int)); + +extern void restore_params __P((void)); +extern void save_params __P((void)); + +#endif /* _LOCALCONF_H */ diff --git a/ipsec-tools/src/racoon/logger.c b/ipsec-tools/src/racoon/logger.c new file mode 100644 index 00000000..06991cc5 --- /dev/null +++ b/ipsec-tools/src/racoon/logger.c @@ -0,0 +1,262 @@ +/* $NetBSD: logger.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* $KAME: logger.c,v 1.9 2002/09/03 14:37:03 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#ifdef HAVE_STDARG_H +#include +#else +#include +#endif +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include "logger.h" +#include "var.h" +#include "gcmalloc.h" + +struct log * +log_open(siz, fname) + size_t siz; + char *fname; +{ + struct log *p; + + p = (struct log *)racoon_malloc(sizeof(*p)); + if (p == NULL) + return NULL; + memset(p, 0, sizeof(*p)); + + p->buf = (char **)racoon_malloc(sizeof(char *) * siz); + if (p->buf == NULL) { + racoon_free(p); + return NULL; + } + memset(p->buf, 0, sizeof(char *) * siz); + + p->tbuf = (time_t *)racoon_malloc(sizeof(time_t *) * siz); + if (p->tbuf == NULL) { + racoon_free(p->buf); + racoon_free(p); + return NULL; + } + memset(p->tbuf, 0, sizeof(time_t *) * siz); + + p->siz = siz; + if (fname) + p->fname = racoon_strdup(fname); + + return p; +} + +/* + * append string to ring buffer. + * string must be \n-terminated (since we add timestamps). + * even if not, we'll add \n to avoid formatting mistake (see log_close()). + */ +void +log_add(p, str) + struct log *p; + char *str; +{ + /* syslog if p->fname == NULL? */ + if (p->buf[p->head]) + racoon_free(p->buf[p->head]); + p->buf[p->head] = racoon_strdup(str); + p->tbuf[p->head] = time(NULL); + p->head++; + p->head %= p->siz; +} + +/* + * write out string to the log file, as is. + * \n-termination is up to the caller. if you don't add \n, the file + * format may be broken. + */ +int +log_print(p, str) + struct log *p; + char *str; +{ + FILE *fp; + + if (p->fname == NULL) + return -1; /*XXX syslog?*/ + fp = fopen(p->fname, "a"); + if (fp == NULL) + return -1; + fprintf(fp, "%s", str); + fclose(fp); + + return 0; +} + +int +log_vprint(struct log *p, const char *fmt, ...) +{ + va_list ap; + + FILE *fp; + + if (p->fname == NULL) + return -1; /*XXX syslog?*/ + fp = fopen(p->fname, "a"); + if (fp == NULL) + return -1; + va_start(ap, fmt); + vfprintf(fp, fmt, ap); + va_end(ap); + + fclose(fp); + + return 0; +} + +int +log_vaprint(struct log *p, const char *fmt, va_list ap) +{ + FILE *fp; + + if (p->fname == NULL) + return -1; /*XXX syslog?*/ + fp = fopen(p->fname, "a"); + if (fp == NULL) + return -1; + vfprintf(fp, fmt, ap); + fclose(fp); + + return 0; +} + +/* + * write out content of ring buffer, and reclaim the log structure + */ +int +log_close(p) + struct log *p; +{ + FILE *fp; + int i, j; + char ts[256]; + struct tm *tm; + + if (p->fname == NULL) + goto nowrite; + fp = fopen(p->fname, "a"); + if (fp == NULL) + goto nowrite; + + for (i = 0; i < p->siz; i++) { + j = (p->head + i) % p->siz; + if (p->buf[j]) { + tm = localtime(&p->tbuf[j]); + strftime(ts, sizeof(ts), "%B %d %T", tm); + fprintf(fp, "%s: %s\n", ts, p->buf[j]); + if (*(p->buf[j] + strlen(p->buf[j]) - 1) != '\n') + fprintf(fp, "\n"); + } + } + fclose(fp); + +nowrite: + log_free(p); + return 0; +} + +void +log_free(p) + struct log *p; +{ + int i; + + for (i = 0; i < p->siz; i++) + racoon_free(p->buf[i]); + racoon_free(p->buf); + racoon_free(p->tbuf); + if (p->fname) + racoon_free(p->fname); + racoon_free(p); +} + +#ifdef TEST +struct log *l; + +void +vatest(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + log_vaprint(l, fmt, ap); + va_end(ap); +} + +int +main(argc, argv) + int argc; + char **argv; +{ + int i; + + l = log_open(30, "/tmp/hoge"); + if (l == NULL) + errx(1, "hoge"); + + for (i = 0; i < 50; i++) { + log_add(l, "foo"); + log_add(l, "baa"); + log_add(l, "baz"); + } + log_print(l, "hoge\n"); + log_vprint(l, "hoge %s\n", "this is test"); + vatest("%s %s\n", "this is", "vprint test"); + abort(); + log_free(l); +} + +#endif + diff --git a/ipsec-tools/src/racoon/logger.h b/ipsec-tools/src/racoon/logger.h new file mode 100644 index 00000000..3fd3e947 --- /dev/null +++ b/ipsec-tools/src/racoon/logger.h @@ -0,0 +1,53 @@ +/* $NetBSD: logger.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: logger.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _LOGGER_H +#define _LOGGER_H + +struct log { + int head; + int siz; + char **buf; + time_t *tbuf; + char *fname; +}; + +extern struct log *log_open __P((size_t, char *)); +extern void log_add __P((struct log *, char *)); +extern int log_print __P((struct log *, char *)); +extern int log_vprint __P((struct log *, const char *, ...)); +extern int log_vaprint __P((struct log *, const char *, va_list)); +extern int log_close __P((struct log *)); +extern void log_free __P((struct log *)); + +#endif /* _LOGGER_H */ diff --git a/ipsec-tools/src/racoon/main.c b/ipsec-tools/src/racoon/main.c new file mode 100644 index 00000000..8936204e --- /dev/null +++ b/ipsec-tools/src/racoon/main.c @@ -0,0 +1,349 @@ +/* $NetBSD: main.c,v 1.12.6.1 2013/07/12 13:12:24 tteras Exp $ */ + +/* Id: main.c,v 1.25 2006/06/20 20:31:34 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include + +/* + * If we're using a debugging malloc library, this may define our + * wrapper stubs. + */ +#define RACOON_MAIN_PROGRAM +#include "gcmalloc.h" + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "debug.h" + +#include "cfparse_proto.h" +#include "isakmp_var.h" +#include "remoteconf.h" +#include "localconf.h" +#include "session.h" +#include "oakley.h" +#include "pfkey.h" +#include "policy.h" +#include "crypto_openssl.h" +#include "backupsa.h" +#include "vendorid.h" + +#include "package_version.h" + +int dump_config = 0; /* dump parsed config file. */ +int f_local = 0; /* local test mode. behave like a wall. */ +int vflag = 1; /* for print-isakmp.c */ +static int loading_sa = 0; /* install sa when racoon boots up. */ + +#ifdef TOP_PACKAGE +static char version[] = "@(#)" TOP_PACKAGE_STRING " (" TOP_PACKAGE_URL ")"; +#else /* TOP_PACKAGE */ +static char version[] = "@(#) racoon / IPsec-tools"; +#endif /* TOP_PACKAGE */ + +static void +print_version() +{ + printf("%s\n" + "\n" + "Compiled with:\n" + "- %s (http://www.openssl.org/)\n" +#ifdef INET6 + "- IPv6 support\n" +#endif +#ifdef ENABLE_DPD + "- Dead Peer Detection\n" +#endif +#ifdef ENABLE_FRAG + "- IKE fragmentation\n" +#endif +#ifdef ENABLE_HYBRID + "- Hybrid authentication\n" +#endif +#ifdef ENABLE_GSSAPI + "- GSS-API authentication\n" +#endif +#ifdef ENABLE_NATT + "- NAT Traversal\n" +#endif +#ifdef ENABLE_STATS + "- Timing statistics\n" +#endif +#ifdef ENABLE_ADMINPORT + "- Admin port\n" +#endif +#ifdef HAVE_CLOCK_MONOTONIC + "- Monotonic clock\n" +#endif +#ifdef HAVE_SECCTX + "- Security context\n" +#endif + "\n", + version, + eay_version()); + exit(0); +} + +static void +usage() +{ + printf("usage: racoon [-BdFv" +#ifdef INET6 + "46" +#endif + "] [-f (file)] [-l (file)] [-p (port)] [-P (natt port)]\n" + " -B: install SA to the kernel from the file " + "specified by the configuration file.\n" + " -d: debug level, more -d will generate more debug message.\n" + " -C: dump parsed config file.\n" + " -L: include location in debug messages\n" + " -F: run in foreground, do not become daemon.\n" + " -v: be more verbose\n" + " -V: print version and exit\n" +#ifdef INET6 + " -4: IPv4 mode.\n" + " -6: IPv6 mode.\n" +#endif + " -f: pathname for configuration file.\n" + " -l: pathname for log file.\n" + " -p: port number for isakmp (default: %d).\n" + " -P: port number for NAT-T (default: %d).\n" + "\n", + PORT_ISAKMP, PORT_ISAKMP_NATT); + exit(1); +} + +static void +parse(ac, av) + int ac; + char **av; +{ + extern char *optarg; + extern int optind; + int c; +#ifdef YYDEBUG + extern int yydebug; +#endif + + pname = strrchr(*av, '/'); + if (pname) + pname++; + else + pname = *av; + + while ((c = getopt(ac, av, "dLFp:P:f:l:vVZBC" +#ifdef YYDEBUG + "y" +#endif +#ifdef INET6 + "46" +#endif + )) != -1) { + switch (c) { + case 'd': + loglevel++; + break; + case 'L': + print_location = 1; + break; + case 'F': + printf("Foreground mode.\n"); + f_foreground = 1; + break; + case 'p': + lcconf->port_isakmp = atoi(optarg); + break; + case 'P': + lcconf->port_isakmp_natt = atoi(optarg); + break; + case 'f': + lcconf->racoon_conf = optarg; + break; + case 'l': + plogset(optarg); + break; + case 'v': + vflag++; + break; + case 'V': + print_version(); + break; + case 'Z': + /* + * only local test. + * To specify -Z option and to choice a appropriate + * port number for ISAKMP, you can launch some racoons + * on the local host for debug. + * pk_sendadd() on initiator side is always failed + * even if this flag is used. Because there is same + * spi in the SAD which is inserted by pk_sendgetspi() + * on responder side. + */ + printf("Local test mode.\n"); + f_local = 1; + break; +#ifdef YYDEBUG + case 'y': + yydebug = 1; + break; +#endif +#ifdef INET6 + case '4': + lcconf->default_af = AF_INET; + break; + case '6': + lcconf->default_af = AF_INET6; + break; +#endif + case 'B': + loading_sa++; + break; + case 'C': + dump_config++; + break; + default: + usage(); + /* NOTREACHED */ + } + } + ac -= optind; + av += optind; + + if (ac != 0) { + usage(); + /* NOTREACHED */ + } +} + +int +main(ac, av) + int ac; + char **av; +{ + int error; + + initlcconf(); + parse(ac, av); + + if (geteuid() != 0) { + errx(1, "must be root to invoke this program."); + /* NOTREACHED*/ + } + + /* + * Don't let anyone read files I write. Although some files (such as + * the PID file) can be other readable, we dare to use the global mask, + * because racoon uses fopen(3), which can't specify the permission + * at the creation time. + */ + umask(077); + if (umask(077) != 077) { + errx(1, "could not set umask"); + /* NOTREACHED*/ + } + + ploginit(); + +#ifdef DEBUG_RECORD_MALLOCATION + DRM_init(); +#endif + +#ifdef HAVE_SECCTX + init_avc(); +#endif + eay_init(); + initrmconf(); + oakley_dhinit(); + compute_vendorids(); + + plog(LLV_INFO, LOCATION, NULL, "%s\n", version); + plog(LLV_INFO, LOCATION, NULL, "@(#)" + "This product linked %s (http://www.openssl.org/)" + "\n", eay_version()); + plog(LLV_INFO, LOCATION, NULL, "Reading configuration from \"%s\"\n", + lcconf->racoon_conf); + + /* + * install SAs from the specified file. If the file is not specified + * by the configuration file, racoon will exit. + */ + if (loading_sa && !f_local) { + if (backupsa_from_file() != 0) + errx(1, "something error happened " + "SA recovering."); + } + + if (f_foreground) + close(0); + else { + if (daemon(0, 0) < 0) { + errx(1, "failed to be daemon. (%s)", + strerror(errno)); + } +#ifndef __linux__ + /* + * In case somebody has started inetd manually, we need to + * clear the logname, so that old servers run as root do not + * get the user's logname.. + */ + if (setlogin("") < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot clear logname: %s\n", strerror(errno)); + /* no big deal if it fails.. */ + } +#endif + } + + session(); + + return 0; +} + diff --git a/ipsec-tools/src/racoon/misc.c b/ipsec-tools/src/racoon/misc.c new file mode 100644 index 00000000..91b8e772 --- /dev/null +++ b/ipsec-tools/src/racoon/misc.c @@ -0,0 +1,182 @@ +/* $NetBSD: misc.c,v 1.6 2008/07/15 00:47:09 mgrooms Exp $ */ + +/* $KAME: misc.c,v 1.23 2001/08/16 14:37:29 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "debug.h" + +#if 0 +static int bindump __P((void *, size_t)); + +static int +bindump(buf0, len) + void *buf0; + size_t len; +{ + unsigned char *buf = (unsigned char *)buf0; + size_t i; + + for (i = 0; i < len; i++) { + if ((buf[i] & 0x80) || !isprint(buf[i])) + printf("\\x%x", buf[i]); + else + printf("%c", buf[i]); + } + printf("\n"); + + return 0; +} +#endif + +int +racoon_hexdump(buf0, len) + void *buf0; + size_t len; +{ + caddr_t buf = (caddr_t)buf0; + size_t i; + + for (i = 0; i < len; i++) { + if (i != 0 && i % 32 == 0) + printf("\n"); + if (i % 4 == 0) + printf(" "); + printf("%02x", (unsigned char)buf[i]); + } + printf("\n"); + + return 0; +} + +char * +bit2str(n, bl) + int n, bl; +{ +#define MAXBITLEN 128 + static char b[MAXBITLEN + 1]; + int i; + + if (bl > MAXBITLEN) + return "Failed to convert."; /* NG */ + memset(b, '0', bl); + b[bl] = '\0'; + + for (i = 0; i < bl; i++) { + if (n & (1 << i)) + b[bl - 1 - i] = '1'; + } + + return b; +} + +const char * +debug_location(file, line, func) + const char *file; + int line; + const char *func; +{ + static char buf[1024]; + const char *p; + + /* truncate pathname */ + p = strrchr(file, '/'); + if (p) + p++; + else + p = file; + + if (func) + snprintf(buf, sizeof(buf), "%s:%d:%s()", p, line, func); + else + snprintf(buf, sizeof(buf), "%s:%d", p, line); + + return buf; +} + +/* + * get file size. + * -1: error occured. + */ +int +getfsize(path) + char *path; +{ + struct stat st; + + if (stat(path, &st) != 0) + return -1; + else + return st.st_size; +} + +/* + * set the close-on-exec flag for file descriptor fd. + */ +void +close_on_exec(fd) + int fd; +{ + fcntl(fd, F_SETFD, FD_CLOEXEC); +} + +/* + * calculate the difference between two times. + * t1: start + * t2: end + */ +double +timedelta(t1, t2) + struct timeval *t1, *t2; +{ + if (t2->tv_usec >= t1->tv_usec) + return t2->tv_sec - t1->tv_sec + + (double)(t2->tv_usec - t1->tv_usec) / 1000000; + + return t2->tv_sec - t1->tv_sec - 1 + + (double)(1000000 + t2->tv_usec - t1->tv_usec) / 1000000; +} diff --git a/ipsec-tools/src/racoon/misc.h b/ipsec-tools/src/racoon/misc.h new file mode 100644 index 00000000..3e758d9a --- /dev/null +++ b/ipsec-tools/src/racoon/misc.h @@ -0,0 +1,78 @@ +/* $NetBSD: misc.h,v 1.6 2008/07/15 00:47:09 mgrooms Exp $ */ + +/* Id: misc.h,v 1.9 2006/04/06 14:00:06 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _MISC_H +#define _MISC_H + +#define BIT2STR(b) bit2str(b, sizeof(b)<<3) + +#ifdef HAVE_FUNC_MACRO +#define LOCATION debug_location(__FILE__, __LINE__, __func__) +#else +#define LOCATION debug_location(__FILE__, __LINE__, NULL) +#endif + +extern int racoon_hexdump __P((void *, size_t)); +extern char *bit2str __P((int, int)); +extern void *get_newbuf __P((void *, size_t)); +extern const char *debug_location __P((const char *, int, const char *)); +extern int getfsize __P((char *)); +struct timeval; +extern double timedelta __P((struct timeval *, struct timeval *)); +char *strdup __P((const char *)); +extern void close_on_exec __P((int fd)); + +#if defined(__APPLE__) && defined(__MACH__) +#define RACOON_TAILQ_FOREACH_REVERSE(var, head, headname ,field) \ + TAILQ_FOREACH_REVERSE(var, head, field, headname) +#else +#define RACOON_TAILQ_FOREACH_REVERSE(var, head, headname ,field) \ + TAILQ_FOREACH_REVERSE(var, head, headname, field) +#endif + +#ifndef HAVE_STRLCPY +#define strlcpy(d,s,l) (strncpy(d,s,l), (d)[(l)-1] = '\0') +#endif + +#ifndef HAVE_STRLCAT +#define strlcat(d,s,l) strncat(d,s,(l)-strlen(d)-1) +#endif + +#define STRDUP_FATAL(x) if (x == NULL) { \ + plog(LLV_ERROR, LOCATION, NULL, "strdup failed\n"); \ + exit(1); \ +} + +#include "libpfkey.h" + +#endif /* _MISC_H */ diff --git a/ipsec-tools/src/racoon/missing/crypto/rijndael/boxes-fst.dat b/ipsec-tools/src/racoon/missing/crypto/rijndael/boxes-fst.dat new file mode 100644 index 00000000..28d15d3b --- /dev/null +++ b/ipsec-tools/src/racoon/missing/crypto/rijndael/boxes-fst.dat @@ -0,0 +1,957 @@ +/* $KAME: boxes-fst.dat,v 1.1.1.1 2001/08/08 09:56:27 sakane Exp $ */ + +const word8 S[256] = { + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, +202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, +183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, +208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, +205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, +224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, +231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, +186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, +112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, +225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, +140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22 +}; + +#ifdef INTERMEDIATE_VALUE_KAT +static const word8 Si[256] = { + 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, +124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, + 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, + 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, +114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, +108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, +144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, +208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, + 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, +150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, + 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, +252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, + 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, + 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, +160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, + 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125 +}; +#endif /* INTERMEDIATE_VALUE_KAT */ + +union xtab { + word32 xt32[256]; + word8 xt8[256][4]; +}; + +static const union xtab xT1 = { + .xt8 = { +{0xc6,0x63,0x63,0xa5}, {0xf8,0x7c,0x7c,0x84}, {0xee,0x77,0x77,0x99}, {0xf6,0x7b,0x7b,0x8d}, +{0xff,0xf2,0xf2,0x0d}, {0xd6,0x6b,0x6b,0xbd}, {0xde,0x6f,0x6f,0xb1}, {0x91,0xc5,0xc5,0x54}, +{0x60,0x30,0x30,0x50}, {0x02,0x01,0x01,0x03}, {0xce,0x67,0x67,0xa9}, {0x56,0x2b,0x2b,0x7d}, +{0xe7,0xfe,0xfe,0x19}, {0xb5,0xd7,0xd7,0x62}, {0x4d,0xab,0xab,0xe6}, {0xec,0x76,0x76,0x9a}, +{0x8f,0xca,0xca,0x45}, {0x1f,0x82,0x82,0x9d}, {0x89,0xc9,0xc9,0x40}, {0xfa,0x7d,0x7d,0x87}, +{0xef,0xfa,0xfa,0x15}, {0xb2,0x59,0x59,0xeb}, {0x8e,0x47,0x47,0xc9}, {0xfb,0xf0,0xf0,0x0b}, +{0x41,0xad,0xad,0xec}, {0xb3,0xd4,0xd4,0x67}, {0x5f,0xa2,0xa2,0xfd}, {0x45,0xaf,0xaf,0xea}, +{0x23,0x9c,0x9c,0xbf}, {0x53,0xa4,0xa4,0xf7}, {0xe4,0x72,0x72,0x96}, {0x9b,0xc0,0xc0,0x5b}, +{0x75,0xb7,0xb7,0xc2}, {0xe1,0xfd,0xfd,0x1c}, {0x3d,0x93,0x93,0xae}, {0x4c,0x26,0x26,0x6a}, +{0x6c,0x36,0x36,0x5a}, {0x7e,0x3f,0x3f,0x41}, {0xf5,0xf7,0xf7,0x02}, {0x83,0xcc,0xcc,0x4f}, +{0x68,0x34,0x34,0x5c}, {0x51,0xa5,0xa5,0xf4}, {0xd1,0xe5,0xe5,0x34}, {0xf9,0xf1,0xf1,0x08}, +{0xe2,0x71,0x71,0x93}, {0xab,0xd8,0xd8,0x73}, {0x62,0x31,0x31,0x53}, {0x2a,0x15,0x15,0x3f}, +{0x08,0x04,0x04,0x0c}, {0x95,0xc7,0xc7,0x52}, {0x46,0x23,0x23,0x65}, {0x9d,0xc3,0xc3,0x5e}, +{0x30,0x18,0x18,0x28}, {0x37,0x96,0x96,0xa1}, {0x0a,0x05,0x05,0x0f}, {0x2f,0x9a,0x9a,0xb5}, +{0x0e,0x07,0x07,0x09}, {0x24,0x12,0x12,0x36}, {0x1b,0x80,0x80,0x9b}, {0xdf,0xe2,0xe2,0x3d}, +{0xcd,0xeb,0xeb,0x26}, {0x4e,0x27,0x27,0x69}, {0x7f,0xb2,0xb2,0xcd}, {0xea,0x75,0x75,0x9f}, +{0x12,0x09,0x09,0x1b}, {0x1d,0x83,0x83,0x9e}, {0x58,0x2c,0x2c,0x74}, {0x34,0x1a,0x1a,0x2e}, +{0x36,0x1b,0x1b,0x2d}, {0xdc,0x6e,0x6e,0xb2}, {0xb4,0x5a,0x5a,0xee}, {0x5b,0xa0,0xa0,0xfb}, +{0xa4,0x52,0x52,0xf6}, {0x76,0x3b,0x3b,0x4d}, {0xb7,0xd6,0xd6,0x61}, {0x7d,0xb3,0xb3,0xce}, +{0x52,0x29,0x29,0x7b}, {0xdd,0xe3,0xe3,0x3e}, {0x5e,0x2f,0x2f,0x71}, {0x13,0x84,0x84,0x97}, +{0xa6,0x53,0x53,0xf5}, {0xb9,0xd1,0xd1,0x68}, {0x00,0x00,0x00,0x00}, {0xc1,0xed,0xed,0x2c}, +{0x40,0x20,0x20,0x60}, {0xe3,0xfc,0xfc,0x1f}, {0x79,0xb1,0xb1,0xc8}, {0xb6,0x5b,0x5b,0xed}, +{0xd4,0x6a,0x6a,0xbe}, {0x8d,0xcb,0xcb,0x46}, {0x67,0xbe,0xbe,0xd9}, {0x72,0x39,0x39,0x4b}, +{0x94,0x4a,0x4a,0xde}, {0x98,0x4c,0x4c,0xd4}, {0xb0,0x58,0x58,0xe8}, {0x85,0xcf,0xcf,0x4a}, +{0xbb,0xd0,0xd0,0x6b}, {0xc5,0xef,0xef,0x2a}, {0x4f,0xaa,0xaa,0xe5}, {0xed,0xfb,0xfb,0x16}, +{0x86,0x43,0x43,0xc5}, {0x9a,0x4d,0x4d,0xd7}, {0x66,0x33,0x33,0x55}, {0x11,0x85,0x85,0x94}, +{0x8a,0x45,0x45,0xcf}, {0xe9,0xf9,0xf9,0x10}, {0x04,0x02,0x02,0x06}, {0xfe,0x7f,0x7f,0x81}, +{0xa0,0x50,0x50,0xf0}, {0x78,0x3c,0x3c,0x44}, {0x25,0x9f,0x9f,0xba}, {0x4b,0xa8,0xa8,0xe3}, +{0xa2,0x51,0x51,0xf3}, {0x5d,0xa3,0xa3,0xfe}, {0x80,0x40,0x40,0xc0}, {0x05,0x8f,0x8f,0x8a}, +{0x3f,0x92,0x92,0xad}, {0x21,0x9d,0x9d,0xbc}, {0x70,0x38,0x38,0x48}, {0xf1,0xf5,0xf5,0x04}, +{0x63,0xbc,0xbc,0xdf}, {0x77,0xb6,0xb6,0xc1}, {0xaf,0xda,0xda,0x75}, {0x42,0x21,0x21,0x63}, +{0x20,0x10,0x10,0x30}, {0xe5,0xff,0xff,0x1a}, {0xfd,0xf3,0xf3,0x0e}, {0xbf,0xd2,0xd2,0x6d}, +{0x81,0xcd,0xcd,0x4c}, {0x18,0x0c,0x0c,0x14}, {0x26,0x13,0x13,0x35}, {0xc3,0xec,0xec,0x2f}, +{0xbe,0x5f,0x5f,0xe1}, {0x35,0x97,0x97,0xa2}, {0x88,0x44,0x44,0xcc}, {0x2e,0x17,0x17,0x39}, +{0x93,0xc4,0xc4,0x57}, {0x55,0xa7,0xa7,0xf2}, {0xfc,0x7e,0x7e,0x82}, {0x7a,0x3d,0x3d,0x47}, +{0xc8,0x64,0x64,0xac}, {0xba,0x5d,0x5d,0xe7}, {0x32,0x19,0x19,0x2b}, {0xe6,0x73,0x73,0x95}, +{0xc0,0x60,0x60,0xa0}, {0x19,0x81,0x81,0x98}, {0x9e,0x4f,0x4f,0xd1}, {0xa3,0xdc,0xdc,0x7f}, +{0x44,0x22,0x22,0x66}, {0x54,0x2a,0x2a,0x7e}, {0x3b,0x90,0x90,0xab}, {0x0b,0x88,0x88,0x83}, +{0x8c,0x46,0x46,0xca}, {0xc7,0xee,0xee,0x29}, {0x6b,0xb8,0xb8,0xd3}, {0x28,0x14,0x14,0x3c}, +{0xa7,0xde,0xde,0x79}, {0xbc,0x5e,0x5e,0xe2}, {0x16,0x0b,0x0b,0x1d}, {0xad,0xdb,0xdb,0x76}, +{0xdb,0xe0,0xe0,0x3b}, {0x64,0x32,0x32,0x56}, {0x74,0x3a,0x3a,0x4e}, {0x14,0x0a,0x0a,0x1e}, +{0x92,0x49,0x49,0xdb}, {0x0c,0x06,0x06,0x0a}, {0x48,0x24,0x24,0x6c}, {0xb8,0x5c,0x5c,0xe4}, +{0x9f,0xc2,0xc2,0x5d}, {0xbd,0xd3,0xd3,0x6e}, {0x43,0xac,0xac,0xef}, {0xc4,0x62,0x62,0xa6}, +{0x39,0x91,0x91,0xa8}, {0x31,0x95,0x95,0xa4}, {0xd3,0xe4,0xe4,0x37}, {0xf2,0x79,0x79,0x8b}, +{0xd5,0xe7,0xe7,0x32}, {0x8b,0xc8,0xc8,0x43}, {0x6e,0x37,0x37,0x59}, {0xda,0x6d,0x6d,0xb7}, +{0x01,0x8d,0x8d,0x8c}, {0xb1,0xd5,0xd5,0x64}, {0x9c,0x4e,0x4e,0xd2}, {0x49,0xa9,0xa9,0xe0}, +{0xd8,0x6c,0x6c,0xb4}, {0xac,0x56,0x56,0xfa}, {0xf3,0xf4,0xf4,0x07}, {0xcf,0xea,0xea,0x25}, +{0xca,0x65,0x65,0xaf}, {0xf4,0x7a,0x7a,0x8e}, {0x47,0xae,0xae,0xe9}, {0x10,0x08,0x08,0x18}, +{0x6f,0xba,0xba,0xd5}, {0xf0,0x78,0x78,0x88}, {0x4a,0x25,0x25,0x6f}, {0x5c,0x2e,0x2e,0x72}, +{0x38,0x1c,0x1c,0x24}, {0x57,0xa6,0xa6,0xf1}, {0x73,0xb4,0xb4,0xc7}, {0x97,0xc6,0xc6,0x51}, +{0xcb,0xe8,0xe8,0x23}, {0xa1,0xdd,0xdd,0x7c}, {0xe8,0x74,0x74,0x9c}, {0x3e,0x1f,0x1f,0x21}, +{0x96,0x4b,0x4b,0xdd}, {0x61,0xbd,0xbd,0xdc}, {0x0d,0x8b,0x8b,0x86}, {0x0f,0x8a,0x8a,0x85}, +{0xe0,0x70,0x70,0x90}, {0x7c,0x3e,0x3e,0x42}, {0x71,0xb5,0xb5,0xc4}, {0xcc,0x66,0x66,0xaa}, +{0x90,0x48,0x48,0xd8}, {0x06,0x03,0x03,0x05}, {0xf7,0xf6,0xf6,0x01}, {0x1c,0x0e,0x0e,0x12}, +{0xc2,0x61,0x61,0xa3}, {0x6a,0x35,0x35,0x5f}, {0xae,0x57,0x57,0xf9}, {0x69,0xb9,0xb9,0xd0}, +{0x17,0x86,0x86,0x91}, {0x99,0xc1,0xc1,0x58}, {0x3a,0x1d,0x1d,0x27}, {0x27,0x9e,0x9e,0xb9}, +{0xd9,0xe1,0xe1,0x38}, {0xeb,0xf8,0xf8,0x13}, {0x2b,0x98,0x98,0xb3}, {0x22,0x11,0x11,0x33}, +{0xd2,0x69,0x69,0xbb}, {0xa9,0xd9,0xd9,0x70}, {0x07,0x8e,0x8e,0x89}, {0x33,0x94,0x94,0xa7}, +{0x2d,0x9b,0x9b,0xb6}, {0x3c,0x1e,0x1e,0x22}, {0x15,0x87,0x87,0x92}, {0xc9,0xe9,0xe9,0x20}, +{0x87,0xce,0xce,0x49}, {0xaa,0x55,0x55,0xff}, {0x50,0x28,0x28,0x78}, {0xa5,0xdf,0xdf,0x7a}, +{0x03,0x8c,0x8c,0x8f}, {0x59,0xa1,0xa1,0xf8}, {0x09,0x89,0x89,0x80}, {0x1a,0x0d,0x0d,0x17}, +{0x65,0xbf,0xbf,0xda}, {0xd7,0xe6,0xe6,0x31}, {0x84,0x42,0x42,0xc6}, {0xd0,0x68,0x68,0xb8}, +{0x82,0x41,0x41,0xc3}, {0x29,0x99,0x99,0xb0}, {0x5a,0x2d,0x2d,0x77}, {0x1e,0x0f,0x0f,0x11}, +{0x7b,0xb0,0xb0,0xcb}, {0xa8,0x54,0x54,0xfc}, {0x6d,0xbb,0xbb,0xd6}, {0x2c,0x16,0x16,0x3a} + } +}; +#define T1 xT1.xt8 + +static const union xtab xT2 = { + .xt8 = { +{0xa5,0xc6,0x63,0x63}, {0x84,0xf8,0x7c,0x7c}, {0x99,0xee,0x77,0x77}, {0x8d,0xf6,0x7b,0x7b}, +{0x0d,0xff,0xf2,0xf2}, {0xbd,0xd6,0x6b,0x6b}, {0xb1,0xde,0x6f,0x6f}, {0x54,0x91,0xc5,0xc5}, +{0x50,0x60,0x30,0x30}, {0x03,0x02,0x01,0x01}, {0xa9,0xce,0x67,0x67}, {0x7d,0x56,0x2b,0x2b}, +{0x19,0xe7,0xfe,0xfe}, {0x62,0xb5,0xd7,0xd7}, {0xe6,0x4d,0xab,0xab}, {0x9a,0xec,0x76,0x76}, +{0x45,0x8f,0xca,0xca}, {0x9d,0x1f,0x82,0x82}, {0x40,0x89,0xc9,0xc9}, {0x87,0xfa,0x7d,0x7d}, +{0x15,0xef,0xfa,0xfa}, {0xeb,0xb2,0x59,0x59}, {0xc9,0x8e,0x47,0x47}, {0x0b,0xfb,0xf0,0xf0}, +{0xec,0x41,0xad,0xad}, {0x67,0xb3,0xd4,0xd4}, {0xfd,0x5f,0xa2,0xa2}, {0xea,0x45,0xaf,0xaf}, +{0xbf,0x23,0x9c,0x9c}, {0xf7,0x53,0xa4,0xa4}, {0x96,0xe4,0x72,0x72}, {0x5b,0x9b,0xc0,0xc0}, +{0xc2,0x75,0xb7,0xb7}, {0x1c,0xe1,0xfd,0xfd}, {0xae,0x3d,0x93,0x93}, {0x6a,0x4c,0x26,0x26}, +{0x5a,0x6c,0x36,0x36}, {0x41,0x7e,0x3f,0x3f}, {0x02,0xf5,0xf7,0xf7}, {0x4f,0x83,0xcc,0xcc}, +{0x5c,0x68,0x34,0x34}, {0xf4,0x51,0xa5,0xa5}, {0x34,0xd1,0xe5,0xe5}, {0x08,0xf9,0xf1,0xf1}, +{0x93,0xe2,0x71,0x71}, {0x73,0xab,0xd8,0xd8}, {0x53,0x62,0x31,0x31}, {0x3f,0x2a,0x15,0x15}, +{0x0c,0x08,0x04,0x04}, {0x52,0x95,0xc7,0xc7}, {0x65,0x46,0x23,0x23}, {0x5e,0x9d,0xc3,0xc3}, +{0x28,0x30,0x18,0x18}, {0xa1,0x37,0x96,0x96}, {0x0f,0x0a,0x05,0x05}, {0xb5,0x2f,0x9a,0x9a}, +{0x09,0x0e,0x07,0x07}, {0x36,0x24,0x12,0x12}, {0x9b,0x1b,0x80,0x80}, {0x3d,0xdf,0xe2,0xe2}, +{0x26,0xcd,0xeb,0xeb}, {0x69,0x4e,0x27,0x27}, {0xcd,0x7f,0xb2,0xb2}, {0x9f,0xea,0x75,0x75}, +{0x1b,0x12,0x09,0x09}, {0x9e,0x1d,0x83,0x83}, {0x74,0x58,0x2c,0x2c}, {0x2e,0x34,0x1a,0x1a}, +{0x2d,0x36,0x1b,0x1b}, {0xb2,0xdc,0x6e,0x6e}, {0xee,0xb4,0x5a,0x5a}, {0xfb,0x5b,0xa0,0xa0}, +{0xf6,0xa4,0x52,0x52}, {0x4d,0x76,0x3b,0x3b}, {0x61,0xb7,0xd6,0xd6}, {0xce,0x7d,0xb3,0xb3}, +{0x7b,0x52,0x29,0x29}, {0x3e,0xdd,0xe3,0xe3}, {0x71,0x5e,0x2f,0x2f}, {0x97,0x13,0x84,0x84}, +{0xf5,0xa6,0x53,0x53}, {0x68,0xb9,0xd1,0xd1}, {0x00,0x00,0x00,0x00}, {0x2c,0xc1,0xed,0xed}, +{0x60,0x40,0x20,0x20}, {0x1f,0xe3,0xfc,0xfc}, {0xc8,0x79,0xb1,0xb1}, {0xed,0xb6,0x5b,0x5b}, +{0xbe,0xd4,0x6a,0x6a}, {0x46,0x8d,0xcb,0xcb}, {0xd9,0x67,0xbe,0xbe}, {0x4b,0x72,0x39,0x39}, +{0xde,0x94,0x4a,0x4a}, {0xd4,0x98,0x4c,0x4c}, {0xe8,0xb0,0x58,0x58}, {0x4a,0x85,0xcf,0xcf}, +{0x6b,0xbb,0xd0,0xd0}, {0x2a,0xc5,0xef,0xef}, {0xe5,0x4f,0xaa,0xaa}, {0x16,0xed,0xfb,0xfb}, +{0xc5,0x86,0x43,0x43}, {0xd7,0x9a,0x4d,0x4d}, {0x55,0x66,0x33,0x33}, {0x94,0x11,0x85,0x85}, +{0xcf,0x8a,0x45,0x45}, {0x10,0xe9,0xf9,0xf9}, {0x06,0x04,0x02,0x02}, {0x81,0xfe,0x7f,0x7f}, +{0xf0,0xa0,0x50,0x50}, {0x44,0x78,0x3c,0x3c}, {0xba,0x25,0x9f,0x9f}, {0xe3,0x4b,0xa8,0xa8}, +{0xf3,0xa2,0x51,0x51}, {0xfe,0x5d,0xa3,0xa3}, {0xc0,0x80,0x40,0x40}, {0x8a,0x05,0x8f,0x8f}, +{0xad,0x3f,0x92,0x92}, {0xbc,0x21,0x9d,0x9d}, {0x48,0x70,0x38,0x38}, {0x04,0xf1,0xf5,0xf5}, +{0xdf,0x63,0xbc,0xbc}, {0xc1,0x77,0xb6,0xb6}, {0x75,0xaf,0xda,0xda}, {0x63,0x42,0x21,0x21}, +{0x30,0x20,0x10,0x10}, {0x1a,0xe5,0xff,0xff}, {0x0e,0xfd,0xf3,0xf3}, {0x6d,0xbf,0xd2,0xd2}, +{0x4c,0x81,0xcd,0xcd}, {0x14,0x18,0x0c,0x0c}, {0x35,0x26,0x13,0x13}, {0x2f,0xc3,0xec,0xec}, +{0xe1,0xbe,0x5f,0x5f}, {0xa2,0x35,0x97,0x97}, {0xcc,0x88,0x44,0x44}, {0x39,0x2e,0x17,0x17}, +{0x57,0x93,0xc4,0xc4}, {0xf2,0x55,0xa7,0xa7}, {0x82,0xfc,0x7e,0x7e}, {0x47,0x7a,0x3d,0x3d}, +{0xac,0xc8,0x64,0x64}, {0xe7,0xba,0x5d,0x5d}, {0x2b,0x32,0x19,0x19}, {0x95,0xe6,0x73,0x73}, +{0xa0,0xc0,0x60,0x60}, {0x98,0x19,0x81,0x81}, {0xd1,0x9e,0x4f,0x4f}, {0x7f,0xa3,0xdc,0xdc}, +{0x66,0x44,0x22,0x22}, {0x7e,0x54,0x2a,0x2a}, {0xab,0x3b,0x90,0x90}, {0x83,0x0b,0x88,0x88}, +{0xca,0x8c,0x46,0x46}, {0x29,0xc7,0xee,0xee}, {0xd3,0x6b,0xb8,0xb8}, {0x3c,0x28,0x14,0x14}, +{0x79,0xa7,0xde,0xde}, {0xe2,0xbc,0x5e,0x5e}, {0x1d,0x16,0x0b,0x0b}, {0x76,0xad,0xdb,0xdb}, +{0x3b,0xdb,0xe0,0xe0}, {0x56,0x64,0x32,0x32}, {0x4e,0x74,0x3a,0x3a}, {0x1e,0x14,0x0a,0x0a}, +{0xdb,0x92,0x49,0x49}, {0x0a,0x0c,0x06,0x06}, {0x6c,0x48,0x24,0x24}, {0xe4,0xb8,0x5c,0x5c}, +{0x5d,0x9f,0xc2,0xc2}, {0x6e,0xbd,0xd3,0xd3}, {0xef,0x43,0xac,0xac}, {0xa6,0xc4,0x62,0x62}, +{0xa8,0x39,0x91,0x91}, {0xa4,0x31,0x95,0x95}, {0x37,0xd3,0xe4,0xe4}, {0x8b,0xf2,0x79,0x79}, +{0x32,0xd5,0xe7,0xe7}, {0x43,0x8b,0xc8,0xc8}, {0x59,0x6e,0x37,0x37}, {0xb7,0xda,0x6d,0x6d}, +{0x8c,0x01,0x8d,0x8d}, {0x64,0xb1,0xd5,0xd5}, {0xd2,0x9c,0x4e,0x4e}, {0xe0,0x49,0xa9,0xa9}, +{0xb4,0xd8,0x6c,0x6c}, {0xfa,0xac,0x56,0x56}, {0x07,0xf3,0xf4,0xf4}, {0x25,0xcf,0xea,0xea}, +{0xaf,0xca,0x65,0x65}, {0x8e,0xf4,0x7a,0x7a}, {0xe9,0x47,0xae,0xae}, {0x18,0x10,0x08,0x08}, +{0xd5,0x6f,0xba,0xba}, {0x88,0xf0,0x78,0x78}, {0x6f,0x4a,0x25,0x25}, {0x72,0x5c,0x2e,0x2e}, +{0x24,0x38,0x1c,0x1c}, {0xf1,0x57,0xa6,0xa6}, {0xc7,0x73,0xb4,0xb4}, {0x51,0x97,0xc6,0xc6}, +{0x23,0xcb,0xe8,0xe8}, {0x7c,0xa1,0xdd,0xdd}, {0x9c,0xe8,0x74,0x74}, {0x21,0x3e,0x1f,0x1f}, +{0xdd,0x96,0x4b,0x4b}, {0xdc,0x61,0xbd,0xbd}, {0x86,0x0d,0x8b,0x8b}, {0x85,0x0f,0x8a,0x8a}, +{0x90,0xe0,0x70,0x70}, {0x42,0x7c,0x3e,0x3e}, {0xc4,0x71,0xb5,0xb5}, {0xaa,0xcc,0x66,0x66}, +{0xd8,0x90,0x48,0x48}, {0x05,0x06,0x03,0x03}, {0x01,0xf7,0xf6,0xf6}, {0x12,0x1c,0x0e,0x0e}, +{0xa3,0xc2,0x61,0x61}, {0x5f,0x6a,0x35,0x35}, {0xf9,0xae,0x57,0x57}, {0xd0,0x69,0xb9,0xb9}, +{0x91,0x17,0x86,0x86}, {0x58,0x99,0xc1,0xc1}, {0x27,0x3a,0x1d,0x1d}, {0xb9,0x27,0x9e,0x9e}, +{0x38,0xd9,0xe1,0xe1}, {0x13,0xeb,0xf8,0xf8}, {0xb3,0x2b,0x98,0x98}, {0x33,0x22,0x11,0x11}, +{0xbb,0xd2,0x69,0x69}, {0x70,0xa9,0xd9,0xd9}, {0x89,0x07,0x8e,0x8e}, {0xa7,0x33,0x94,0x94}, +{0xb6,0x2d,0x9b,0x9b}, {0x22,0x3c,0x1e,0x1e}, {0x92,0x15,0x87,0x87}, {0x20,0xc9,0xe9,0xe9}, +{0x49,0x87,0xce,0xce}, {0xff,0xaa,0x55,0x55}, {0x78,0x50,0x28,0x28}, {0x7a,0xa5,0xdf,0xdf}, +{0x8f,0x03,0x8c,0x8c}, {0xf8,0x59,0xa1,0xa1}, {0x80,0x09,0x89,0x89}, {0x17,0x1a,0x0d,0x0d}, +{0xda,0x65,0xbf,0xbf}, {0x31,0xd7,0xe6,0xe6}, {0xc6,0x84,0x42,0x42}, {0xb8,0xd0,0x68,0x68}, +{0xc3,0x82,0x41,0x41}, {0xb0,0x29,0x99,0x99}, {0x77,0x5a,0x2d,0x2d}, {0x11,0x1e,0x0f,0x0f}, +{0xcb,0x7b,0xb0,0xb0}, {0xfc,0xa8,0x54,0x54}, {0xd6,0x6d,0xbb,0xbb}, {0x3a,0x2c,0x16,0x16} + } +}; +#define T2 xT2.xt8 + +static const union xtab xT3 = { + .xt8 = { +{0x63,0xa5,0xc6,0x63}, {0x7c,0x84,0xf8,0x7c}, {0x77,0x99,0xee,0x77}, {0x7b,0x8d,0xf6,0x7b}, +{0xf2,0x0d,0xff,0xf2}, {0x6b,0xbd,0xd6,0x6b}, {0x6f,0xb1,0xde,0x6f}, {0xc5,0x54,0x91,0xc5}, +{0x30,0x50,0x60,0x30}, {0x01,0x03,0x02,0x01}, {0x67,0xa9,0xce,0x67}, {0x2b,0x7d,0x56,0x2b}, +{0xfe,0x19,0xe7,0xfe}, {0xd7,0x62,0xb5,0xd7}, {0xab,0xe6,0x4d,0xab}, {0x76,0x9a,0xec,0x76}, +{0xca,0x45,0x8f,0xca}, {0x82,0x9d,0x1f,0x82}, {0xc9,0x40,0x89,0xc9}, {0x7d,0x87,0xfa,0x7d}, +{0xfa,0x15,0xef,0xfa}, {0x59,0xeb,0xb2,0x59}, {0x47,0xc9,0x8e,0x47}, {0xf0,0x0b,0xfb,0xf0}, +{0xad,0xec,0x41,0xad}, {0xd4,0x67,0xb3,0xd4}, {0xa2,0xfd,0x5f,0xa2}, {0xaf,0xea,0x45,0xaf}, +{0x9c,0xbf,0x23,0x9c}, {0xa4,0xf7,0x53,0xa4}, {0x72,0x96,0xe4,0x72}, {0xc0,0x5b,0x9b,0xc0}, +{0xb7,0xc2,0x75,0xb7}, {0xfd,0x1c,0xe1,0xfd}, {0x93,0xae,0x3d,0x93}, {0x26,0x6a,0x4c,0x26}, +{0x36,0x5a,0x6c,0x36}, {0x3f,0x41,0x7e,0x3f}, {0xf7,0x02,0xf5,0xf7}, {0xcc,0x4f,0x83,0xcc}, +{0x34,0x5c,0x68,0x34}, {0xa5,0xf4,0x51,0xa5}, {0xe5,0x34,0xd1,0xe5}, {0xf1,0x08,0xf9,0xf1}, +{0x71,0x93,0xe2,0x71}, {0xd8,0x73,0xab,0xd8}, {0x31,0x53,0x62,0x31}, {0x15,0x3f,0x2a,0x15}, +{0x04,0x0c,0x08,0x04}, {0xc7,0x52,0x95,0xc7}, {0x23,0x65,0x46,0x23}, {0xc3,0x5e,0x9d,0xc3}, +{0x18,0x28,0x30,0x18}, {0x96,0xa1,0x37,0x96}, {0x05,0x0f,0x0a,0x05}, {0x9a,0xb5,0x2f,0x9a}, +{0x07,0x09,0x0e,0x07}, {0x12,0x36,0x24,0x12}, {0x80,0x9b,0x1b,0x80}, {0xe2,0x3d,0xdf,0xe2}, +{0xeb,0x26,0xcd,0xeb}, {0x27,0x69,0x4e,0x27}, {0xb2,0xcd,0x7f,0xb2}, {0x75,0x9f,0xea,0x75}, +{0x09,0x1b,0x12,0x09}, {0x83,0x9e,0x1d,0x83}, {0x2c,0x74,0x58,0x2c}, {0x1a,0x2e,0x34,0x1a}, +{0x1b,0x2d,0x36,0x1b}, {0x6e,0xb2,0xdc,0x6e}, {0x5a,0xee,0xb4,0x5a}, {0xa0,0xfb,0x5b,0xa0}, +{0x52,0xf6,0xa4,0x52}, {0x3b,0x4d,0x76,0x3b}, {0xd6,0x61,0xb7,0xd6}, {0xb3,0xce,0x7d,0xb3}, +{0x29,0x7b,0x52,0x29}, {0xe3,0x3e,0xdd,0xe3}, {0x2f,0x71,0x5e,0x2f}, {0x84,0x97,0x13,0x84}, +{0x53,0xf5,0xa6,0x53}, {0xd1,0x68,0xb9,0xd1}, {0x00,0x00,0x00,0x00}, {0xed,0x2c,0xc1,0xed}, +{0x20,0x60,0x40,0x20}, {0xfc,0x1f,0xe3,0xfc}, {0xb1,0xc8,0x79,0xb1}, {0x5b,0xed,0xb6,0x5b}, +{0x6a,0xbe,0xd4,0x6a}, {0xcb,0x46,0x8d,0xcb}, {0xbe,0xd9,0x67,0xbe}, {0x39,0x4b,0x72,0x39}, +{0x4a,0xde,0x94,0x4a}, {0x4c,0xd4,0x98,0x4c}, {0x58,0xe8,0xb0,0x58}, {0xcf,0x4a,0x85,0xcf}, +{0xd0,0x6b,0xbb,0xd0}, {0xef,0x2a,0xc5,0xef}, {0xaa,0xe5,0x4f,0xaa}, {0xfb,0x16,0xed,0xfb}, +{0x43,0xc5,0x86,0x43}, {0x4d,0xd7,0x9a,0x4d}, {0x33,0x55,0x66,0x33}, {0x85,0x94,0x11,0x85}, +{0x45,0xcf,0x8a,0x45}, {0xf9,0x10,0xe9,0xf9}, {0x02,0x06,0x04,0x02}, {0x7f,0x81,0xfe,0x7f}, +{0x50,0xf0,0xa0,0x50}, {0x3c,0x44,0x78,0x3c}, {0x9f,0xba,0x25,0x9f}, {0xa8,0xe3,0x4b,0xa8}, +{0x51,0xf3,0xa2,0x51}, {0xa3,0xfe,0x5d,0xa3}, {0x40,0xc0,0x80,0x40}, {0x8f,0x8a,0x05,0x8f}, +{0x92,0xad,0x3f,0x92}, {0x9d,0xbc,0x21,0x9d}, {0x38,0x48,0x70,0x38}, {0xf5,0x04,0xf1,0xf5}, +{0xbc,0xdf,0x63,0xbc}, {0xb6,0xc1,0x77,0xb6}, {0xda,0x75,0xaf,0xda}, {0x21,0x63,0x42,0x21}, +{0x10,0x30,0x20,0x10}, {0xff,0x1a,0xe5,0xff}, {0xf3,0x0e,0xfd,0xf3}, {0xd2,0x6d,0xbf,0xd2}, +{0xcd,0x4c,0x81,0xcd}, {0x0c,0x14,0x18,0x0c}, {0x13,0x35,0x26,0x13}, {0xec,0x2f,0xc3,0xec}, +{0x5f,0xe1,0xbe,0x5f}, {0x97,0xa2,0x35,0x97}, {0x44,0xcc,0x88,0x44}, {0x17,0x39,0x2e,0x17}, +{0xc4,0x57,0x93,0xc4}, {0xa7,0xf2,0x55,0xa7}, {0x7e,0x82,0xfc,0x7e}, {0x3d,0x47,0x7a,0x3d}, +{0x64,0xac,0xc8,0x64}, {0x5d,0xe7,0xba,0x5d}, {0x19,0x2b,0x32,0x19}, {0x73,0x95,0xe6,0x73}, +{0x60,0xa0,0xc0,0x60}, {0x81,0x98,0x19,0x81}, {0x4f,0xd1,0x9e,0x4f}, {0xdc,0x7f,0xa3,0xdc}, +{0x22,0x66,0x44,0x22}, {0x2a,0x7e,0x54,0x2a}, {0x90,0xab,0x3b,0x90}, {0x88,0x83,0x0b,0x88}, +{0x46,0xca,0x8c,0x46}, {0xee,0x29,0xc7,0xee}, {0xb8,0xd3,0x6b,0xb8}, {0x14,0x3c,0x28,0x14}, +{0xde,0x79,0xa7,0xde}, {0x5e,0xe2,0xbc,0x5e}, {0x0b,0x1d,0x16,0x0b}, {0xdb,0x76,0xad,0xdb}, +{0xe0,0x3b,0xdb,0xe0}, {0x32,0x56,0x64,0x32}, {0x3a,0x4e,0x74,0x3a}, {0x0a,0x1e,0x14,0x0a}, +{0x49,0xdb,0x92,0x49}, {0x06,0x0a,0x0c,0x06}, {0x24,0x6c,0x48,0x24}, {0x5c,0xe4,0xb8,0x5c}, +{0xc2,0x5d,0x9f,0xc2}, {0xd3,0x6e,0xbd,0xd3}, {0xac,0xef,0x43,0xac}, {0x62,0xa6,0xc4,0x62}, +{0x91,0xa8,0x39,0x91}, {0x95,0xa4,0x31,0x95}, {0xe4,0x37,0xd3,0xe4}, {0x79,0x8b,0xf2,0x79}, +{0xe7,0x32,0xd5,0xe7}, {0xc8,0x43,0x8b,0xc8}, {0x37,0x59,0x6e,0x37}, {0x6d,0xb7,0xda,0x6d}, +{0x8d,0x8c,0x01,0x8d}, {0xd5,0x64,0xb1,0xd5}, {0x4e,0xd2,0x9c,0x4e}, {0xa9,0xe0,0x49,0xa9}, +{0x6c,0xb4,0xd8,0x6c}, {0x56,0xfa,0xac,0x56}, {0xf4,0x07,0xf3,0xf4}, {0xea,0x25,0xcf,0xea}, +{0x65,0xaf,0xca,0x65}, {0x7a,0x8e,0xf4,0x7a}, {0xae,0xe9,0x47,0xae}, {0x08,0x18,0x10,0x08}, +{0xba,0xd5,0x6f,0xba}, {0x78,0x88,0xf0,0x78}, {0x25,0x6f,0x4a,0x25}, {0x2e,0x72,0x5c,0x2e}, +{0x1c,0x24,0x38,0x1c}, {0xa6,0xf1,0x57,0xa6}, {0xb4,0xc7,0x73,0xb4}, {0xc6,0x51,0x97,0xc6}, +{0xe8,0x23,0xcb,0xe8}, {0xdd,0x7c,0xa1,0xdd}, {0x74,0x9c,0xe8,0x74}, {0x1f,0x21,0x3e,0x1f}, +{0x4b,0xdd,0x96,0x4b}, {0xbd,0xdc,0x61,0xbd}, {0x8b,0x86,0x0d,0x8b}, {0x8a,0x85,0x0f,0x8a}, +{0x70,0x90,0xe0,0x70}, {0x3e,0x42,0x7c,0x3e}, {0xb5,0xc4,0x71,0xb5}, {0x66,0xaa,0xcc,0x66}, +{0x48,0xd8,0x90,0x48}, {0x03,0x05,0x06,0x03}, {0xf6,0x01,0xf7,0xf6}, {0x0e,0x12,0x1c,0x0e}, +{0x61,0xa3,0xc2,0x61}, {0x35,0x5f,0x6a,0x35}, {0x57,0xf9,0xae,0x57}, {0xb9,0xd0,0x69,0xb9}, +{0x86,0x91,0x17,0x86}, {0xc1,0x58,0x99,0xc1}, {0x1d,0x27,0x3a,0x1d}, {0x9e,0xb9,0x27,0x9e}, +{0xe1,0x38,0xd9,0xe1}, {0xf8,0x13,0xeb,0xf8}, {0x98,0xb3,0x2b,0x98}, {0x11,0x33,0x22,0x11}, +{0x69,0xbb,0xd2,0x69}, {0xd9,0x70,0xa9,0xd9}, {0x8e,0x89,0x07,0x8e}, {0x94,0xa7,0x33,0x94}, +{0x9b,0xb6,0x2d,0x9b}, {0x1e,0x22,0x3c,0x1e}, {0x87,0x92,0x15,0x87}, {0xe9,0x20,0xc9,0xe9}, +{0xce,0x49,0x87,0xce}, {0x55,0xff,0xaa,0x55}, {0x28,0x78,0x50,0x28}, {0xdf,0x7a,0xa5,0xdf}, +{0x8c,0x8f,0x03,0x8c}, {0xa1,0xf8,0x59,0xa1}, {0x89,0x80,0x09,0x89}, {0x0d,0x17,0x1a,0x0d}, +{0xbf,0xda,0x65,0xbf}, {0xe6,0x31,0xd7,0xe6}, {0x42,0xc6,0x84,0x42}, {0x68,0xb8,0xd0,0x68}, +{0x41,0xc3,0x82,0x41}, {0x99,0xb0,0x29,0x99}, {0x2d,0x77,0x5a,0x2d}, {0x0f,0x11,0x1e,0x0f}, +{0xb0,0xcb,0x7b,0xb0}, {0x54,0xfc,0xa8,0x54}, {0xbb,0xd6,0x6d,0xbb}, {0x16,0x3a,0x2c,0x16} + } +}; +#define T3 xT3.xt8 + +static const union xtab xT4 = { + .xt8 = { +{0x63,0x63,0xa5,0xc6}, {0x7c,0x7c,0x84,0xf8}, {0x77,0x77,0x99,0xee}, {0x7b,0x7b,0x8d,0xf6}, +{0xf2,0xf2,0x0d,0xff}, {0x6b,0x6b,0xbd,0xd6}, {0x6f,0x6f,0xb1,0xde}, {0xc5,0xc5,0x54,0x91}, +{0x30,0x30,0x50,0x60}, {0x01,0x01,0x03,0x02}, {0x67,0x67,0xa9,0xce}, {0x2b,0x2b,0x7d,0x56}, +{0xfe,0xfe,0x19,0xe7}, {0xd7,0xd7,0x62,0xb5}, {0xab,0xab,0xe6,0x4d}, {0x76,0x76,0x9a,0xec}, +{0xca,0xca,0x45,0x8f}, {0x82,0x82,0x9d,0x1f}, {0xc9,0xc9,0x40,0x89}, {0x7d,0x7d,0x87,0xfa}, +{0xfa,0xfa,0x15,0xef}, {0x59,0x59,0xeb,0xb2}, {0x47,0x47,0xc9,0x8e}, {0xf0,0xf0,0x0b,0xfb}, +{0xad,0xad,0xec,0x41}, {0xd4,0xd4,0x67,0xb3}, {0xa2,0xa2,0xfd,0x5f}, {0xaf,0xaf,0xea,0x45}, +{0x9c,0x9c,0xbf,0x23}, {0xa4,0xa4,0xf7,0x53}, {0x72,0x72,0x96,0xe4}, {0xc0,0xc0,0x5b,0x9b}, +{0xb7,0xb7,0xc2,0x75}, {0xfd,0xfd,0x1c,0xe1}, {0x93,0x93,0xae,0x3d}, {0x26,0x26,0x6a,0x4c}, +{0x36,0x36,0x5a,0x6c}, {0x3f,0x3f,0x41,0x7e}, {0xf7,0xf7,0x02,0xf5}, {0xcc,0xcc,0x4f,0x83}, +{0x34,0x34,0x5c,0x68}, {0xa5,0xa5,0xf4,0x51}, {0xe5,0xe5,0x34,0xd1}, {0xf1,0xf1,0x08,0xf9}, +{0x71,0x71,0x93,0xe2}, {0xd8,0xd8,0x73,0xab}, {0x31,0x31,0x53,0x62}, {0x15,0x15,0x3f,0x2a}, +{0x04,0x04,0x0c,0x08}, {0xc7,0xc7,0x52,0x95}, {0x23,0x23,0x65,0x46}, {0xc3,0xc3,0x5e,0x9d}, +{0x18,0x18,0x28,0x30}, {0x96,0x96,0xa1,0x37}, {0x05,0x05,0x0f,0x0a}, {0x9a,0x9a,0xb5,0x2f}, +{0x07,0x07,0x09,0x0e}, {0x12,0x12,0x36,0x24}, {0x80,0x80,0x9b,0x1b}, {0xe2,0xe2,0x3d,0xdf}, +{0xeb,0xeb,0x26,0xcd}, {0x27,0x27,0x69,0x4e}, {0xb2,0xb2,0xcd,0x7f}, {0x75,0x75,0x9f,0xea}, +{0x09,0x09,0x1b,0x12}, {0x83,0x83,0x9e,0x1d}, {0x2c,0x2c,0x74,0x58}, {0x1a,0x1a,0x2e,0x34}, +{0x1b,0x1b,0x2d,0x36}, {0x6e,0x6e,0xb2,0xdc}, {0x5a,0x5a,0xee,0xb4}, {0xa0,0xa0,0xfb,0x5b}, +{0x52,0x52,0xf6,0xa4}, {0x3b,0x3b,0x4d,0x76}, {0xd6,0xd6,0x61,0xb7}, {0xb3,0xb3,0xce,0x7d}, +{0x29,0x29,0x7b,0x52}, {0xe3,0xe3,0x3e,0xdd}, {0x2f,0x2f,0x71,0x5e}, {0x84,0x84,0x97,0x13}, +{0x53,0x53,0xf5,0xa6}, {0xd1,0xd1,0x68,0xb9}, {0x00,0x00,0x00,0x00}, {0xed,0xed,0x2c,0xc1}, +{0x20,0x20,0x60,0x40}, {0xfc,0xfc,0x1f,0xe3}, {0xb1,0xb1,0xc8,0x79}, {0x5b,0x5b,0xed,0xb6}, +{0x6a,0x6a,0xbe,0xd4}, {0xcb,0xcb,0x46,0x8d}, {0xbe,0xbe,0xd9,0x67}, {0x39,0x39,0x4b,0x72}, +{0x4a,0x4a,0xde,0x94}, {0x4c,0x4c,0xd4,0x98}, {0x58,0x58,0xe8,0xb0}, {0xcf,0xcf,0x4a,0x85}, +{0xd0,0xd0,0x6b,0xbb}, {0xef,0xef,0x2a,0xc5}, {0xaa,0xaa,0xe5,0x4f}, {0xfb,0xfb,0x16,0xed}, +{0x43,0x43,0xc5,0x86}, {0x4d,0x4d,0xd7,0x9a}, {0x33,0x33,0x55,0x66}, {0x85,0x85,0x94,0x11}, +{0x45,0x45,0xcf,0x8a}, {0xf9,0xf9,0x10,0xe9}, {0x02,0x02,0x06,0x04}, {0x7f,0x7f,0x81,0xfe}, +{0x50,0x50,0xf0,0xa0}, {0x3c,0x3c,0x44,0x78}, {0x9f,0x9f,0xba,0x25}, {0xa8,0xa8,0xe3,0x4b}, +{0x51,0x51,0xf3,0xa2}, {0xa3,0xa3,0xfe,0x5d}, {0x40,0x40,0xc0,0x80}, {0x8f,0x8f,0x8a,0x05}, +{0x92,0x92,0xad,0x3f}, {0x9d,0x9d,0xbc,0x21}, {0x38,0x38,0x48,0x70}, {0xf5,0xf5,0x04,0xf1}, +{0xbc,0xbc,0xdf,0x63}, {0xb6,0xb6,0xc1,0x77}, {0xda,0xda,0x75,0xaf}, {0x21,0x21,0x63,0x42}, +{0x10,0x10,0x30,0x20}, {0xff,0xff,0x1a,0xe5}, {0xf3,0xf3,0x0e,0xfd}, {0xd2,0xd2,0x6d,0xbf}, +{0xcd,0xcd,0x4c,0x81}, {0x0c,0x0c,0x14,0x18}, {0x13,0x13,0x35,0x26}, {0xec,0xec,0x2f,0xc3}, +{0x5f,0x5f,0xe1,0xbe}, {0x97,0x97,0xa2,0x35}, {0x44,0x44,0xcc,0x88}, {0x17,0x17,0x39,0x2e}, +{0xc4,0xc4,0x57,0x93}, {0xa7,0xa7,0xf2,0x55}, {0x7e,0x7e,0x82,0xfc}, {0x3d,0x3d,0x47,0x7a}, +{0x64,0x64,0xac,0xc8}, {0x5d,0x5d,0xe7,0xba}, {0x19,0x19,0x2b,0x32}, {0x73,0x73,0x95,0xe6}, +{0x60,0x60,0xa0,0xc0}, {0x81,0x81,0x98,0x19}, {0x4f,0x4f,0xd1,0x9e}, {0xdc,0xdc,0x7f,0xa3}, +{0x22,0x22,0x66,0x44}, {0x2a,0x2a,0x7e,0x54}, {0x90,0x90,0xab,0x3b}, {0x88,0x88,0x83,0x0b}, +{0x46,0x46,0xca,0x8c}, {0xee,0xee,0x29,0xc7}, {0xb8,0xb8,0xd3,0x6b}, {0x14,0x14,0x3c,0x28}, +{0xde,0xde,0x79,0xa7}, {0x5e,0x5e,0xe2,0xbc}, {0x0b,0x0b,0x1d,0x16}, {0xdb,0xdb,0x76,0xad}, +{0xe0,0xe0,0x3b,0xdb}, {0x32,0x32,0x56,0x64}, {0x3a,0x3a,0x4e,0x74}, {0x0a,0x0a,0x1e,0x14}, +{0x49,0x49,0xdb,0x92}, {0x06,0x06,0x0a,0x0c}, {0x24,0x24,0x6c,0x48}, {0x5c,0x5c,0xe4,0xb8}, +{0xc2,0xc2,0x5d,0x9f}, {0xd3,0xd3,0x6e,0xbd}, {0xac,0xac,0xef,0x43}, {0x62,0x62,0xa6,0xc4}, +{0x91,0x91,0xa8,0x39}, {0x95,0x95,0xa4,0x31}, {0xe4,0xe4,0x37,0xd3}, {0x79,0x79,0x8b,0xf2}, +{0xe7,0xe7,0x32,0xd5}, {0xc8,0xc8,0x43,0x8b}, {0x37,0x37,0x59,0x6e}, {0x6d,0x6d,0xb7,0xda}, +{0x8d,0x8d,0x8c,0x01}, {0xd5,0xd5,0x64,0xb1}, {0x4e,0x4e,0xd2,0x9c}, {0xa9,0xa9,0xe0,0x49}, +{0x6c,0x6c,0xb4,0xd8}, {0x56,0x56,0xfa,0xac}, {0xf4,0xf4,0x07,0xf3}, {0xea,0xea,0x25,0xcf}, +{0x65,0x65,0xaf,0xca}, {0x7a,0x7a,0x8e,0xf4}, {0xae,0xae,0xe9,0x47}, {0x08,0x08,0x18,0x10}, +{0xba,0xba,0xd5,0x6f}, {0x78,0x78,0x88,0xf0}, {0x25,0x25,0x6f,0x4a}, {0x2e,0x2e,0x72,0x5c}, +{0x1c,0x1c,0x24,0x38}, {0xa6,0xa6,0xf1,0x57}, {0xb4,0xb4,0xc7,0x73}, {0xc6,0xc6,0x51,0x97}, +{0xe8,0xe8,0x23,0xcb}, {0xdd,0xdd,0x7c,0xa1}, {0x74,0x74,0x9c,0xe8}, {0x1f,0x1f,0x21,0x3e}, +{0x4b,0x4b,0xdd,0x96}, {0xbd,0xbd,0xdc,0x61}, {0x8b,0x8b,0x86,0x0d}, {0x8a,0x8a,0x85,0x0f}, +{0x70,0x70,0x90,0xe0}, {0x3e,0x3e,0x42,0x7c}, {0xb5,0xb5,0xc4,0x71}, {0x66,0x66,0xaa,0xcc}, +{0x48,0x48,0xd8,0x90}, {0x03,0x03,0x05,0x06}, {0xf6,0xf6,0x01,0xf7}, {0x0e,0x0e,0x12,0x1c}, +{0x61,0x61,0xa3,0xc2}, {0x35,0x35,0x5f,0x6a}, {0x57,0x57,0xf9,0xae}, {0xb9,0xb9,0xd0,0x69}, +{0x86,0x86,0x91,0x17}, {0xc1,0xc1,0x58,0x99}, {0x1d,0x1d,0x27,0x3a}, {0x9e,0x9e,0xb9,0x27}, +{0xe1,0xe1,0x38,0xd9}, {0xf8,0xf8,0x13,0xeb}, {0x98,0x98,0xb3,0x2b}, {0x11,0x11,0x33,0x22}, +{0x69,0x69,0xbb,0xd2}, {0xd9,0xd9,0x70,0xa9}, {0x8e,0x8e,0x89,0x07}, {0x94,0x94,0xa7,0x33}, +{0x9b,0x9b,0xb6,0x2d}, {0x1e,0x1e,0x22,0x3c}, {0x87,0x87,0x92,0x15}, {0xe9,0xe9,0x20,0xc9}, +{0xce,0xce,0x49,0x87}, {0x55,0x55,0xff,0xaa}, {0x28,0x28,0x78,0x50}, {0xdf,0xdf,0x7a,0xa5}, +{0x8c,0x8c,0x8f,0x03}, {0xa1,0xa1,0xf8,0x59}, {0x89,0x89,0x80,0x09}, {0x0d,0x0d,0x17,0x1a}, +{0xbf,0xbf,0xda,0x65}, {0xe6,0xe6,0x31,0xd7}, {0x42,0x42,0xc6,0x84}, {0x68,0x68,0xb8,0xd0}, +{0x41,0x41,0xc3,0x82}, {0x99,0x99,0xb0,0x29}, {0x2d,0x2d,0x77,0x5a}, {0x0f,0x0f,0x11,0x1e}, +{0xb0,0xb0,0xcb,0x7b}, {0x54,0x54,0xfc,0xa8}, {0xbb,0xbb,0xd6,0x6d}, {0x16,0x16,0x3a,0x2c} + } +}; +#define T4 xT4.xt8 + +static const union xtab xT5 = { + .xt8 = { +{0x51,0xf4,0xa7,0x50}, {0x7e,0x41,0x65,0x53}, {0x1a,0x17,0xa4,0xc3}, {0x3a,0x27,0x5e,0x96}, +{0x3b,0xab,0x6b,0xcb}, {0x1f,0x9d,0x45,0xf1}, {0xac,0xfa,0x58,0xab}, {0x4b,0xe3,0x03,0x93}, +{0x20,0x30,0xfa,0x55}, {0xad,0x76,0x6d,0xf6}, {0x88,0xcc,0x76,0x91}, {0xf5,0x02,0x4c,0x25}, +{0x4f,0xe5,0xd7,0xfc}, {0xc5,0x2a,0xcb,0xd7}, {0x26,0x35,0x44,0x80}, {0xb5,0x62,0xa3,0x8f}, +{0xde,0xb1,0x5a,0x49}, {0x25,0xba,0x1b,0x67}, {0x45,0xea,0x0e,0x98}, {0x5d,0xfe,0xc0,0xe1}, +{0xc3,0x2f,0x75,0x02}, {0x81,0x4c,0xf0,0x12}, {0x8d,0x46,0x97,0xa3}, {0x6b,0xd3,0xf9,0xc6}, +{0x03,0x8f,0x5f,0xe7}, {0x15,0x92,0x9c,0x95}, {0xbf,0x6d,0x7a,0xeb}, {0x95,0x52,0x59,0xda}, +{0xd4,0xbe,0x83,0x2d}, {0x58,0x74,0x21,0xd3}, {0x49,0xe0,0x69,0x29}, {0x8e,0xc9,0xc8,0x44}, +{0x75,0xc2,0x89,0x6a}, {0xf4,0x8e,0x79,0x78}, {0x99,0x58,0x3e,0x6b}, {0x27,0xb9,0x71,0xdd}, +{0xbe,0xe1,0x4f,0xb6}, {0xf0,0x88,0xad,0x17}, {0xc9,0x20,0xac,0x66}, {0x7d,0xce,0x3a,0xb4}, +{0x63,0xdf,0x4a,0x18}, {0xe5,0x1a,0x31,0x82}, {0x97,0x51,0x33,0x60}, {0x62,0x53,0x7f,0x45}, +{0xb1,0x64,0x77,0xe0}, {0xbb,0x6b,0xae,0x84}, {0xfe,0x81,0xa0,0x1c}, {0xf9,0x08,0x2b,0x94}, +{0x70,0x48,0x68,0x58}, {0x8f,0x45,0xfd,0x19}, {0x94,0xde,0x6c,0x87}, {0x52,0x7b,0xf8,0xb7}, +{0xab,0x73,0xd3,0x23}, {0x72,0x4b,0x02,0xe2}, {0xe3,0x1f,0x8f,0x57}, {0x66,0x55,0xab,0x2a}, +{0xb2,0xeb,0x28,0x07}, {0x2f,0xb5,0xc2,0x03}, {0x86,0xc5,0x7b,0x9a}, {0xd3,0x37,0x08,0xa5}, +{0x30,0x28,0x87,0xf2}, {0x23,0xbf,0xa5,0xb2}, {0x02,0x03,0x6a,0xba}, {0xed,0x16,0x82,0x5c}, +{0x8a,0xcf,0x1c,0x2b}, {0xa7,0x79,0xb4,0x92}, {0xf3,0x07,0xf2,0xf0}, {0x4e,0x69,0xe2,0xa1}, +{0x65,0xda,0xf4,0xcd}, {0x06,0x05,0xbe,0xd5}, {0xd1,0x34,0x62,0x1f}, {0xc4,0xa6,0xfe,0x8a}, +{0x34,0x2e,0x53,0x9d}, {0xa2,0xf3,0x55,0xa0}, {0x05,0x8a,0xe1,0x32}, {0xa4,0xf6,0xeb,0x75}, +{0x0b,0x83,0xec,0x39}, {0x40,0x60,0xef,0xaa}, {0x5e,0x71,0x9f,0x06}, {0xbd,0x6e,0x10,0x51}, +{0x3e,0x21,0x8a,0xf9}, {0x96,0xdd,0x06,0x3d}, {0xdd,0x3e,0x05,0xae}, {0x4d,0xe6,0xbd,0x46}, +{0x91,0x54,0x8d,0xb5}, {0x71,0xc4,0x5d,0x05}, {0x04,0x06,0xd4,0x6f}, {0x60,0x50,0x15,0xff}, +{0x19,0x98,0xfb,0x24}, {0xd6,0xbd,0xe9,0x97}, {0x89,0x40,0x43,0xcc}, {0x67,0xd9,0x9e,0x77}, +{0xb0,0xe8,0x42,0xbd}, {0x07,0x89,0x8b,0x88}, {0xe7,0x19,0x5b,0x38}, {0x79,0xc8,0xee,0xdb}, +{0xa1,0x7c,0x0a,0x47}, {0x7c,0x42,0x0f,0xe9}, {0xf8,0x84,0x1e,0xc9}, {0x00,0x00,0x00,0x00}, +{0x09,0x80,0x86,0x83}, {0x32,0x2b,0xed,0x48}, {0x1e,0x11,0x70,0xac}, {0x6c,0x5a,0x72,0x4e}, +{0xfd,0x0e,0xff,0xfb}, {0x0f,0x85,0x38,0x56}, {0x3d,0xae,0xd5,0x1e}, {0x36,0x2d,0x39,0x27}, +{0x0a,0x0f,0xd9,0x64}, {0x68,0x5c,0xa6,0x21}, {0x9b,0x5b,0x54,0xd1}, {0x24,0x36,0x2e,0x3a}, +{0x0c,0x0a,0x67,0xb1}, {0x93,0x57,0xe7,0x0f}, {0xb4,0xee,0x96,0xd2}, {0x1b,0x9b,0x91,0x9e}, +{0x80,0xc0,0xc5,0x4f}, {0x61,0xdc,0x20,0xa2}, {0x5a,0x77,0x4b,0x69}, {0x1c,0x12,0x1a,0x16}, +{0xe2,0x93,0xba,0x0a}, {0xc0,0xa0,0x2a,0xe5}, {0x3c,0x22,0xe0,0x43}, {0x12,0x1b,0x17,0x1d}, +{0x0e,0x09,0x0d,0x0b}, {0xf2,0x8b,0xc7,0xad}, {0x2d,0xb6,0xa8,0xb9}, {0x14,0x1e,0xa9,0xc8}, +{0x57,0xf1,0x19,0x85}, {0xaf,0x75,0x07,0x4c}, {0xee,0x99,0xdd,0xbb}, {0xa3,0x7f,0x60,0xfd}, +{0xf7,0x01,0x26,0x9f}, {0x5c,0x72,0xf5,0xbc}, {0x44,0x66,0x3b,0xc5}, {0x5b,0xfb,0x7e,0x34}, +{0x8b,0x43,0x29,0x76}, {0xcb,0x23,0xc6,0xdc}, {0xb6,0xed,0xfc,0x68}, {0xb8,0xe4,0xf1,0x63}, +{0xd7,0x31,0xdc,0xca}, {0x42,0x63,0x85,0x10}, {0x13,0x97,0x22,0x40}, {0x84,0xc6,0x11,0x20}, +{0x85,0x4a,0x24,0x7d}, {0xd2,0xbb,0x3d,0xf8}, {0xae,0xf9,0x32,0x11}, {0xc7,0x29,0xa1,0x6d}, +{0x1d,0x9e,0x2f,0x4b}, {0xdc,0xb2,0x30,0xf3}, {0x0d,0x86,0x52,0xec}, {0x77,0xc1,0xe3,0xd0}, +{0x2b,0xb3,0x16,0x6c}, {0xa9,0x70,0xb9,0x99}, {0x11,0x94,0x48,0xfa}, {0x47,0xe9,0x64,0x22}, +{0xa8,0xfc,0x8c,0xc4}, {0xa0,0xf0,0x3f,0x1a}, {0x56,0x7d,0x2c,0xd8}, {0x22,0x33,0x90,0xef}, +{0x87,0x49,0x4e,0xc7}, {0xd9,0x38,0xd1,0xc1}, {0x8c,0xca,0xa2,0xfe}, {0x98,0xd4,0x0b,0x36}, +{0xa6,0xf5,0x81,0xcf}, {0xa5,0x7a,0xde,0x28}, {0xda,0xb7,0x8e,0x26}, {0x3f,0xad,0xbf,0xa4}, +{0x2c,0x3a,0x9d,0xe4}, {0x50,0x78,0x92,0x0d}, {0x6a,0x5f,0xcc,0x9b}, {0x54,0x7e,0x46,0x62}, +{0xf6,0x8d,0x13,0xc2}, {0x90,0xd8,0xb8,0xe8}, {0x2e,0x39,0xf7,0x5e}, {0x82,0xc3,0xaf,0xf5}, +{0x9f,0x5d,0x80,0xbe}, {0x69,0xd0,0x93,0x7c}, {0x6f,0xd5,0x2d,0xa9}, {0xcf,0x25,0x12,0xb3}, +{0xc8,0xac,0x99,0x3b}, {0x10,0x18,0x7d,0xa7}, {0xe8,0x9c,0x63,0x6e}, {0xdb,0x3b,0xbb,0x7b}, +{0xcd,0x26,0x78,0x09}, {0x6e,0x59,0x18,0xf4}, {0xec,0x9a,0xb7,0x01}, {0x83,0x4f,0x9a,0xa8}, +{0xe6,0x95,0x6e,0x65}, {0xaa,0xff,0xe6,0x7e}, {0x21,0xbc,0xcf,0x08}, {0xef,0x15,0xe8,0xe6}, +{0xba,0xe7,0x9b,0xd9}, {0x4a,0x6f,0x36,0xce}, {0xea,0x9f,0x09,0xd4}, {0x29,0xb0,0x7c,0xd6}, +{0x31,0xa4,0xb2,0xaf}, {0x2a,0x3f,0x23,0x31}, {0xc6,0xa5,0x94,0x30}, {0x35,0xa2,0x66,0xc0}, +{0x74,0x4e,0xbc,0x37}, {0xfc,0x82,0xca,0xa6}, {0xe0,0x90,0xd0,0xb0}, {0x33,0xa7,0xd8,0x15}, +{0xf1,0x04,0x98,0x4a}, {0x41,0xec,0xda,0xf7}, {0x7f,0xcd,0x50,0x0e}, {0x17,0x91,0xf6,0x2f}, +{0x76,0x4d,0xd6,0x8d}, {0x43,0xef,0xb0,0x4d}, {0xcc,0xaa,0x4d,0x54}, {0xe4,0x96,0x04,0xdf}, +{0x9e,0xd1,0xb5,0xe3}, {0x4c,0x6a,0x88,0x1b}, {0xc1,0x2c,0x1f,0xb8}, {0x46,0x65,0x51,0x7f}, +{0x9d,0x5e,0xea,0x04}, {0x01,0x8c,0x35,0x5d}, {0xfa,0x87,0x74,0x73}, {0xfb,0x0b,0x41,0x2e}, +{0xb3,0x67,0x1d,0x5a}, {0x92,0xdb,0xd2,0x52}, {0xe9,0x10,0x56,0x33}, {0x6d,0xd6,0x47,0x13}, +{0x9a,0xd7,0x61,0x8c}, {0x37,0xa1,0x0c,0x7a}, {0x59,0xf8,0x14,0x8e}, {0xeb,0x13,0x3c,0x89}, +{0xce,0xa9,0x27,0xee}, {0xb7,0x61,0xc9,0x35}, {0xe1,0x1c,0xe5,0xed}, {0x7a,0x47,0xb1,0x3c}, +{0x9c,0xd2,0xdf,0x59}, {0x55,0xf2,0x73,0x3f}, {0x18,0x14,0xce,0x79}, {0x73,0xc7,0x37,0xbf}, +{0x53,0xf7,0xcd,0xea}, {0x5f,0xfd,0xaa,0x5b}, {0xdf,0x3d,0x6f,0x14}, {0x78,0x44,0xdb,0x86}, +{0xca,0xaf,0xf3,0x81}, {0xb9,0x68,0xc4,0x3e}, {0x38,0x24,0x34,0x2c}, {0xc2,0xa3,0x40,0x5f}, +{0x16,0x1d,0xc3,0x72}, {0xbc,0xe2,0x25,0x0c}, {0x28,0x3c,0x49,0x8b}, {0xff,0x0d,0x95,0x41}, +{0x39,0xa8,0x01,0x71}, {0x08,0x0c,0xb3,0xde}, {0xd8,0xb4,0xe4,0x9c}, {0x64,0x56,0xc1,0x90}, +{0x7b,0xcb,0x84,0x61}, {0xd5,0x32,0xb6,0x70}, {0x48,0x6c,0x5c,0x74}, {0xd0,0xb8,0x57,0x42} + } +}; +#define T5 xT5.xt8 + +static const union xtab xT6 = { + .xt8 = { +{0x50,0x51,0xf4,0xa7}, {0x53,0x7e,0x41,0x65}, {0xc3,0x1a,0x17,0xa4}, {0x96,0x3a,0x27,0x5e}, +{0xcb,0x3b,0xab,0x6b}, {0xf1,0x1f,0x9d,0x45}, {0xab,0xac,0xfa,0x58}, {0x93,0x4b,0xe3,0x03}, +{0x55,0x20,0x30,0xfa}, {0xf6,0xad,0x76,0x6d}, {0x91,0x88,0xcc,0x76}, {0x25,0xf5,0x02,0x4c}, +{0xfc,0x4f,0xe5,0xd7}, {0xd7,0xc5,0x2a,0xcb}, {0x80,0x26,0x35,0x44}, {0x8f,0xb5,0x62,0xa3}, +{0x49,0xde,0xb1,0x5a}, {0x67,0x25,0xba,0x1b}, {0x98,0x45,0xea,0x0e}, {0xe1,0x5d,0xfe,0xc0}, +{0x02,0xc3,0x2f,0x75}, {0x12,0x81,0x4c,0xf0}, {0xa3,0x8d,0x46,0x97}, {0xc6,0x6b,0xd3,0xf9}, +{0xe7,0x03,0x8f,0x5f}, {0x95,0x15,0x92,0x9c}, {0xeb,0xbf,0x6d,0x7a}, {0xda,0x95,0x52,0x59}, +{0x2d,0xd4,0xbe,0x83}, {0xd3,0x58,0x74,0x21}, {0x29,0x49,0xe0,0x69}, {0x44,0x8e,0xc9,0xc8}, +{0x6a,0x75,0xc2,0x89}, {0x78,0xf4,0x8e,0x79}, {0x6b,0x99,0x58,0x3e}, {0xdd,0x27,0xb9,0x71}, +{0xb6,0xbe,0xe1,0x4f}, {0x17,0xf0,0x88,0xad}, {0x66,0xc9,0x20,0xac}, {0xb4,0x7d,0xce,0x3a}, +{0x18,0x63,0xdf,0x4a}, {0x82,0xe5,0x1a,0x31}, {0x60,0x97,0x51,0x33}, {0x45,0x62,0x53,0x7f}, +{0xe0,0xb1,0x64,0x77}, {0x84,0xbb,0x6b,0xae}, {0x1c,0xfe,0x81,0xa0}, {0x94,0xf9,0x08,0x2b}, +{0x58,0x70,0x48,0x68}, {0x19,0x8f,0x45,0xfd}, {0x87,0x94,0xde,0x6c}, {0xb7,0x52,0x7b,0xf8}, +{0x23,0xab,0x73,0xd3}, {0xe2,0x72,0x4b,0x02}, {0x57,0xe3,0x1f,0x8f}, {0x2a,0x66,0x55,0xab}, +{0x07,0xb2,0xeb,0x28}, {0x03,0x2f,0xb5,0xc2}, {0x9a,0x86,0xc5,0x7b}, {0xa5,0xd3,0x37,0x08}, +{0xf2,0x30,0x28,0x87}, {0xb2,0x23,0xbf,0xa5}, {0xba,0x02,0x03,0x6a}, {0x5c,0xed,0x16,0x82}, +{0x2b,0x8a,0xcf,0x1c}, {0x92,0xa7,0x79,0xb4}, {0xf0,0xf3,0x07,0xf2}, {0xa1,0x4e,0x69,0xe2}, +{0xcd,0x65,0xda,0xf4}, {0xd5,0x06,0x05,0xbe}, {0x1f,0xd1,0x34,0x62}, {0x8a,0xc4,0xa6,0xfe}, +{0x9d,0x34,0x2e,0x53}, {0xa0,0xa2,0xf3,0x55}, {0x32,0x05,0x8a,0xe1}, {0x75,0xa4,0xf6,0xeb}, +{0x39,0x0b,0x83,0xec}, {0xaa,0x40,0x60,0xef}, {0x06,0x5e,0x71,0x9f}, {0x51,0xbd,0x6e,0x10}, +{0xf9,0x3e,0x21,0x8a}, {0x3d,0x96,0xdd,0x06}, {0xae,0xdd,0x3e,0x05}, {0x46,0x4d,0xe6,0xbd}, +{0xb5,0x91,0x54,0x8d}, {0x05,0x71,0xc4,0x5d}, {0x6f,0x04,0x06,0xd4}, {0xff,0x60,0x50,0x15}, +{0x24,0x19,0x98,0xfb}, {0x97,0xd6,0xbd,0xe9}, {0xcc,0x89,0x40,0x43}, {0x77,0x67,0xd9,0x9e}, +{0xbd,0xb0,0xe8,0x42}, {0x88,0x07,0x89,0x8b}, {0x38,0xe7,0x19,0x5b}, {0xdb,0x79,0xc8,0xee}, +{0x47,0xa1,0x7c,0x0a}, {0xe9,0x7c,0x42,0x0f}, {0xc9,0xf8,0x84,0x1e}, {0x00,0x00,0x00,0x00}, +{0x83,0x09,0x80,0x86}, {0x48,0x32,0x2b,0xed}, {0xac,0x1e,0x11,0x70}, {0x4e,0x6c,0x5a,0x72}, +{0xfb,0xfd,0x0e,0xff}, {0x56,0x0f,0x85,0x38}, {0x1e,0x3d,0xae,0xd5}, {0x27,0x36,0x2d,0x39}, +{0x64,0x0a,0x0f,0xd9}, {0x21,0x68,0x5c,0xa6}, {0xd1,0x9b,0x5b,0x54}, {0x3a,0x24,0x36,0x2e}, +{0xb1,0x0c,0x0a,0x67}, {0x0f,0x93,0x57,0xe7}, {0xd2,0xb4,0xee,0x96}, {0x9e,0x1b,0x9b,0x91}, +{0x4f,0x80,0xc0,0xc5}, {0xa2,0x61,0xdc,0x20}, {0x69,0x5a,0x77,0x4b}, {0x16,0x1c,0x12,0x1a}, +{0x0a,0xe2,0x93,0xba}, {0xe5,0xc0,0xa0,0x2a}, {0x43,0x3c,0x22,0xe0}, {0x1d,0x12,0x1b,0x17}, +{0x0b,0x0e,0x09,0x0d}, {0xad,0xf2,0x8b,0xc7}, {0xb9,0x2d,0xb6,0xa8}, {0xc8,0x14,0x1e,0xa9}, +{0x85,0x57,0xf1,0x19}, {0x4c,0xaf,0x75,0x07}, {0xbb,0xee,0x99,0xdd}, {0xfd,0xa3,0x7f,0x60}, +{0x9f,0xf7,0x01,0x26}, {0xbc,0x5c,0x72,0xf5}, {0xc5,0x44,0x66,0x3b}, {0x34,0x5b,0xfb,0x7e}, +{0x76,0x8b,0x43,0x29}, {0xdc,0xcb,0x23,0xc6}, {0x68,0xb6,0xed,0xfc}, {0x63,0xb8,0xe4,0xf1}, +{0xca,0xd7,0x31,0xdc}, {0x10,0x42,0x63,0x85}, {0x40,0x13,0x97,0x22}, {0x20,0x84,0xc6,0x11}, +{0x7d,0x85,0x4a,0x24}, {0xf8,0xd2,0xbb,0x3d}, {0x11,0xae,0xf9,0x32}, {0x6d,0xc7,0x29,0xa1}, +{0x4b,0x1d,0x9e,0x2f}, {0xf3,0xdc,0xb2,0x30}, {0xec,0x0d,0x86,0x52}, {0xd0,0x77,0xc1,0xe3}, +{0x6c,0x2b,0xb3,0x16}, {0x99,0xa9,0x70,0xb9}, {0xfa,0x11,0x94,0x48}, {0x22,0x47,0xe9,0x64}, +{0xc4,0xa8,0xfc,0x8c}, {0x1a,0xa0,0xf0,0x3f}, {0xd8,0x56,0x7d,0x2c}, {0xef,0x22,0x33,0x90}, +{0xc7,0x87,0x49,0x4e}, {0xc1,0xd9,0x38,0xd1}, {0xfe,0x8c,0xca,0xa2}, {0x36,0x98,0xd4,0x0b}, +{0xcf,0xa6,0xf5,0x81}, {0x28,0xa5,0x7a,0xde}, {0x26,0xda,0xb7,0x8e}, {0xa4,0x3f,0xad,0xbf}, +{0xe4,0x2c,0x3a,0x9d}, {0x0d,0x50,0x78,0x92}, {0x9b,0x6a,0x5f,0xcc}, {0x62,0x54,0x7e,0x46}, +{0xc2,0xf6,0x8d,0x13}, {0xe8,0x90,0xd8,0xb8}, {0x5e,0x2e,0x39,0xf7}, {0xf5,0x82,0xc3,0xaf}, +{0xbe,0x9f,0x5d,0x80}, {0x7c,0x69,0xd0,0x93}, {0xa9,0x6f,0xd5,0x2d}, {0xb3,0xcf,0x25,0x12}, +{0x3b,0xc8,0xac,0x99}, {0xa7,0x10,0x18,0x7d}, {0x6e,0xe8,0x9c,0x63}, {0x7b,0xdb,0x3b,0xbb}, +{0x09,0xcd,0x26,0x78}, {0xf4,0x6e,0x59,0x18}, {0x01,0xec,0x9a,0xb7}, {0xa8,0x83,0x4f,0x9a}, +{0x65,0xe6,0x95,0x6e}, {0x7e,0xaa,0xff,0xe6}, {0x08,0x21,0xbc,0xcf}, {0xe6,0xef,0x15,0xe8}, +{0xd9,0xba,0xe7,0x9b}, {0xce,0x4a,0x6f,0x36}, {0xd4,0xea,0x9f,0x09}, {0xd6,0x29,0xb0,0x7c}, +{0xaf,0x31,0xa4,0xb2}, {0x31,0x2a,0x3f,0x23}, {0x30,0xc6,0xa5,0x94}, {0xc0,0x35,0xa2,0x66}, +{0x37,0x74,0x4e,0xbc}, {0xa6,0xfc,0x82,0xca}, {0xb0,0xe0,0x90,0xd0}, {0x15,0x33,0xa7,0xd8}, +{0x4a,0xf1,0x04,0x98}, {0xf7,0x41,0xec,0xda}, {0x0e,0x7f,0xcd,0x50}, {0x2f,0x17,0x91,0xf6}, +{0x8d,0x76,0x4d,0xd6}, {0x4d,0x43,0xef,0xb0}, {0x54,0xcc,0xaa,0x4d}, {0xdf,0xe4,0x96,0x04}, +{0xe3,0x9e,0xd1,0xb5}, {0x1b,0x4c,0x6a,0x88}, {0xb8,0xc1,0x2c,0x1f}, {0x7f,0x46,0x65,0x51}, +{0x04,0x9d,0x5e,0xea}, {0x5d,0x01,0x8c,0x35}, {0x73,0xfa,0x87,0x74}, {0x2e,0xfb,0x0b,0x41}, +{0x5a,0xb3,0x67,0x1d}, {0x52,0x92,0xdb,0xd2}, {0x33,0xe9,0x10,0x56}, {0x13,0x6d,0xd6,0x47}, +{0x8c,0x9a,0xd7,0x61}, {0x7a,0x37,0xa1,0x0c}, {0x8e,0x59,0xf8,0x14}, {0x89,0xeb,0x13,0x3c}, +{0xee,0xce,0xa9,0x27}, {0x35,0xb7,0x61,0xc9}, {0xed,0xe1,0x1c,0xe5}, {0x3c,0x7a,0x47,0xb1}, +{0x59,0x9c,0xd2,0xdf}, {0x3f,0x55,0xf2,0x73}, {0x79,0x18,0x14,0xce}, {0xbf,0x73,0xc7,0x37}, +{0xea,0x53,0xf7,0xcd}, {0x5b,0x5f,0xfd,0xaa}, {0x14,0xdf,0x3d,0x6f}, {0x86,0x78,0x44,0xdb}, +{0x81,0xca,0xaf,0xf3}, {0x3e,0xb9,0x68,0xc4}, {0x2c,0x38,0x24,0x34}, {0x5f,0xc2,0xa3,0x40}, +{0x72,0x16,0x1d,0xc3}, {0x0c,0xbc,0xe2,0x25}, {0x8b,0x28,0x3c,0x49}, {0x41,0xff,0x0d,0x95}, +{0x71,0x39,0xa8,0x01}, {0xde,0x08,0x0c,0xb3}, {0x9c,0xd8,0xb4,0xe4}, {0x90,0x64,0x56,0xc1}, +{0x61,0x7b,0xcb,0x84}, {0x70,0xd5,0x32,0xb6}, {0x74,0x48,0x6c,0x5c}, {0x42,0xd0,0xb8,0x57} + } +}; +#define T6 xT6.xt8 + +static const union xtab xT7 = { + .xt8 = { +{0xa7,0x50,0x51,0xf4}, {0x65,0x53,0x7e,0x41}, {0xa4,0xc3,0x1a,0x17}, {0x5e,0x96,0x3a,0x27}, +{0x6b,0xcb,0x3b,0xab}, {0x45,0xf1,0x1f,0x9d}, {0x58,0xab,0xac,0xfa}, {0x03,0x93,0x4b,0xe3}, +{0xfa,0x55,0x20,0x30}, {0x6d,0xf6,0xad,0x76}, {0x76,0x91,0x88,0xcc}, {0x4c,0x25,0xf5,0x02}, +{0xd7,0xfc,0x4f,0xe5}, {0xcb,0xd7,0xc5,0x2a}, {0x44,0x80,0x26,0x35}, {0xa3,0x8f,0xb5,0x62}, +{0x5a,0x49,0xde,0xb1}, {0x1b,0x67,0x25,0xba}, {0x0e,0x98,0x45,0xea}, {0xc0,0xe1,0x5d,0xfe}, +{0x75,0x02,0xc3,0x2f}, {0xf0,0x12,0x81,0x4c}, {0x97,0xa3,0x8d,0x46}, {0xf9,0xc6,0x6b,0xd3}, +{0x5f,0xe7,0x03,0x8f}, {0x9c,0x95,0x15,0x92}, {0x7a,0xeb,0xbf,0x6d}, {0x59,0xda,0x95,0x52}, +{0x83,0x2d,0xd4,0xbe}, {0x21,0xd3,0x58,0x74}, {0x69,0x29,0x49,0xe0}, {0xc8,0x44,0x8e,0xc9}, +{0x89,0x6a,0x75,0xc2}, {0x79,0x78,0xf4,0x8e}, {0x3e,0x6b,0x99,0x58}, {0x71,0xdd,0x27,0xb9}, +{0x4f,0xb6,0xbe,0xe1}, {0xad,0x17,0xf0,0x88}, {0xac,0x66,0xc9,0x20}, {0x3a,0xb4,0x7d,0xce}, +{0x4a,0x18,0x63,0xdf}, {0x31,0x82,0xe5,0x1a}, {0x33,0x60,0x97,0x51}, {0x7f,0x45,0x62,0x53}, +{0x77,0xe0,0xb1,0x64}, {0xae,0x84,0xbb,0x6b}, {0xa0,0x1c,0xfe,0x81}, {0x2b,0x94,0xf9,0x08}, +{0x68,0x58,0x70,0x48}, {0xfd,0x19,0x8f,0x45}, {0x6c,0x87,0x94,0xde}, {0xf8,0xb7,0x52,0x7b}, +{0xd3,0x23,0xab,0x73}, {0x02,0xe2,0x72,0x4b}, {0x8f,0x57,0xe3,0x1f}, {0xab,0x2a,0x66,0x55}, +{0x28,0x07,0xb2,0xeb}, {0xc2,0x03,0x2f,0xb5}, {0x7b,0x9a,0x86,0xc5}, {0x08,0xa5,0xd3,0x37}, +{0x87,0xf2,0x30,0x28}, {0xa5,0xb2,0x23,0xbf}, {0x6a,0xba,0x02,0x03}, {0x82,0x5c,0xed,0x16}, +{0x1c,0x2b,0x8a,0xcf}, {0xb4,0x92,0xa7,0x79}, {0xf2,0xf0,0xf3,0x07}, {0xe2,0xa1,0x4e,0x69}, +{0xf4,0xcd,0x65,0xda}, {0xbe,0xd5,0x06,0x05}, {0x62,0x1f,0xd1,0x34}, {0xfe,0x8a,0xc4,0xa6}, +{0x53,0x9d,0x34,0x2e}, {0x55,0xa0,0xa2,0xf3}, {0xe1,0x32,0x05,0x8a}, {0xeb,0x75,0xa4,0xf6}, +{0xec,0x39,0x0b,0x83}, {0xef,0xaa,0x40,0x60}, {0x9f,0x06,0x5e,0x71}, {0x10,0x51,0xbd,0x6e}, +{0x8a,0xf9,0x3e,0x21}, {0x06,0x3d,0x96,0xdd}, {0x05,0xae,0xdd,0x3e}, {0xbd,0x46,0x4d,0xe6}, +{0x8d,0xb5,0x91,0x54}, {0x5d,0x05,0x71,0xc4}, {0xd4,0x6f,0x04,0x06}, {0x15,0xff,0x60,0x50}, +{0xfb,0x24,0x19,0x98}, {0xe9,0x97,0xd6,0xbd}, {0x43,0xcc,0x89,0x40}, {0x9e,0x77,0x67,0xd9}, +{0x42,0xbd,0xb0,0xe8}, {0x8b,0x88,0x07,0x89}, {0x5b,0x38,0xe7,0x19}, {0xee,0xdb,0x79,0xc8}, +{0x0a,0x47,0xa1,0x7c}, {0x0f,0xe9,0x7c,0x42}, {0x1e,0xc9,0xf8,0x84}, {0x00,0x00,0x00,0x00}, +{0x86,0x83,0x09,0x80}, {0xed,0x48,0x32,0x2b}, {0x70,0xac,0x1e,0x11}, {0x72,0x4e,0x6c,0x5a}, +{0xff,0xfb,0xfd,0x0e}, {0x38,0x56,0x0f,0x85}, {0xd5,0x1e,0x3d,0xae}, {0x39,0x27,0x36,0x2d}, +{0xd9,0x64,0x0a,0x0f}, {0xa6,0x21,0x68,0x5c}, {0x54,0xd1,0x9b,0x5b}, {0x2e,0x3a,0x24,0x36}, +{0x67,0xb1,0x0c,0x0a}, {0xe7,0x0f,0x93,0x57}, {0x96,0xd2,0xb4,0xee}, {0x91,0x9e,0x1b,0x9b}, +{0xc5,0x4f,0x80,0xc0}, {0x20,0xa2,0x61,0xdc}, {0x4b,0x69,0x5a,0x77}, {0x1a,0x16,0x1c,0x12}, +{0xba,0x0a,0xe2,0x93}, {0x2a,0xe5,0xc0,0xa0}, {0xe0,0x43,0x3c,0x22}, {0x17,0x1d,0x12,0x1b}, +{0x0d,0x0b,0x0e,0x09}, {0xc7,0xad,0xf2,0x8b}, {0xa8,0xb9,0x2d,0xb6}, {0xa9,0xc8,0x14,0x1e}, +{0x19,0x85,0x57,0xf1}, {0x07,0x4c,0xaf,0x75}, {0xdd,0xbb,0xee,0x99}, {0x60,0xfd,0xa3,0x7f}, +{0x26,0x9f,0xf7,0x01}, {0xf5,0xbc,0x5c,0x72}, {0x3b,0xc5,0x44,0x66}, {0x7e,0x34,0x5b,0xfb}, +{0x29,0x76,0x8b,0x43}, {0xc6,0xdc,0xcb,0x23}, {0xfc,0x68,0xb6,0xed}, {0xf1,0x63,0xb8,0xe4}, +{0xdc,0xca,0xd7,0x31}, {0x85,0x10,0x42,0x63}, {0x22,0x40,0x13,0x97}, {0x11,0x20,0x84,0xc6}, +{0x24,0x7d,0x85,0x4a}, {0x3d,0xf8,0xd2,0xbb}, {0x32,0x11,0xae,0xf9}, {0xa1,0x6d,0xc7,0x29}, +{0x2f,0x4b,0x1d,0x9e}, {0x30,0xf3,0xdc,0xb2}, {0x52,0xec,0x0d,0x86}, {0xe3,0xd0,0x77,0xc1}, +{0x16,0x6c,0x2b,0xb3}, {0xb9,0x99,0xa9,0x70}, {0x48,0xfa,0x11,0x94}, {0x64,0x22,0x47,0xe9}, +{0x8c,0xc4,0xa8,0xfc}, {0x3f,0x1a,0xa0,0xf0}, {0x2c,0xd8,0x56,0x7d}, {0x90,0xef,0x22,0x33}, +{0x4e,0xc7,0x87,0x49}, {0xd1,0xc1,0xd9,0x38}, {0xa2,0xfe,0x8c,0xca}, {0x0b,0x36,0x98,0xd4}, +{0x81,0xcf,0xa6,0xf5}, {0xde,0x28,0xa5,0x7a}, {0x8e,0x26,0xda,0xb7}, {0xbf,0xa4,0x3f,0xad}, +{0x9d,0xe4,0x2c,0x3a}, {0x92,0x0d,0x50,0x78}, {0xcc,0x9b,0x6a,0x5f}, {0x46,0x62,0x54,0x7e}, +{0x13,0xc2,0xf6,0x8d}, {0xb8,0xe8,0x90,0xd8}, {0xf7,0x5e,0x2e,0x39}, {0xaf,0xf5,0x82,0xc3}, +{0x80,0xbe,0x9f,0x5d}, {0x93,0x7c,0x69,0xd0}, {0x2d,0xa9,0x6f,0xd5}, {0x12,0xb3,0xcf,0x25}, +{0x99,0x3b,0xc8,0xac}, {0x7d,0xa7,0x10,0x18}, {0x63,0x6e,0xe8,0x9c}, {0xbb,0x7b,0xdb,0x3b}, +{0x78,0x09,0xcd,0x26}, {0x18,0xf4,0x6e,0x59}, {0xb7,0x01,0xec,0x9a}, {0x9a,0xa8,0x83,0x4f}, +{0x6e,0x65,0xe6,0x95}, {0xe6,0x7e,0xaa,0xff}, {0xcf,0x08,0x21,0xbc}, {0xe8,0xe6,0xef,0x15}, +{0x9b,0xd9,0xba,0xe7}, {0x36,0xce,0x4a,0x6f}, {0x09,0xd4,0xea,0x9f}, {0x7c,0xd6,0x29,0xb0}, +{0xb2,0xaf,0x31,0xa4}, {0x23,0x31,0x2a,0x3f}, {0x94,0x30,0xc6,0xa5}, {0x66,0xc0,0x35,0xa2}, +{0xbc,0x37,0x74,0x4e}, {0xca,0xa6,0xfc,0x82}, {0xd0,0xb0,0xe0,0x90}, {0xd8,0x15,0x33,0xa7}, +{0x98,0x4a,0xf1,0x04}, {0xda,0xf7,0x41,0xec}, {0x50,0x0e,0x7f,0xcd}, {0xf6,0x2f,0x17,0x91}, +{0xd6,0x8d,0x76,0x4d}, {0xb0,0x4d,0x43,0xef}, {0x4d,0x54,0xcc,0xaa}, {0x04,0xdf,0xe4,0x96}, +{0xb5,0xe3,0x9e,0xd1}, {0x88,0x1b,0x4c,0x6a}, {0x1f,0xb8,0xc1,0x2c}, {0x51,0x7f,0x46,0x65}, +{0xea,0x04,0x9d,0x5e}, {0x35,0x5d,0x01,0x8c}, {0x74,0x73,0xfa,0x87}, {0x41,0x2e,0xfb,0x0b}, +{0x1d,0x5a,0xb3,0x67}, {0xd2,0x52,0x92,0xdb}, {0x56,0x33,0xe9,0x10}, {0x47,0x13,0x6d,0xd6}, +{0x61,0x8c,0x9a,0xd7}, {0x0c,0x7a,0x37,0xa1}, {0x14,0x8e,0x59,0xf8}, {0x3c,0x89,0xeb,0x13}, +{0x27,0xee,0xce,0xa9}, {0xc9,0x35,0xb7,0x61}, {0xe5,0xed,0xe1,0x1c}, {0xb1,0x3c,0x7a,0x47}, +{0xdf,0x59,0x9c,0xd2}, {0x73,0x3f,0x55,0xf2}, {0xce,0x79,0x18,0x14}, {0x37,0xbf,0x73,0xc7}, +{0xcd,0xea,0x53,0xf7}, {0xaa,0x5b,0x5f,0xfd}, {0x6f,0x14,0xdf,0x3d}, {0xdb,0x86,0x78,0x44}, +{0xf3,0x81,0xca,0xaf}, {0xc4,0x3e,0xb9,0x68}, {0x34,0x2c,0x38,0x24}, {0x40,0x5f,0xc2,0xa3}, +{0xc3,0x72,0x16,0x1d}, {0x25,0x0c,0xbc,0xe2}, {0x49,0x8b,0x28,0x3c}, {0x95,0x41,0xff,0x0d}, +{0x01,0x71,0x39,0xa8}, {0xb3,0xde,0x08,0x0c}, {0xe4,0x9c,0xd8,0xb4}, {0xc1,0x90,0x64,0x56}, +{0x84,0x61,0x7b,0xcb}, {0xb6,0x70,0xd5,0x32}, {0x5c,0x74,0x48,0x6c}, {0x57,0x42,0xd0,0xb8} + } +}; +#define T7 xT7.xt8 + +static const union xtab xT8 = { + .xt8 = { +{0xf4,0xa7,0x50,0x51}, {0x41,0x65,0x53,0x7e}, {0x17,0xa4,0xc3,0x1a}, {0x27,0x5e,0x96,0x3a}, +{0xab,0x6b,0xcb,0x3b}, {0x9d,0x45,0xf1,0x1f}, {0xfa,0x58,0xab,0xac}, {0xe3,0x03,0x93,0x4b}, +{0x30,0xfa,0x55,0x20}, {0x76,0x6d,0xf6,0xad}, {0xcc,0x76,0x91,0x88}, {0x02,0x4c,0x25,0xf5}, +{0xe5,0xd7,0xfc,0x4f}, {0x2a,0xcb,0xd7,0xc5}, {0x35,0x44,0x80,0x26}, {0x62,0xa3,0x8f,0xb5}, +{0xb1,0x5a,0x49,0xde}, {0xba,0x1b,0x67,0x25}, {0xea,0x0e,0x98,0x45}, {0xfe,0xc0,0xe1,0x5d}, +{0x2f,0x75,0x02,0xc3}, {0x4c,0xf0,0x12,0x81}, {0x46,0x97,0xa3,0x8d}, {0xd3,0xf9,0xc6,0x6b}, +{0x8f,0x5f,0xe7,0x03}, {0x92,0x9c,0x95,0x15}, {0x6d,0x7a,0xeb,0xbf}, {0x52,0x59,0xda,0x95}, +{0xbe,0x83,0x2d,0xd4}, {0x74,0x21,0xd3,0x58}, {0xe0,0x69,0x29,0x49}, {0xc9,0xc8,0x44,0x8e}, +{0xc2,0x89,0x6a,0x75}, {0x8e,0x79,0x78,0xf4}, {0x58,0x3e,0x6b,0x99}, {0xb9,0x71,0xdd,0x27}, +{0xe1,0x4f,0xb6,0xbe}, {0x88,0xad,0x17,0xf0}, {0x20,0xac,0x66,0xc9}, {0xce,0x3a,0xb4,0x7d}, +{0xdf,0x4a,0x18,0x63}, {0x1a,0x31,0x82,0xe5}, {0x51,0x33,0x60,0x97}, {0x53,0x7f,0x45,0x62}, +{0x64,0x77,0xe0,0xb1}, {0x6b,0xae,0x84,0xbb}, {0x81,0xa0,0x1c,0xfe}, {0x08,0x2b,0x94,0xf9}, +{0x48,0x68,0x58,0x70}, {0x45,0xfd,0x19,0x8f}, {0xde,0x6c,0x87,0x94}, {0x7b,0xf8,0xb7,0x52}, +{0x73,0xd3,0x23,0xab}, {0x4b,0x02,0xe2,0x72}, {0x1f,0x8f,0x57,0xe3}, {0x55,0xab,0x2a,0x66}, +{0xeb,0x28,0x07,0xb2}, {0xb5,0xc2,0x03,0x2f}, {0xc5,0x7b,0x9a,0x86}, {0x37,0x08,0xa5,0xd3}, +{0x28,0x87,0xf2,0x30}, {0xbf,0xa5,0xb2,0x23}, {0x03,0x6a,0xba,0x02}, {0x16,0x82,0x5c,0xed}, +{0xcf,0x1c,0x2b,0x8a}, {0x79,0xb4,0x92,0xa7}, {0x07,0xf2,0xf0,0xf3}, {0x69,0xe2,0xa1,0x4e}, +{0xda,0xf4,0xcd,0x65}, {0x05,0xbe,0xd5,0x06}, {0x34,0x62,0x1f,0xd1}, {0xa6,0xfe,0x8a,0xc4}, +{0x2e,0x53,0x9d,0x34}, {0xf3,0x55,0xa0,0xa2}, {0x8a,0xe1,0x32,0x05}, {0xf6,0xeb,0x75,0xa4}, +{0x83,0xec,0x39,0x0b}, {0x60,0xef,0xaa,0x40}, {0x71,0x9f,0x06,0x5e}, {0x6e,0x10,0x51,0xbd}, +{0x21,0x8a,0xf9,0x3e}, {0xdd,0x06,0x3d,0x96}, {0x3e,0x05,0xae,0xdd}, {0xe6,0xbd,0x46,0x4d}, +{0x54,0x8d,0xb5,0x91}, {0xc4,0x5d,0x05,0x71}, {0x06,0xd4,0x6f,0x04}, {0x50,0x15,0xff,0x60}, +{0x98,0xfb,0x24,0x19}, {0xbd,0xe9,0x97,0xd6}, {0x40,0x43,0xcc,0x89}, {0xd9,0x9e,0x77,0x67}, +{0xe8,0x42,0xbd,0xb0}, {0x89,0x8b,0x88,0x07}, {0x19,0x5b,0x38,0xe7}, {0xc8,0xee,0xdb,0x79}, +{0x7c,0x0a,0x47,0xa1}, {0x42,0x0f,0xe9,0x7c}, {0x84,0x1e,0xc9,0xf8}, {0x00,0x00,0x00,0x00}, +{0x80,0x86,0x83,0x09}, {0x2b,0xed,0x48,0x32}, {0x11,0x70,0xac,0x1e}, {0x5a,0x72,0x4e,0x6c}, +{0x0e,0xff,0xfb,0xfd}, {0x85,0x38,0x56,0x0f}, {0xae,0xd5,0x1e,0x3d}, {0x2d,0x39,0x27,0x36}, +{0x0f,0xd9,0x64,0x0a}, {0x5c,0xa6,0x21,0x68}, {0x5b,0x54,0xd1,0x9b}, {0x36,0x2e,0x3a,0x24}, +{0x0a,0x67,0xb1,0x0c}, {0x57,0xe7,0x0f,0x93}, {0xee,0x96,0xd2,0xb4}, {0x9b,0x91,0x9e,0x1b}, +{0xc0,0xc5,0x4f,0x80}, {0xdc,0x20,0xa2,0x61}, {0x77,0x4b,0x69,0x5a}, {0x12,0x1a,0x16,0x1c}, +{0x93,0xba,0x0a,0xe2}, {0xa0,0x2a,0xe5,0xc0}, {0x22,0xe0,0x43,0x3c}, {0x1b,0x17,0x1d,0x12}, +{0x09,0x0d,0x0b,0x0e}, {0x8b,0xc7,0xad,0xf2}, {0xb6,0xa8,0xb9,0x2d}, {0x1e,0xa9,0xc8,0x14}, +{0xf1,0x19,0x85,0x57}, {0x75,0x07,0x4c,0xaf}, {0x99,0xdd,0xbb,0xee}, {0x7f,0x60,0xfd,0xa3}, +{0x01,0x26,0x9f,0xf7}, {0x72,0xf5,0xbc,0x5c}, {0x66,0x3b,0xc5,0x44}, {0xfb,0x7e,0x34,0x5b}, +{0x43,0x29,0x76,0x8b}, {0x23,0xc6,0xdc,0xcb}, {0xed,0xfc,0x68,0xb6}, {0xe4,0xf1,0x63,0xb8}, +{0x31,0xdc,0xca,0xd7}, {0x63,0x85,0x10,0x42}, {0x97,0x22,0x40,0x13}, {0xc6,0x11,0x20,0x84}, +{0x4a,0x24,0x7d,0x85}, {0xbb,0x3d,0xf8,0xd2}, {0xf9,0x32,0x11,0xae}, {0x29,0xa1,0x6d,0xc7}, +{0x9e,0x2f,0x4b,0x1d}, {0xb2,0x30,0xf3,0xdc}, {0x86,0x52,0xec,0x0d}, {0xc1,0xe3,0xd0,0x77}, +{0xb3,0x16,0x6c,0x2b}, {0x70,0xb9,0x99,0xa9}, {0x94,0x48,0xfa,0x11}, {0xe9,0x64,0x22,0x47}, +{0xfc,0x8c,0xc4,0xa8}, {0xf0,0x3f,0x1a,0xa0}, {0x7d,0x2c,0xd8,0x56}, {0x33,0x90,0xef,0x22}, +{0x49,0x4e,0xc7,0x87}, {0x38,0xd1,0xc1,0xd9}, {0xca,0xa2,0xfe,0x8c}, {0xd4,0x0b,0x36,0x98}, +{0xf5,0x81,0xcf,0xa6}, {0x7a,0xde,0x28,0xa5}, {0xb7,0x8e,0x26,0xda}, {0xad,0xbf,0xa4,0x3f}, +{0x3a,0x9d,0xe4,0x2c}, {0x78,0x92,0x0d,0x50}, {0x5f,0xcc,0x9b,0x6a}, {0x7e,0x46,0x62,0x54}, +{0x8d,0x13,0xc2,0xf6}, {0xd8,0xb8,0xe8,0x90}, {0x39,0xf7,0x5e,0x2e}, {0xc3,0xaf,0xf5,0x82}, +{0x5d,0x80,0xbe,0x9f}, {0xd0,0x93,0x7c,0x69}, {0xd5,0x2d,0xa9,0x6f}, {0x25,0x12,0xb3,0xcf}, +{0xac,0x99,0x3b,0xc8}, {0x18,0x7d,0xa7,0x10}, {0x9c,0x63,0x6e,0xe8}, {0x3b,0xbb,0x7b,0xdb}, +{0x26,0x78,0x09,0xcd}, {0x59,0x18,0xf4,0x6e}, {0x9a,0xb7,0x01,0xec}, {0x4f,0x9a,0xa8,0x83}, +{0x95,0x6e,0x65,0xe6}, {0xff,0xe6,0x7e,0xaa}, {0xbc,0xcf,0x08,0x21}, {0x15,0xe8,0xe6,0xef}, +{0xe7,0x9b,0xd9,0xba}, {0x6f,0x36,0xce,0x4a}, {0x9f,0x09,0xd4,0xea}, {0xb0,0x7c,0xd6,0x29}, +{0xa4,0xb2,0xaf,0x31}, {0x3f,0x23,0x31,0x2a}, {0xa5,0x94,0x30,0xc6}, {0xa2,0x66,0xc0,0x35}, +{0x4e,0xbc,0x37,0x74}, {0x82,0xca,0xa6,0xfc}, {0x90,0xd0,0xb0,0xe0}, {0xa7,0xd8,0x15,0x33}, +{0x04,0x98,0x4a,0xf1}, {0xec,0xda,0xf7,0x41}, {0xcd,0x50,0x0e,0x7f}, {0x91,0xf6,0x2f,0x17}, +{0x4d,0xd6,0x8d,0x76}, {0xef,0xb0,0x4d,0x43}, {0xaa,0x4d,0x54,0xcc}, {0x96,0x04,0xdf,0xe4}, +{0xd1,0xb5,0xe3,0x9e}, {0x6a,0x88,0x1b,0x4c}, {0x2c,0x1f,0xb8,0xc1}, {0x65,0x51,0x7f,0x46}, +{0x5e,0xea,0x04,0x9d}, {0x8c,0x35,0x5d,0x01}, {0x87,0x74,0x73,0xfa}, {0x0b,0x41,0x2e,0xfb}, +{0x67,0x1d,0x5a,0xb3}, {0xdb,0xd2,0x52,0x92}, {0x10,0x56,0x33,0xe9}, {0xd6,0x47,0x13,0x6d}, +{0xd7,0x61,0x8c,0x9a}, {0xa1,0x0c,0x7a,0x37}, {0xf8,0x14,0x8e,0x59}, {0x13,0x3c,0x89,0xeb}, +{0xa9,0x27,0xee,0xce}, {0x61,0xc9,0x35,0xb7}, {0x1c,0xe5,0xed,0xe1}, {0x47,0xb1,0x3c,0x7a}, +{0xd2,0xdf,0x59,0x9c}, {0xf2,0x73,0x3f,0x55}, {0x14,0xce,0x79,0x18}, {0xc7,0x37,0xbf,0x73}, +{0xf7,0xcd,0xea,0x53}, {0xfd,0xaa,0x5b,0x5f}, {0x3d,0x6f,0x14,0xdf}, {0x44,0xdb,0x86,0x78}, +{0xaf,0xf3,0x81,0xca}, {0x68,0xc4,0x3e,0xb9}, {0x24,0x34,0x2c,0x38}, {0xa3,0x40,0x5f,0xc2}, +{0x1d,0xc3,0x72,0x16}, {0xe2,0x25,0x0c,0xbc}, {0x3c,0x49,0x8b,0x28}, {0x0d,0x95,0x41,0xff}, +{0xa8,0x01,0x71,0x39}, {0x0c,0xb3,0xde,0x08}, {0xb4,0xe4,0x9c,0xd8}, {0x56,0xc1,0x90,0x64}, +{0xcb,0x84,0x61,0x7b}, {0x32,0xb6,0x70,0xd5}, {0x6c,0x5c,0x74,0x48}, {0xb8,0x57,0x42,0xd0} + } +}; +#define T8 xT8.xt8 + +static const word8 S5[256] = { +0x52,0x09,0x6a,0xd5, +0x30,0x36,0xa5,0x38, +0xbf,0x40,0xa3,0x9e, +0x81,0xf3,0xd7,0xfb, +0x7c,0xe3,0x39,0x82, +0x9b,0x2f,0xff,0x87, +0x34,0x8e,0x43,0x44, +0xc4,0xde,0xe9,0xcb, +0x54,0x7b,0x94,0x32, +0xa6,0xc2,0x23,0x3d, +0xee,0x4c,0x95,0x0b, +0x42,0xfa,0xc3,0x4e, +0x08,0x2e,0xa1,0x66, +0x28,0xd9,0x24,0xb2, +0x76,0x5b,0xa2,0x49, +0x6d,0x8b,0xd1,0x25, +0x72,0xf8,0xf6,0x64, +0x86,0x68,0x98,0x16, +0xd4,0xa4,0x5c,0xcc, +0x5d,0x65,0xb6,0x92, +0x6c,0x70,0x48,0x50, +0xfd,0xed,0xb9,0xda, +0x5e,0x15,0x46,0x57, +0xa7,0x8d,0x9d,0x84, +0x90,0xd8,0xab,0x00, +0x8c,0xbc,0xd3,0x0a, +0xf7,0xe4,0x58,0x05, +0xb8,0xb3,0x45,0x06, +0xd0,0x2c,0x1e,0x8f, +0xca,0x3f,0x0f,0x02, +0xc1,0xaf,0xbd,0x03, +0x01,0x13,0x8a,0x6b, +0x3a,0x91,0x11,0x41, +0x4f,0x67,0xdc,0xea, +0x97,0xf2,0xcf,0xce, +0xf0,0xb4,0xe6,0x73, +0x96,0xac,0x74,0x22, +0xe7,0xad,0x35,0x85, +0xe2,0xf9,0x37,0xe8, +0x1c,0x75,0xdf,0x6e, +0x47,0xf1,0x1a,0x71, +0x1d,0x29,0xc5,0x89, +0x6f,0xb7,0x62,0x0e, +0xaa,0x18,0xbe,0x1b, +0xfc,0x56,0x3e,0x4b, +0xc6,0xd2,0x79,0x20, +0x9a,0xdb,0xc0,0xfe, +0x78,0xcd,0x5a,0xf4, +0x1f,0xdd,0xa8,0x33, +0x88,0x07,0xc7,0x31, +0xb1,0x12,0x10,0x59, +0x27,0x80,0xec,0x5f, +0x60,0x51,0x7f,0xa9, +0x19,0xb5,0x4a,0x0d, +0x2d,0xe5,0x7a,0x9f, +0x93,0xc9,0x9c,0xef, +0xa0,0xe0,0x3b,0x4d, +0xae,0x2a,0xf5,0xb0, +0xc8,0xeb,0xbb,0x3c, +0x83,0x53,0x99,0x61, +0x17,0x2b,0x04,0x7e, +0xba,0x77,0xd6,0x26, +0xe1,0x69,0x14,0x63, +0x55,0x21,0x0c,0x7d +}; + +static const union xtab xU1 = { + .xt8 = { +{0x00,0x00,0x00,0x00}, {0x0e,0x09,0x0d,0x0b}, {0x1c,0x12,0x1a,0x16}, {0x12,0x1b,0x17,0x1d}, +{0x38,0x24,0x34,0x2c}, {0x36,0x2d,0x39,0x27}, {0x24,0x36,0x2e,0x3a}, {0x2a,0x3f,0x23,0x31}, +{0x70,0x48,0x68,0x58}, {0x7e,0x41,0x65,0x53}, {0x6c,0x5a,0x72,0x4e}, {0x62,0x53,0x7f,0x45}, +{0x48,0x6c,0x5c,0x74}, {0x46,0x65,0x51,0x7f}, {0x54,0x7e,0x46,0x62}, {0x5a,0x77,0x4b,0x69}, +{0xe0,0x90,0xd0,0xb0}, {0xee,0x99,0xdd,0xbb}, {0xfc,0x82,0xca,0xa6}, {0xf2,0x8b,0xc7,0xad}, +{0xd8,0xb4,0xe4,0x9c}, {0xd6,0xbd,0xe9,0x97}, {0xc4,0xa6,0xfe,0x8a}, {0xca,0xaf,0xf3,0x81}, +{0x90,0xd8,0xb8,0xe8}, {0x9e,0xd1,0xb5,0xe3}, {0x8c,0xca,0xa2,0xfe}, {0x82,0xc3,0xaf,0xf5}, +{0xa8,0xfc,0x8c,0xc4}, {0xa6,0xf5,0x81,0xcf}, {0xb4,0xee,0x96,0xd2}, {0xba,0xe7,0x9b,0xd9}, +{0xdb,0x3b,0xbb,0x7b}, {0xd5,0x32,0xb6,0x70}, {0xc7,0x29,0xa1,0x6d}, {0xc9,0x20,0xac,0x66}, +{0xe3,0x1f,0x8f,0x57}, {0xed,0x16,0x82,0x5c}, {0xff,0x0d,0x95,0x41}, {0xf1,0x04,0x98,0x4a}, +{0xab,0x73,0xd3,0x23}, {0xa5,0x7a,0xde,0x28}, {0xb7,0x61,0xc9,0x35}, {0xb9,0x68,0xc4,0x3e}, +{0x93,0x57,0xe7,0x0f}, {0x9d,0x5e,0xea,0x04}, {0x8f,0x45,0xfd,0x19}, {0x81,0x4c,0xf0,0x12}, +{0x3b,0xab,0x6b,0xcb}, {0x35,0xa2,0x66,0xc0}, {0x27,0xb9,0x71,0xdd}, {0x29,0xb0,0x7c,0xd6}, +{0x03,0x8f,0x5f,0xe7}, {0x0d,0x86,0x52,0xec}, {0x1f,0x9d,0x45,0xf1}, {0x11,0x94,0x48,0xfa}, +{0x4b,0xe3,0x03,0x93}, {0x45,0xea,0x0e,0x98}, {0x57,0xf1,0x19,0x85}, {0x59,0xf8,0x14,0x8e}, +{0x73,0xc7,0x37,0xbf}, {0x7d,0xce,0x3a,0xb4}, {0x6f,0xd5,0x2d,0xa9}, {0x61,0xdc,0x20,0xa2}, +{0xad,0x76,0x6d,0xf6}, {0xa3,0x7f,0x60,0xfd}, {0xb1,0x64,0x77,0xe0}, {0xbf,0x6d,0x7a,0xeb}, +{0x95,0x52,0x59,0xda}, {0x9b,0x5b,0x54,0xd1}, {0x89,0x40,0x43,0xcc}, {0x87,0x49,0x4e,0xc7}, +{0xdd,0x3e,0x05,0xae}, {0xd3,0x37,0x08,0xa5}, {0xc1,0x2c,0x1f,0xb8}, {0xcf,0x25,0x12,0xb3}, +{0xe5,0x1a,0x31,0x82}, {0xeb,0x13,0x3c,0x89}, {0xf9,0x08,0x2b,0x94}, {0xf7,0x01,0x26,0x9f}, +{0x4d,0xe6,0xbd,0x46}, {0x43,0xef,0xb0,0x4d}, {0x51,0xf4,0xa7,0x50}, {0x5f,0xfd,0xaa,0x5b}, +{0x75,0xc2,0x89,0x6a}, {0x7b,0xcb,0x84,0x61}, {0x69,0xd0,0x93,0x7c}, {0x67,0xd9,0x9e,0x77}, +{0x3d,0xae,0xd5,0x1e}, {0x33,0xa7,0xd8,0x15}, {0x21,0xbc,0xcf,0x08}, {0x2f,0xb5,0xc2,0x03}, +{0x05,0x8a,0xe1,0x32}, {0x0b,0x83,0xec,0x39}, {0x19,0x98,0xfb,0x24}, {0x17,0x91,0xf6,0x2f}, +{0x76,0x4d,0xd6,0x8d}, {0x78,0x44,0xdb,0x86}, {0x6a,0x5f,0xcc,0x9b}, {0x64,0x56,0xc1,0x90}, +{0x4e,0x69,0xe2,0xa1}, {0x40,0x60,0xef,0xaa}, {0x52,0x7b,0xf8,0xb7}, {0x5c,0x72,0xf5,0xbc}, +{0x06,0x05,0xbe,0xd5}, {0x08,0x0c,0xb3,0xde}, {0x1a,0x17,0xa4,0xc3}, {0x14,0x1e,0xa9,0xc8}, +{0x3e,0x21,0x8a,0xf9}, {0x30,0x28,0x87,0xf2}, {0x22,0x33,0x90,0xef}, {0x2c,0x3a,0x9d,0xe4}, +{0x96,0xdd,0x06,0x3d}, {0x98,0xd4,0x0b,0x36}, {0x8a,0xcf,0x1c,0x2b}, {0x84,0xc6,0x11,0x20}, +{0xae,0xf9,0x32,0x11}, {0xa0,0xf0,0x3f,0x1a}, {0xb2,0xeb,0x28,0x07}, {0xbc,0xe2,0x25,0x0c}, +{0xe6,0x95,0x6e,0x65}, {0xe8,0x9c,0x63,0x6e}, {0xfa,0x87,0x74,0x73}, {0xf4,0x8e,0x79,0x78}, +{0xde,0xb1,0x5a,0x49}, {0xd0,0xb8,0x57,0x42}, {0xc2,0xa3,0x40,0x5f}, {0xcc,0xaa,0x4d,0x54}, +{0x41,0xec,0xda,0xf7}, {0x4f,0xe5,0xd7,0xfc}, {0x5d,0xfe,0xc0,0xe1}, {0x53,0xf7,0xcd,0xea}, +{0x79,0xc8,0xee,0xdb}, {0x77,0xc1,0xe3,0xd0}, {0x65,0xda,0xf4,0xcd}, {0x6b,0xd3,0xf9,0xc6}, +{0x31,0xa4,0xb2,0xaf}, {0x3f,0xad,0xbf,0xa4}, {0x2d,0xb6,0xa8,0xb9}, {0x23,0xbf,0xa5,0xb2}, +{0x09,0x80,0x86,0x83}, {0x07,0x89,0x8b,0x88}, {0x15,0x92,0x9c,0x95}, {0x1b,0x9b,0x91,0x9e}, +{0xa1,0x7c,0x0a,0x47}, {0xaf,0x75,0x07,0x4c}, {0xbd,0x6e,0x10,0x51}, {0xb3,0x67,0x1d,0x5a}, +{0x99,0x58,0x3e,0x6b}, {0x97,0x51,0x33,0x60}, {0x85,0x4a,0x24,0x7d}, {0x8b,0x43,0x29,0x76}, +{0xd1,0x34,0x62,0x1f}, {0xdf,0x3d,0x6f,0x14}, {0xcd,0x26,0x78,0x09}, {0xc3,0x2f,0x75,0x02}, +{0xe9,0x10,0x56,0x33}, {0xe7,0x19,0x5b,0x38}, {0xf5,0x02,0x4c,0x25}, {0xfb,0x0b,0x41,0x2e}, +{0x9a,0xd7,0x61,0x8c}, {0x94,0xde,0x6c,0x87}, {0x86,0xc5,0x7b,0x9a}, {0x88,0xcc,0x76,0x91}, +{0xa2,0xf3,0x55,0xa0}, {0xac,0xfa,0x58,0xab}, {0xbe,0xe1,0x4f,0xb6}, {0xb0,0xe8,0x42,0xbd}, +{0xea,0x9f,0x09,0xd4}, {0xe4,0x96,0x04,0xdf}, {0xf6,0x8d,0x13,0xc2}, {0xf8,0x84,0x1e,0xc9}, +{0xd2,0xbb,0x3d,0xf8}, {0xdc,0xb2,0x30,0xf3}, {0xce,0xa9,0x27,0xee}, {0xc0,0xa0,0x2a,0xe5}, +{0x7a,0x47,0xb1,0x3c}, {0x74,0x4e,0xbc,0x37}, {0x66,0x55,0xab,0x2a}, {0x68,0x5c,0xa6,0x21}, +{0x42,0x63,0x85,0x10}, {0x4c,0x6a,0x88,0x1b}, {0x5e,0x71,0x9f,0x06}, {0x50,0x78,0x92,0x0d}, +{0x0a,0x0f,0xd9,0x64}, {0x04,0x06,0xd4,0x6f}, {0x16,0x1d,0xc3,0x72}, {0x18,0x14,0xce,0x79}, +{0x32,0x2b,0xed,0x48}, {0x3c,0x22,0xe0,0x43}, {0x2e,0x39,0xf7,0x5e}, {0x20,0x30,0xfa,0x55}, +{0xec,0x9a,0xb7,0x01}, {0xe2,0x93,0xba,0x0a}, {0xf0,0x88,0xad,0x17}, {0xfe,0x81,0xa0,0x1c}, +{0xd4,0xbe,0x83,0x2d}, {0xda,0xb7,0x8e,0x26}, {0xc8,0xac,0x99,0x3b}, {0xc6,0xa5,0x94,0x30}, +{0x9c,0xd2,0xdf,0x59}, {0x92,0xdb,0xd2,0x52}, {0x80,0xc0,0xc5,0x4f}, {0x8e,0xc9,0xc8,0x44}, +{0xa4,0xf6,0xeb,0x75}, {0xaa,0xff,0xe6,0x7e}, {0xb8,0xe4,0xf1,0x63}, {0xb6,0xed,0xfc,0x68}, +{0x0c,0x0a,0x67,0xb1}, {0x02,0x03,0x6a,0xba}, {0x10,0x18,0x7d,0xa7}, {0x1e,0x11,0x70,0xac}, +{0x34,0x2e,0x53,0x9d}, {0x3a,0x27,0x5e,0x96}, {0x28,0x3c,0x49,0x8b}, {0x26,0x35,0x44,0x80}, +{0x7c,0x42,0x0f,0xe9}, {0x72,0x4b,0x02,0xe2}, {0x60,0x50,0x15,0xff}, {0x6e,0x59,0x18,0xf4}, +{0x44,0x66,0x3b,0xc5}, {0x4a,0x6f,0x36,0xce}, {0x58,0x74,0x21,0xd3}, {0x56,0x7d,0x2c,0xd8}, +{0x37,0xa1,0x0c,0x7a}, {0x39,0xa8,0x01,0x71}, {0x2b,0xb3,0x16,0x6c}, {0x25,0xba,0x1b,0x67}, +{0x0f,0x85,0x38,0x56}, {0x01,0x8c,0x35,0x5d}, {0x13,0x97,0x22,0x40}, {0x1d,0x9e,0x2f,0x4b}, +{0x47,0xe9,0x64,0x22}, {0x49,0xe0,0x69,0x29}, {0x5b,0xfb,0x7e,0x34}, {0x55,0xf2,0x73,0x3f}, +{0x7f,0xcd,0x50,0x0e}, {0x71,0xc4,0x5d,0x05}, {0x63,0xdf,0x4a,0x18}, {0x6d,0xd6,0x47,0x13}, +{0xd7,0x31,0xdc,0xca}, {0xd9,0x38,0xd1,0xc1}, {0xcb,0x23,0xc6,0xdc}, {0xc5,0x2a,0xcb,0xd7}, +{0xef,0x15,0xe8,0xe6}, {0xe1,0x1c,0xe5,0xed}, {0xf3,0x07,0xf2,0xf0}, {0xfd,0x0e,0xff,0xfb}, +{0xa7,0x79,0xb4,0x92}, {0xa9,0x70,0xb9,0x99}, {0xbb,0x6b,0xae,0x84}, {0xb5,0x62,0xa3,0x8f}, +{0x9f,0x5d,0x80,0xbe}, {0x91,0x54,0x8d,0xb5}, {0x83,0x4f,0x9a,0xa8}, {0x8d,0x46,0x97,0xa3} + } +}; +#define U1 xU1.xt8 + +static const union xtab xU2 = { + .xt8 = { +{0x00,0x00,0x00,0x00}, {0x0b,0x0e,0x09,0x0d}, {0x16,0x1c,0x12,0x1a}, {0x1d,0x12,0x1b,0x17}, +{0x2c,0x38,0x24,0x34}, {0x27,0x36,0x2d,0x39}, {0x3a,0x24,0x36,0x2e}, {0x31,0x2a,0x3f,0x23}, +{0x58,0x70,0x48,0x68}, {0x53,0x7e,0x41,0x65}, {0x4e,0x6c,0x5a,0x72}, {0x45,0x62,0x53,0x7f}, +{0x74,0x48,0x6c,0x5c}, {0x7f,0x46,0x65,0x51}, {0x62,0x54,0x7e,0x46}, {0x69,0x5a,0x77,0x4b}, +{0xb0,0xe0,0x90,0xd0}, {0xbb,0xee,0x99,0xdd}, {0xa6,0xfc,0x82,0xca}, {0xad,0xf2,0x8b,0xc7}, +{0x9c,0xd8,0xb4,0xe4}, {0x97,0xd6,0xbd,0xe9}, {0x8a,0xc4,0xa6,0xfe}, {0x81,0xca,0xaf,0xf3}, +{0xe8,0x90,0xd8,0xb8}, {0xe3,0x9e,0xd1,0xb5}, {0xfe,0x8c,0xca,0xa2}, {0xf5,0x82,0xc3,0xaf}, +{0xc4,0xa8,0xfc,0x8c}, {0xcf,0xa6,0xf5,0x81}, {0xd2,0xb4,0xee,0x96}, {0xd9,0xba,0xe7,0x9b}, +{0x7b,0xdb,0x3b,0xbb}, {0x70,0xd5,0x32,0xb6}, {0x6d,0xc7,0x29,0xa1}, {0x66,0xc9,0x20,0xac}, +{0x57,0xe3,0x1f,0x8f}, {0x5c,0xed,0x16,0x82}, {0x41,0xff,0x0d,0x95}, {0x4a,0xf1,0x04,0x98}, +{0x23,0xab,0x73,0xd3}, {0x28,0xa5,0x7a,0xde}, {0x35,0xb7,0x61,0xc9}, {0x3e,0xb9,0x68,0xc4}, +{0x0f,0x93,0x57,0xe7}, {0x04,0x9d,0x5e,0xea}, {0x19,0x8f,0x45,0xfd}, {0x12,0x81,0x4c,0xf0}, +{0xcb,0x3b,0xab,0x6b}, {0xc0,0x35,0xa2,0x66}, {0xdd,0x27,0xb9,0x71}, {0xd6,0x29,0xb0,0x7c}, +{0xe7,0x03,0x8f,0x5f}, {0xec,0x0d,0x86,0x52}, {0xf1,0x1f,0x9d,0x45}, {0xfa,0x11,0x94,0x48}, +{0x93,0x4b,0xe3,0x03}, {0x98,0x45,0xea,0x0e}, {0x85,0x57,0xf1,0x19}, {0x8e,0x59,0xf8,0x14}, +{0xbf,0x73,0xc7,0x37}, {0xb4,0x7d,0xce,0x3a}, {0xa9,0x6f,0xd5,0x2d}, {0xa2,0x61,0xdc,0x20}, +{0xf6,0xad,0x76,0x6d}, {0xfd,0xa3,0x7f,0x60}, {0xe0,0xb1,0x64,0x77}, {0xeb,0xbf,0x6d,0x7a}, +{0xda,0x95,0x52,0x59}, {0xd1,0x9b,0x5b,0x54}, {0xcc,0x89,0x40,0x43}, {0xc7,0x87,0x49,0x4e}, +{0xae,0xdd,0x3e,0x05}, {0xa5,0xd3,0x37,0x08}, {0xb8,0xc1,0x2c,0x1f}, {0xb3,0xcf,0x25,0x12}, +{0x82,0xe5,0x1a,0x31}, {0x89,0xeb,0x13,0x3c}, {0x94,0xf9,0x08,0x2b}, {0x9f,0xf7,0x01,0x26}, +{0x46,0x4d,0xe6,0xbd}, {0x4d,0x43,0xef,0xb0}, {0x50,0x51,0xf4,0xa7}, {0x5b,0x5f,0xfd,0xaa}, +{0x6a,0x75,0xc2,0x89}, {0x61,0x7b,0xcb,0x84}, {0x7c,0x69,0xd0,0x93}, {0x77,0x67,0xd9,0x9e}, +{0x1e,0x3d,0xae,0xd5}, {0x15,0x33,0xa7,0xd8}, {0x08,0x21,0xbc,0xcf}, {0x03,0x2f,0xb5,0xc2}, +{0x32,0x05,0x8a,0xe1}, {0x39,0x0b,0x83,0xec}, {0x24,0x19,0x98,0xfb}, {0x2f,0x17,0x91,0xf6}, +{0x8d,0x76,0x4d,0xd6}, {0x86,0x78,0x44,0xdb}, {0x9b,0x6a,0x5f,0xcc}, {0x90,0x64,0x56,0xc1}, +{0xa1,0x4e,0x69,0xe2}, {0xaa,0x40,0x60,0xef}, {0xb7,0x52,0x7b,0xf8}, {0xbc,0x5c,0x72,0xf5}, +{0xd5,0x06,0x05,0xbe}, {0xde,0x08,0x0c,0xb3}, {0xc3,0x1a,0x17,0xa4}, {0xc8,0x14,0x1e,0xa9}, +{0xf9,0x3e,0x21,0x8a}, {0xf2,0x30,0x28,0x87}, {0xef,0x22,0x33,0x90}, {0xe4,0x2c,0x3a,0x9d}, +{0x3d,0x96,0xdd,0x06}, {0x36,0x98,0xd4,0x0b}, {0x2b,0x8a,0xcf,0x1c}, {0x20,0x84,0xc6,0x11}, +{0x11,0xae,0xf9,0x32}, {0x1a,0xa0,0xf0,0x3f}, {0x07,0xb2,0xeb,0x28}, {0x0c,0xbc,0xe2,0x25}, +{0x65,0xe6,0x95,0x6e}, {0x6e,0xe8,0x9c,0x63}, {0x73,0xfa,0x87,0x74}, {0x78,0xf4,0x8e,0x79}, +{0x49,0xde,0xb1,0x5a}, {0x42,0xd0,0xb8,0x57}, {0x5f,0xc2,0xa3,0x40}, {0x54,0xcc,0xaa,0x4d}, +{0xf7,0x41,0xec,0xda}, {0xfc,0x4f,0xe5,0xd7}, {0xe1,0x5d,0xfe,0xc0}, {0xea,0x53,0xf7,0xcd}, +{0xdb,0x79,0xc8,0xee}, {0xd0,0x77,0xc1,0xe3}, {0xcd,0x65,0xda,0xf4}, {0xc6,0x6b,0xd3,0xf9}, +{0xaf,0x31,0xa4,0xb2}, {0xa4,0x3f,0xad,0xbf}, {0xb9,0x2d,0xb6,0xa8}, {0xb2,0x23,0xbf,0xa5}, +{0x83,0x09,0x80,0x86}, {0x88,0x07,0x89,0x8b}, {0x95,0x15,0x92,0x9c}, {0x9e,0x1b,0x9b,0x91}, +{0x47,0xa1,0x7c,0x0a}, {0x4c,0xaf,0x75,0x07}, {0x51,0xbd,0x6e,0x10}, {0x5a,0xb3,0x67,0x1d}, +{0x6b,0x99,0x58,0x3e}, {0x60,0x97,0x51,0x33}, {0x7d,0x85,0x4a,0x24}, {0x76,0x8b,0x43,0x29}, +{0x1f,0xd1,0x34,0x62}, {0x14,0xdf,0x3d,0x6f}, {0x09,0xcd,0x26,0x78}, {0x02,0xc3,0x2f,0x75}, +{0x33,0xe9,0x10,0x56}, {0x38,0xe7,0x19,0x5b}, {0x25,0xf5,0x02,0x4c}, {0x2e,0xfb,0x0b,0x41}, +{0x8c,0x9a,0xd7,0x61}, {0x87,0x94,0xde,0x6c}, {0x9a,0x86,0xc5,0x7b}, {0x91,0x88,0xcc,0x76}, +{0xa0,0xa2,0xf3,0x55}, {0xab,0xac,0xfa,0x58}, {0xb6,0xbe,0xe1,0x4f}, {0xbd,0xb0,0xe8,0x42}, +{0xd4,0xea,0x9f,0x09}, {0xdf,0xe4,0x96,0x04}, {0xc2,0xf6,0x8d,0x13}, {0xc9,0xf8,0x84,0x1e}, +{0xf8,0xd2,0xbb,0x3d}, {0xf3,0xdc,0xb2,0x30}, {0xee,0xce,0xa9,0x27}, {0xe5,0xc0,0xa0,0x2a}, +{0x3c,0x7a,0x47,0xb1}, {0x37,0x74,0x4e,0xbc}, {0x2a,0x66,0x55,0xab}, {0x21,0x68,0x5c,0xa6}, +{0x10,0x42,0x63,0x85}, {0x1b,0x4c,0x6a,0x88}, {0x06,0x5e,0x71,0x9f}, {0x0d,0x50,0x78,0x92}, +{0x64,0x0a,0x0f,0xd9}, {0x6f,0x04,0x06,0xd4}, {0x72,0x16,0x1d,0xc3}, {0x79,0x18,0x14,0xce}, +{0x48,0x32,0x2b,0xed}, {0x43,0x3c,0x22,0xe0}, {0x5e,0x2e,0x39,0xf7}, {0x55,0x20,0x30,0xfa}, +{0x01,0xec,0x9a,0xb7}, {0x0a,0xe2,0x93,0xba}, {0x17,0xf0,0x88,0xad}, {0x1c,0xfe,0x81,0xa0}, +{0x2d,0xd4,0xbe,0x83}, {0x26,0xda,0xb7,0x8e}, {0x3b,0xc8,0xac,0x99}, {0x30,0xc6,0xa5,0x94}, +{0x59,0x9c,0xd2,0xdf}, {0x52,0x92,0xdb,0xd2}, {0x4f,0x80,0xc0,0xc5}, {0x44,0x8e,0xc9,0xc8}, +{0x75,0xa4,0xf6,0xeb}, {0x7e,0xaa,0xff,0xe6}, {0x63,0xb8,0xe4,0xf1}, {0x68,0xb6,0xed,0xfc}, +{0xb1,0x0c,0x0a,0x67}, {0xba,0x02,0x03,0x6a}, {0xa7,0x10,0x18,0x7d}, {0xac,0x1e,0x11,0x70}, +{0x9d,0x34,0x2e,0x53}, {0x96,0x3a,0x27,0x5e}, {0x8b,0x28,0x3c,0x49}, {0x80,0x26,0x35,0x44}, +{0xe9,0x7c,0x42,0x0f}, {0xe2,0x72,0x4b,0x02}, {0xff,0x60,0x50,0x15}, {0xf4,0x6e,0x59,0x18}, +{0xc5,0x44,0x66,0x3b}, {0xce,0x4a,0x6f,0x36}, {0xd3,0x58,0x74,0x21}, {0xd8,0x56,0x7d,0x2c}, +{0x7a,0x37,0xa1,0x0c}, {0x71,0x39,0xa8,0x01}, {0x6c,0x2b,0xb3,0x16}, {0x67,0x25,0xba,0x1b}, +{0x56,0x0f,0x85,0x38}, {0x5d,0x01,0x8c,0x35}, {0x40,0x13,0x97,0x22}, {0x4b,0x1d,0x9e,0x2f}, +{0x22,0x47,0xe9,0x64}, {0x29,0x49,0xe0,0x69}, {0x34,0x5b,0xfb,0x7e}, {0x3f,0x55,0xf2,0x73}, +{0x0e,0x7f,0xcd,0x50}, {0x05,0x71,0xc4,0x5d}, {0x18,0x63,0xdf,0x4a}, {0x13,0x6d,0xd6,0x47}, +{0xca,0xd7,0x31,0xdc}, {0xc1,0xd9,0x38,0xd1}, {0xdc,0xcb,0x23,0xc6}, {0xd7,0xc5,0x2a,0xcb}, +{0xe6,0xef,0x15,0xe8}, {0xed,0xe1,0x1c,0xe5}, {0xf0,0xf3,0x07,0xf2}, {0xfb,0xfd,0x0e,0xff}, +{0x92,0xa7,0x79,0xb4}, {0x99,0xa9,0x70,0xb9}, {0x84,0xbb,0x6b,0xae}, {0x8f,0xb5,0x62,0xa3}, +{0xbe,0x9f,0x5d,0x80}, {0xb5,0x91,0x54,0x8d}, {0xa8,0x83,0x4f,0x9a}, {0xa3,0x8d,0x46,0x97} + } +}; +#define U2 xU2.xt8 + +static const union xtab xU3 = { + .xt8 = { +{0x00,0x00,0x00,0x00}, {0x0d,0x0b,0x0e,0x09}, {0x1a,0x16,0x1c,0x12}, {0x17,0x1d,0x12,0x1b}, +{0x34,0x2c,0x38,0x24}, {0x39,0x27,0x36,0x2d}, {0x2e,0x3a,0x24,0x36}, {0x23,0x31,0x2a,0x3f}, +{0x68,0x58,0x70,0x48}, {0x65,0x53,0x7e,0x41}, {0x72,0x4e,0x6c,0x5a}, {0x7f,0x45,0x62,0x53}, +{0x5c,0x74,0x48,0x6c}, {0x51,0x7f,0x46,0x65}, {0x46,0x62,0x54,0x7e}, {0x4b,0x69,0x5a,0x77}, +{0xd0,0xb0,0xe0,0x90}, {0xdd,0xbb,0xee,0x99}, {0xca,0xa6,0xfc,0x82}, {0xc7,0xad,0xf2,0x8b}, +{0xe4,0x9c,0xd8,0xb4}, {0xe9,0x97,0xd6,0xbd}, {0xfe,0x8a,0xc4,0xa6}, {0xf3,0x81,0xca,0xaf}, +{0xb8,0xe8,0x90,0xd8}, {0xb5,0xe3,0x9e,0xd1}, {0xa2,0xfe,0x8c,0xca}, {0xaf,0xf5,0x82,0xc3}, +{0x8c,0xc4,0xa8,0xfc}, {0x81,0xcf,0xa6,0xf5}, {0x96,0xd2,0xb4,0xee}, {0x9b,0xd9,0xba,0xe7}, +{0xbb,0x7b,0xdb,0x3b}, {0xb6,0x70,0xd5,0x32}, {0xa1,0x6d,0xc7,0x29}, {0xac,0x66,0xc9,0x20}, +{0x8f,0x57,0xe3,0x1f}, {0x82,0x5c,0xed,0x16}, {0x95,0x41,0xff,0x0d}, {0x98,0x4a,0xf1,0x04}, +{0xd3,0x23,0xab,0x73}, {0xde,0x28,0xa5,0x7a}, {0xc9,0x35,0xb7,0x61}, {0xc4,0x3e,0xb9,0x68}, +{0xe7,0x0f,0x93,0x57}, {0xea,0x04,0x9d,0x5e}, {0xfd,0x19,0x8f,0x45}, {0xf0,0x12,0x81,0x4c}, +{0x6b,0xcb,0x3b,0xab}, {0x66,0xc0,0x35,0xa2}, {0x71,0xdd,0x27,0xb9}, {0x7c,0xd6,0x29,0xb0}, +{0x5f,0xe7,0x03,0x8f}, {0x52,0xec,0x0d,0x86}, {0x45,0xf1,0x1f,0x9d}, {0x48,0xfa,0x11,0x94}, +{0x03,0x93,0x4b,0xe3}, {0x0e,0x98,0x45,0xea}, {0x19,0x85,0x57,0xf1}, {0x14,0x8e,0x59,0xf8}, +{0x37,0xbf,0x73,0xc7}, {0x3a,0xb4,0x7d,0xce}, {0x2d,0xa9,0x6f,0xd5}, {0x20,0xa2,0x61,0xdc}, +{0x6d,0xf6,0xad,0x76}, {0x60,0xfd,0xa3,0x7f}, {0x77,0xe0,0xb1,0x64}, {0x7a,0xeb,0xbf,0x6d}, +{0x59,0xda,0x95,0x52}, {0x54,0xd1,0x9b,0x5b}, {0x43,0xcc,0x89,0x40}, {0x4e,0xc7,0x87,0x49}, +{0x05,0xae,0xdd,0x3e}, {0x08,0xa5,0xd3,0x37}, {0x1f,0xb8,0xc1,0x2c}, {0x12,0xb3,0xcf,0x25}, +{0x31,0x82,0xe5,0x1a}, {0x3c,0x89,0xeb,0x13}, {0x2b,0x94,0xf9,0x08}, {0x26,0x9f,0xf7,0x01}, +{0xbd,0x46,0x4d,0xe6}, {0xb0,0x4d,0x43,0xef}, {0xa7,0x50,0x51,0xf4}, {0xaa,0x5b,0x5f,0xfd}, +{0x89,0x6a,0x75,0xc2}, {0x84,0x61,0x7b,0xcb}, {0x93,0x7c,0x69,0xd0}, {0x9e,0x77,0x67,0xd9}, +{0xd5,0x1e,0x3d,0xae}, {0xd8,0x15,0x33,0xa7}, {0xcf,0x08,0x21,0xbc}, {0xc2,0x03,0x2f,0xb5}, +{0xe1,0x32,0x05,0x8a}, {0xec,0x39,0x0b,0x83}, {0xfb,0x24,0x19,0x98}, {0xf6,0x2f,0x17,0x91}, +{0xd6,0x8d,0x76,0x4d}, {0xdb,0x86,0x78,0x44}, {0xcc,0x9b,0x6a,0x5f}, {0xc1,0x90,0x64,0x56}, +{0xe2,0xa1,0x4e,0x69}, {0xef,0xaa,0x40,0x60}, {0xf8,0xb7,0x52,0x7b}, {0xf5,0xbc,0x5c,0x72}, +{0xbe,0xd5,0x06,0x05}, {0xb3,0xde,0x08,0x0c}, {0xa4,0xc3,0x1a,0x17}, {0xa9,0xc8,0x14,0x1e}, +{0x8a,0xf9,0x3e,0x21}, {0x87,0xf2,0x30,0x28}, {0x90,0xef,0x22,0x33}, {0x9d,0xe4,0x2c,0x3a}, +{0x06,0x3d,0x96,0xdd}, {0x0b,0x36,0x98,0xd4}, {0x1c,0x2b,0x8a,0xcf}, {0x11,0x20,0x84,0xc6}, +{0x32,0x11,0xae,0xf9}, {0x3f,0x1a,0xa0,0xf0}, {0x28,0x07,0xb2,0xeb}, {0x25,0x0c,0xbc,0xe2}, +{0x6e,0x65,0xe6,0x95}, {0x63,0x6e,0xe8,0x9c}, {0x74,0x73,0xfa,0x87}, {0x79,0x78,0xf4,0x8e}, +{0x5a,0x49,0xde,0xb1}, {0x57,0x42,0xd0,0xb8}, {0x40,0x5f,0xc2,0xa3}, {0x4d,0x54,0xcc,0xaa}, +{0xda,0xf7,0x41,0xec}, {0xd7,0xfc,0x4f,0xe5}, {0xc0,0xe1,0x5d,0xfe}, {0xcd,0xea,0x53,0xf7}, +{0xee,0xdb,0x79,0xc8}, {0xe3,0xd0,0x77,0xc1}, {0xf4,0xcd,0x65,0xda}, {0xf9,0xc6,0x6b,0xd3}, +{0xb2,0xaf,0x31,0xa4}, {0xbf,0xa4,0x3f,0xad}, {0xa8,0xb9,0x2d,0xb6}, {0xa5,0xb2,0x23,0xbf}, +{0x86,0x83,0x09,0x80}, {0x8b,0x88,0x07,0x89}, {0x9c,0x95,0x15,0x92}, {0x91,0x9e,0x1b,0x9b}, +{0x0a,0x47,0xa1,0x7c}, {0x07,0x4c,0xaf,0x75}, {0x10,0x51,0xbd,0x6e}, {0x1d,0x5a,0xb3,0x67}, +{0x3e,0x6b,0x99,0x58}, {0x33,0x60,0x97,0x51}, {0x24,0x7d,0x85,0x4a}, {0x29,0x76,0x8b,0x43}, +{0x62,0x1f,0xd1,0x34}, {0x6f,0x14,0xdf,0x3d}, {0x78,0x09,0xcd,0x26}, {0x75,0x02,0xc3,0x2f}, +{0x56,0x33,0xe9,0x10}, {0x5b,0x38,0xe7,0x19}, {0x4c,0x25,0xf5,0x02}, {0x41,0x2e,0xfb,0x0b}, +{0x61,0x8c,0x9a,0xd7}, {0x6c,0x87,0x94,0xde}, {0x7b,0x9a,0x86,0xc5}, {0x76,0x91,0x88,0xcc}, +{0x55,0xa0,0xa2,0xf3}, {0x58,0xab,0xac,0xfa}, {0x4f,0xb6,0xbe,0xe1}, {0x42,0xbd,0xb0,0xe8}, +{0x09,0xd4,0xea,0x9f}, {0x04,0xdf,0xe4,0x96}, {0x13,0xc2,0xf6,0x8d}, {0x1e,0xc9,0xf8,0x84}, +{0x3d,0xf8,0xd2,0xbb}, {0x30,0xf3,0xdc,0xb2}, {0x27,0xee,0xce,0xa9}, {0x2a,0xe5,0xc0,0xa0}, +{0xb1,0x3c,0x7a,0x47}, {0xbc,0x37,0x74,0x4e}, {0xab,0x2a,0x66,0x55}, {0xa6,0x21,0x68,0x5c}, +{0x85,0x10,0x42,0x63}, {0x88,0x1b,0x4c,0x6a}, {0x9f,0x06,0x5e,0x71}, {0x92,0x0d,0x50,0x78}, +{0xd9,0x64,0x0a,0x0f}, {0xd4,0x6f,0x04,0x06}, {0xc3,0x72,0x16,0x1d}, {0xce,0x79,0x18,0x14}, +{0xed,0x48,0x32,0x2b}, {0xe0,0x43,0x3c,0x22}, {0xf7,0x5e,0x2e,0x39}, {0xfa,0x55,0x20,0x30}, +{0xb7,0x01,0xec,0x9a}, {0xba,0x0a,0xe2,0x93}, {0xad,0x17,0xf0,0x88}, {0xa0,0x1c,0xfe,0x81}, +{0x83,0x2d,0xd4,0xbe}, {0x8e,0x26,0xda,0xb7}, {0x99,0x3b,0xc8,0xac}, {0x94,0x30,0xc6,0xa5}, +{0xdf,0x59,0x9c,0xd2}, {0xd2,0x52,0x92,0xdb}, {0xc5,0x4f,0x80,0xc0}, {0xc8,0x44,0x8e,0xc9}, +{0xeb,0x75,0xa4,0xf6}, {0xe6,0x7e,0xaa,0xff}, {0xf1,0x63,0xb8,0xe4}, {0xfc,0x68,0xb6,0xed}, +{0x67,0xb1,0x0c,0x0a}, {0x6a,0xba,0x02,0x03}, {0x7d,0xa7,0x10,0x18}, {0x70,0xac,0x1e,0x11}, +{0x53,0x9d,0x34,0x2e}, {0x5e,0x96,0x3a,0x27}, {0x49,0x8b,0x28,0x3c}, {0x44,0x80,0x26,0x35}, +{0x0f,0xe9,0x7c,0x42}, {0x02,0xe2,0x72,0x4b}, {0x15,0xff,0x60,0x50}, {0x18,0xf4,0x6e,0x59}, +{0x3b,0xc5,0x44,0x66}, {0x36,0xce,0x4a,0x6f}, {0x21,0xd3,0x58,0x74}, {0x2c,0xd8,0x56,0x7d}, +{0x0c,0x7a,0x37,0xa1}, {0x01,0x71,0x39,0xa8}, {0x16,0x6c,0x2b,0xb3}, {0x1b,0x67,0x25,0xba}, +{0x38,0x56,0x0f,0x85}, {0x35,0x5d,0x01,0x8c}, {0x22,0x40,0x13,0x97}, {0x2f,0x4b,0x1d,0x9e}, +{0x64,0x22,0x47,0xe9}, {0x69,0x29,0x49,0xe0}, {0x7e,0x34,0x5b,0xfb}, {0x73,0x3f,0x55,0xf2}, +{0x50,0x0e,0x7f,0xcd}, {0x5d,0x05,0x71,0xc4}, {0x4a,0x18,0x63,0xdf}, {0x47,0x13,0x6d,0xd6}, +{0xdc,0xca,0xd7,0x31}, {0xd1,0xc1,0xd9,0x38}, {0xc6,0xdc,0xcb,0x23}, {0xcb,0xd7,0xc5,0x2a}, +{0xe8,0xe6,0xef,0x15}, {0xe5,0xed,0xe1,0x1c}, {0xf2,0xf0,0xf3,0x07}, {0xff,0xfb,0xfd,0x0e}, +{0xb4,0x92,0xa7,0x79}, {0xb9,0x99,0xa9,0x70}, {0xae,0x84,0xbb,0x6b}, {0xa3,0x8f,0xb5,0x62}, +{0x80,0xbe,0x9f,0x5d}, {0x8d,0xb5,0x91,0x54}, {0x9a,0xa8,0x83,0x4f}, {0x97,0xa3,0x8d,0x46} + } +}; +#define U3 xU3.xt8 + +static const union xtab xU4 = { + .xt8 = { +{0x00,0x00,0x00,0x00}, {0x09,0x0d,0x0b,0x0e}, {0x12,0x1a,0x16,0x1c}, {0x1b,0x17,0x1d,0x12}, +{0x24,0x34,0x2c,0x38}, {0x2d,0x39,0x27,0x36}, {0x36,0x2e,0x3a,0x24}, {0x3f,0x23,0x31,0x2a}, +{0x48,0x68,0x58,0x70}, {0x41,0x65,0x53,0x7e}, {0x5a,0x72,0x4e,0x6c}, {0x53,0x7f,0x45,0x62}, +{0x6c,0x5c,0x74,0x48}, {0x65,0x51,0x7f,0x46}, {0x7e,0x46,0x62,0x54}, {0x77,0x4b,0x69,0x5a}, +{0x90,0xd0,0xb0,0xe0}, {0x99,0xdd,0xbb,0xee}, {0x82,0xca,0xa6,0xfc}, {0x8b,0xc7,0xad,0xf2}, +{0xb4,0xe4,0x9c,0xd8}, {0xbd,0xe9,0x97,0xd6}, {0xa6,0xfe,0x8a,0xc4}, {0xaf,0xf3,0x81,0xca}, +{0xd8,0xb8,0xe8,0x90}, {0xd1,0xb5,0xe3,0x9e}, {0xca,0xa2,0xfe,0x8c}, {0xc3,0xaf,0xf5,0x82}, +{0xfc,0x8c,0xc4,0xa8}, {0xf5,0x81,0xcf,0xa6}, {0xee,0x96,0xd2,0xb4}, {0xe7,0x9b,0xd9,0xba}, +{0x3b,0xbb,0x7b,0xdb}, {0x32,0xb6,0x70,0xd5}, {0x29,0xa1,0x6d,0xc7}, {0x20,0xac,0x66,0xc9}, +{0x1f,0x8f,0x57,0xe3}, {0x16,0x82,0x5c,0xed}, {0x0d,0x95,0x41,0xff}, {0x04,0x98,0x4a,0xf1}, +{0x73,0xd3,0x23,0xab}, {0x7a,0xde,0x28,0xa5}, {0x61,0xc9,0x35,0xb7}, {0x68,0xc4,0x3e,0xb9}, +{0x57,0xe7,0x0f,0x93}, {0x5e,0xea,0x04,0x9d}, {0x45,0xfd,0x19,0x8f}, {0x4c,0xf0,0x12,0x81}, +{0xab,0x6b,0xcb,0x3b}, {0xa2,0x66,0xc0,0x35}, {0xb9,0x71,0xdd,0x27}, {0xb0,0x7c,0xd6,0x29}, +{0x8f,0x5f,0xe7,0x03}, {0x86,0x52,0xec,0x0d}, {0x9d,0x45,0xf1,0x1f}, {0x94,0x48,0xfa,0x11}, +{0xe3,0x03,0x93,0x4b}, {0xea,0x0e,0x98,0x45}, {0xf1,0x19,0x85,0x57}, {0xf8,0x14,0x8e,0x59}, +{0xc7,0x37,0xbf,0x73}, {0xce,0x3a,0xb4,0x7d}, {0xd5,0x2d,0xa9,0x6f}, {0xdc,0x20,0xa2,0x61}, +{0x76,0x6d,0xf6,0xad}, {0x7f,0x60,0xfd,0xa3}, {0x64,0x77,0xe0,0xb1}, {0x6d,0x7a,0xeb,0xbf}, +{0x52,0x59,0xda,0x95}, {0x5b,0x54,0xd1,0x9b}, {0x40,0x43,0xcc,0x89}, {0x49,0x4e,0xc7,0x87}, +{0x3e,0x05,0xae,0xdd}, {0x37,0x08,0xa5,0xd3}, {0x2c,0x1f,0xb8,0xc1}, {0x25,0x12,0xb3,0xcf}, +{0x1a,0x31,0x82,0xe5}, {0x13,0x3c,0x89,0xeb}, {0x08,0x2b,0x94,0xf9}, {0x01,0x26,0x9f,0xf7}, +{0xe6,0xbd,0x46,0x4d}, {0xef,0xb0,0x4d,0x43}, {0xf4,0xa7,0x50,0x51}, {0xfd,0xaa,0x5b,0x5f}, +{0xc2,0x89,0x6a,0x75}, {0xcb,0x84,0x61,0x7b}, {0xd0,0x93,0x7c,0x69}, {0xd9,0x9e,0x77,0x67}, +{0xae,0xd5,0x1e,0x3d}, {0xa7,0xd8,0x15,0x33}, {0xbc,0xcf,0x08,0x21}, {0xb5,0xc2,0x03,0x2f}, +{0x8a,0xe1,0x32,0x05}, {0x83,0xec,0x39,0x0b}, {0x98,0xfb,0x24,0x19}, {0x91,0xf6,0x2f,0x17}, +{0x4d,0xd6,0x8d,0x76}, {0x44,0xdb,0x86,0x78}, {0x5f,0xcc,0x9b,0x6a}, {0x56,0xc1,0x90,0x64}, +{0x69,0xe2,0xa1,0x4e}, {0x60,0xef,0xaa,0x40}, {0x7b,0xf8,0xb7,0x52}, {0x72,0xf5,0xbc,0x5c}, +{0x05,0xbe,0xd5,0x06}, {0x0c,0xb3,0xde,0x08}, {0x17,0xa4,0xc3,0x1a}, {0x1e,0xa9,0xc8,0x14}, +{0x21,0x8a,0xf9,0x3e}, {0x28,0x87,0xf2,0x30}, {0x33,0x90,0xef,0x22}, {0x3a,0x9d,0xe4,0x2c}, +{0xdd,0x06,0x3d,0x96}, {0xd4,0x0b,0x36,0x98}, {0xcf,0x1c,0x2b,0x8a}, {0xc6,0x11,0x20,0x84}, +{0xf9,0x32,0x11,0xae}, {0xf0,0x3f,0x1a,0xa0}, {0xeb,0x28,0x07,0xb2}, {0xe2,0x25,0x0c,0xbc}, +{0x95,0x6e,0x65,0xe6}, {0x9c,0x63,0x6e,0xe8}, {0x87,0x74,0x73,0xfa}, {0x8e,0x79,0x78,0xf4}, +{0xb1,0x5a,0x49,0xde}, {0xb8,0x57,0x42,0xd0}, {0xa3,0x40,0x5f,0xc2}, {0xaa,0x4d,0x54,0xcc}, +{0xec,0xda,0xf7,0x41}, {0xe5,0xd7,0xfc,0x4f}, {0xfe,0xc0,0xe1,0x5d}, {0xf7,0xcd,0xea,0x53}, +{0xc8,0xee,0xdb,0x79}, {0xc1,0xe3,0xd0,0x77}, {0xda,0xf4,0xcd,0x65}, {0xd3,0xf9,0xc6,0x6b}, +{0xa4,0xb2,0xaf,0x31}, {0xad,0xbf,0xa4,0x3f}, {0xb6,0xa8,0xb9,0x2d}, {0xbf,0xa5,0xb2,0x23}, +{0x80,0x86,0x83,0x09}, {0x89,0x8b,0x88,0x07}, {0x92,0x9c,0x95,0x15}, {0x9b,0x91,0x9e,0x1b}, +{0x7c,0x0a,0x47,0xa1}, {0x75,0x07,0x4c,0xaf}, {0x6e,0x10,0x51,0xbd}, {0x67,0x1d,0x5a,0xb3}, +{0x58,0x3e,0x6b,0x99}, {0x51,0x33,0x60,0x97}, {0x4a,0x24,0x7d,0x85}, {0x43,0x29,0x76,0x8b}, +{0x34,0x62,0x1f,0xd1}, {0x3d,0x6f,0x14,0xdf}, {0x26,0x78,0x09,0xcd}, {0x2f,0x75,0x02,0xc3}, +{0x10,0x56,0x33,0xe9}, {0x19,0x5b,0x38,0xe7}, {0x02,0x4c,0x25,0xf5}, {0x0b,0x41,0x2e,0xfb}, +{0xd7,0x61,0x8c,0x9a}, {0xde,0x6c,0x87,0x94}, {0xc5,0x7b,0x9a,0x86}, {0xcc,0x76,0x91,0x88}, +{0xf3,0x55,0xa0,0xa2}, {0xfa,0x58,0xab,0xac}, {0xe1,0x4f,0xb6,0xbe}, {0xe8,0x42,0xbd,0xb0}, +{0x9f,0x09,0xd4,0xea}, {0x96,0x04,0xdf,0xe4}, {0x8d,0x13,0xc2,0xf6}, {0x84,0x1e,0xc9,0xf8}, +{0xbb,0x3d,0xf8,0xd2}, {0xb2,0x30,0xf3,0xdc}, {0xa9,0x27,0xee,0xce}, {0xa0,0x2a,0xe5,0xc0}, +{0x47,0xb1,0x3c,0x7a}, {0x4e,0xbc,0x37,0x74}, {0x55,0xab,0x2a,0x66}, {0x5c,0xa6,0x21,0x68}, +{0x63,0x85,0x10,0x42}, {0x6a,0x88,0x1b,0x4c}, {0x71,0x9f,0x06,0x5e}, {0x78,0x92,0x0d,0x50}, +{0x0f,0xd9,0x64,0x0a}, {0x06,0xd4,0x6f,0x04}, {0x1d,0xc3,0x72,0x16}, {0x14,0xce,0x79,0x18}, +{0x2b,0xed,0x48,0x32}, {0x22,0xe0,0x43,0x3c}, {0x39,0xf7,0x5e,0x2e}, {0x30,0xfa,0x55,0x20}, +{0x9a,0xb7,0x01,0xec}, {0x93,0xba,0x0a,0xe2}, {0x88,0xad,0x17,0xf0}, {0x81,0xa0,0x1c,0xfe}, +{0xbe,0x83,0x2d,0xd4}, {0xb7,0x8e,0x26,0xda}, {0xac,0x99,0x3b,0xc8}, {0xa5,0x94,0x30,0xc6}, +{0xd2,0xdf,0x59,0x9c}, {0xdb,0xd2,0x52,0x92}, {0xc0,0xc5,0x4f,0x80}, {0xc9,0xc8,0x44,0x8e}, +{0xf6,0xeb,0x75,0xa4}, {0xff,0xe6,0x7e,0xaa}, {0xe4,0xf1,0x63,0xb8}, {0xed,0xfc,0x68,0xb6}, +{0x0a,0x67,0xb1,0x0c}, {0x03,0x6a,0xba,0x02}, {0x18,0x7d,0xa7,0x10}, {0x11,0x70,0xac,0x1e}, +{0x2e,0x53,0x9d,0x34}, {0x27,0x5e,0x96,0x3a}, {0x3c,0x49,0x8b,0x28}, {0x35,0x44,0x80,0x26}, +{0x42,0x0f,0xe9,0x7c}, {0x4b,0x02,0xe2,0x72}, {0x50,0x15,0xff,0x60}, {0x59,0x18,0xf4,0x6e}, +{0x66,0x3b,0xc5,0x44}, {0x6f,0x36,0xce,0x4a}, {0x74,0x21,0xd3,0x58}, {0x7d,0x2c,0xd8,0x56}, +{0xa1,0x0c,0x7a,0x37}, {0xa8,0x01,0x71,0x39}, {0xb3,0x16,0x6c,0x2b}, {0xba,0x1b,0x67,0x25}, +{0x85,0x38,0x56,0x0f}, {0x8c,0x35,0x5d,0x01}, {0x97,0x22,0x40,0x13}, {0x9e,0x2f,0x4b,0x1d}, +{0xe9,0x64,0x22,0x47}, {0xe0,0x69,0x29,0x49}, {0xfb,0x7e,0x34,0x5b}, {0xf2,0x73,0x3f,0x55}, +{0xcd,0x50,0x0e,0x7f}, {0xc4,0x5d,0x05,0x71}, {0xdf,0x4a,0x18,0x63}, {0xd6,0x47,0x13,0x6d}, +{0x31,0xdc,0xca,0xd7}, {0x38,0xd1,0xc1,0xd9}, {0x23,0xc6,0xdc,0xcb}, {0x2a,0xcb,0xd7,0xc5}, +{0x15,0xe8,0xe6,0xef}, {0x1c,0xe5,0xed,0xe1}, {0x07,0xf2,0xf0,0xf3}, {0x0e,0xff,0xfb,0xfd}, +{0x79,0xb4,0x92,0xa7}, {0x70,0xb9,0x99,0xa9}, {0x6b,0xae,0x84,0xbb}, {0x62,0xa3,0x8f,0xb5}, +{0x5d,0x80,0xbe,0x9f}, {0x54,0x8d,0xb5,0x91}, {0x4f,0x9a,0xa8,0x83}, {0x46,0x97,0xa3,0x8d} + } +}; +#define U4 xU4.xt8 + +static const word32 rcon[30] = { + 0x01,0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 +}; diff --git a/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-alg-fst.c b/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-alg-fst.c new file mode 100644 index 00000000..7e48d44b --- /dev/null +++ b/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-alg-fst.c @@ -0,0 +1,496 @@ +/* $NetBSD: rijndael-alg-fst.c,v 1.4 2006/09/09 16:22:36 manu Exp $ */ + +/* $KAME: rijndael-alg-fst.c,v 1.1.1.1 2001/08/08 09:56:23 sakane Exp $ */ + +/* + * rijndael-alg-fst.c v2.3 April '2000 + * + * Optimised ANSI C code + * + * authors: v1.0: Antoon Bosselaers + * v2.0: Vincent Rijmen + * v2.3: Paulo Barreto + * + * This code is placed in the public domain. + */ + +#include "config.h" + +#include +#include +#ifdef _KERNEL +#include +#else +#include +#endif +#include +#include + +#include + +#include +#define bcopy(a, b, c) memcpy((b), (a), (c)) +#define bzero(a, b) memset((a), 0, (b)) +#define panic(a) err(1, (a)) + +int rijndaelKeySched(word8 k[MAXKC][4], word8 W[MAXROUNDS+1][4][4], int ROUNDS) { + /* Calculate the necessary round keys + * The number of calculations depends on keyBits and blockBits + */ + int j, r, t, rconpointer = 0; + union { + word8 x8[MAXKC][4]; + word32 x32[MAXKC]; + } xtk; +#define tk xtk.x8 + int KC = ROUNDS - 6; + + for (j = KC-1; j >= 0; j--) { + *((word32*)tk[j]) = *((word32*)k[j]); + } + r = 0; + t = 0; + /* copy values into round key array */ + for (j = 0; (j < KC) && (r < ROUNDS + 1); ) { + for (; (j < KC) && (t < 4); j++, t++) { + *((word32*)W[r][t]) = *((word32*)tk[j]); + } + if (t == 4) { + r++; + t = 0; + } + } + + while (r < ROUNDS + 1) { /* while not enough round key material calculated */ + /* calculate new values */ + tk[0][0] ^= S[tk[KC-1][1]]; + tk[0][1] ^= S[tk[KC-1][2]]; + tk[0][2] ^= S[tk[KC-1][3]]; + tk[0][3] ^= S[tk[KC-1][0]]; + tk[0][0] ^= rcon[rconpointer++]; + + if (KC != 8) { + for (j = 1; j < KC; j++) { + *((word32*)tk[j]) ^= *((word32*)tk[j-1]); + } + } else { + for (j = 1; j < KC/2; j++) { + *((word32*)tk[j]) ^= *((word32*)tk[j-1]); + } + tk[KC/2][0] ^= S[tk[KC/2 - 1][0]]; + tk[KC/2][1] ^= S[tk[KC/2 - 1][1]]; + tk[KC/2][2] ^= S[tk[KC/2 - 1][2]]; + tk[KC/2][3] ^= S[tk[KC/2 - 1][3]]; + for (j = KC/2 + 1; j < KC; j++) { + *((word32*)tk[j]) ^= *((word32*)tk[j-1]); + } + } + /* copy values into round key array */ + for (j = 0; (j < KC) && (r < ROUNDS + 1); ) { + for (; (j < KC) && (t < 4); j++, t++) { + *((word32*)W[r][t]) = *((word32*)tk[j]); + } + if (t == 4) { + r++; + t = 0; + } + } + } + return 0; +#undef tk +} + +int rijndaelKeyEncToDec(word8 W[MAXROUNDS+1][4][4], int ROUNDS) { + int r; + word8 *w; + + for (r = 1; r < ROUNDS; r++) { + w = W[r][0]; + *((word32*)w) = + *((const word32*)U1[w[0]]) + ^ *((const word32*)U2[w[1]]) + ^ *((const word32*)U3[w[2]]) + ^ *((const word32*)U4[w[3]]); + + w = W[r][1]; + *((word32*)w) = + *((const word32*)U1[w[0]]) + ^ *((const word32*)U2[w[1]]) + ^ *((const word32*)U3[w[2]]) + ^ *((const word32*)U4[w[3]]); + + w = W[r][2]; + *((word32*)w) = + *((const word32*)U1[w[0]]) + ^ *((const word32*)U2[w[1]]) + ^ *((const word32*)U3[w[2]]) + ^ *((const word32*)U4[w[3]]); + + w = W[r][3]; + *((word32*)w) = + *((const word32*)U1[w[0]]) + ^ *((const word32*)U2[w[1]]) + ^ *((const word32*)U3[w[2]]) + ^ *((const word32*)U4[w[3]]); + } + return 0; +} + +/** + * Encrypt a single block. + */ +int rijndaelEncrypt(word8 in[16], word8 out[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS) { + int r; + union { + word8 x8[16]; + word32 x32[4]; + } xa, xb; +#define a xa.x8 +#define b xb.x8 + union { + word8 x8[4][4]; + word32 x32[4]; + } xtemp; +#define temp xtemp.x8 + + memcpy(a, in, sizeof a); + + *((word32*)temp[0]) = *((word32*)(a )) ^ *((word32*)rk[0][0]); + *((word32*)temp[1]) = *((word32*)(a+ 4)) ^ *((word32*)rk[0][1]); + *((word32*)temp[2]) = *((word32*)(a+ 8)) ^ *((word32*)rk[0][2]); + *((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[0][3]); + *((word32*)(b )) = *((const word32*)T1[temp[0][0]]) + ^ *((const word32*)T2[temp[1][1]]) + ^ *((const word32*)T3[temp[2][2]]) + ^ *((const word32*)T4[temp[3][3]]); + *((word32*)(b + 4)) = *((const word32*)T1[temp[1][0]]) + ^ *((const word32*)T2[temp[2][1]]) + ^ *((const word32*)T3[temp[3][2]]) + ^ *((const word32*)T4[temp[0][3]]); + *((word32*)(b + 8)) = *((const word32*)T1[temp[2][0]]) + ^ *((const word32*)T2[temp[3][1]]) + ^ *((const word32*)T3[temp[0][2]]) + ^ *((const word32*)T4[temp[1][3]]); + *((word32*)(b +12)) = *((const word32*)T1[temp[3][0]]) + ^ *((const word32*)T2[temp[0][1]]) + ^ *((const word32*)T3[temp[1][2]]) + ^ *((const word32*)T4[temp[2][3]]); + for (r = 1; r < ROUNDS-1; r++) { + *((word32*)temp[0]) = *((word32*)(b )) ^ *((word32*)rk[r][0]); + *((word32*)temp[1]) = *((word32*)(b+ 4)) ^ *((word32*)rk[r][1]); + *((word32*)temp[2]) = *((word32*)(b+ 8)) ^ *((word32*)rk[r][2]); + *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]); + + *((word32*)(b )) = *((const word32*)T1[temp[0][0]]) + ^ *((const word32*)T2[temp[1][1]]) + ^ *((const word32*)T3[temp[2][2]]) + ^ *((const word32*)T4[temp[3][3]]); + *((word32*)(b + 4)) = *((const word32*)T1[temp[1][0]]) + ^ *((const word32*)T2[temp[2][1]]) + ^ *((const word32*)T3[temp[3][2]]) + ^ *((const word32*)T4[temp[0][3]]); + *((word32*)(b + 8)) = *((const word32*)T1[temp[2][0]]) + ^ *((const word32*)T2[temp[3][1]]) + ^ *((const word32*)T3[temp[0][2]]) + ^ *((const word32*)T4[temp[1][3]]); + *((word32*)(b +12)) = *((const word32*)T1[temp[3][0]]) + ^ *((const word32*)T2[temp[0][1]]) + ^ *((const word32*)T3[temp[1][2]]) + ^ *((const word32*)T4[temp[2][3]]); + } + /* last round is special */ + *((word32*)temp[0]) = *((word32*)(b )) ^ *((word32*)rk[ROUNDS-1][0]); + *((word32*)temp[1]) = *((word32*)(b+ 4)) ^ *((word32*)rk[ROUNDS-1][1]); + *((word32*)temp[2]) = *((word32*)(b+ 8)) ^ *((word32*)rk[ROUNDS-1][2]); + *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[ROUNDS-1][3]); + b[ 0] = T1[temp[0][0]][1]; + b[ 1] = T1[temp[1][1]][1]; + b[ 2] = T1[temp[2][2]][1]; + b[ 3] = T1[temp[3][3]][1]; + b[ 4] = T1[temp[1][0]][1]; + b[ 5] = T1[temp[2][1]][1]; + b[ 6] = T1[temp[3][2]][1]; + b[ 7] = T1[temp[0][3]][1]; + b[ 8] = T1[temp[2][0]][1]; + b[ 9] = T1[temp[3][1]][1]; + b[10] = T1[temp[0][2]][1]; + b[11] = T1[temp[1][3]][1]; + b[12] = T1[temp[3][0]][1]; + b[13] = T1[temp[0][1]][1]; + b[14] = T1[temp[1][2]][1]; + b[15] = T1[temp[2][3]][1]; + *((word32*)(b )) ^= *((word32*)rk[ROUNDS][0]); + *((word32*)(b+ 4)) ^= *((word32*)rk[ROUNDS][1]); + *((word32*)(b+ 8)) ^= *((word32*)rk[ROUNDS][2]); + *((word32*)(b+12)) ^= *((word32*)rk[ROUNDS][3]); + + memcpy(out, b, sizeof b /* XXX out */); + + return 0; +#undef a +#undef b +#undef temp +} + +#ifdef INTERMEDIATE_VALUE_KAT +/** + * Encrypt only a certain number of rounds. + * Only used in the Intermediate Value Known Answer Test. + */ +int rijndaelEncryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS, int rounds) { + int r; + word8 temp[4][4]; + + /* make number of rounds sane */ + if (rounds > ROUNDS) { + rounds = ROUNDS; + } + + *((word32*)a[0]) = *((word32*)a[0]) ^ *((word32*)rk[0][0]); + *((word32*)a[1]) = *((word32*)a[1]) ^ *((word32*)rk[0][1]); + *((word32*)a[2]) = *((word32*)a[2]) ^ *((word32*)rk[0][2]); + *((word32*)a[3]) = *((word32*)a[3]) ^ *((word32*)rk[0][3]); + + for (r = 1; (r <= rounds) && (r < ROUNDS); r++) { + *((word32*)temp[0]) = *((const word32*)T1[a[0][0]]) + ^ *((const word32*)T2[a[1][1]]) + ^ *((const word32*)T3[a[2][2]]) + ^ *((const word32*)T4[a[3][3]]); + *((word32*)temp[1]) = *((const word32*)T1[a[1][0]]) + ^ *((const word32*)T2[a[2][1]]) + ^ *((const word32*)T3[a[3][2]]) + ^ *((const word32*)T4[a[0][3]]); + *((word32*)temp[2]) = *((const word32*)T1[a[2][0]]) + ^ *((const word32*)T2[a[3][1]]) + ^ *((const word32*)T3[a[0][2]]) + ^ *((const word32*)T4[a[1][3]]); + *((word32*)temp[3]) = *((const word32*)T1[a[3][0]]) + ^ *((const word32*)T2[a[0][1]]) + ^ *((const word32*)T3[a[1][2]]) + ^ *((const word32*)T4[a[2][3]]); + *((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[r][0]); + *((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[r][1]); + *((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[r][2]); + *((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[r][3]); + } + if (rounds == ROUNDS) { + /* last round is special */ + temp[0][0] = T1[a[0][0]][1]; + temp[0][1] = T1[a[1][1]][1]; + temp[0][2] = T1[a[2][2]][1]; + temp[0][3] = T1[a[3][3]][1]; + temp[1][0] = T1[a[1][0]][1]; + temp[1][1] = T1[a[2][1]][1]; + temp[1][2] = T1[a[3][2]][1]; + temp[1][3] = T1[a[0][3]][1]; + temp[2][0] = T1[a[2][0]][1]; + temp[2][1] = T1[a[3][1]][1]; + temp[2][2] = T1[a[0][2]][1]; + temp[2][3] = T1[a[1][3]][1]; + temp[3][0] = T1[a[3][0]][1]; + temp[3][1] = T1[a[0][1]][1]; + temp[3][2] = T1[a[1][2]][1]; + temp[3][3] = T1[a[2][3]][1]; + *((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[ROUNDS][0]); + *((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[ROUNDS][1]); + *((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[ROUNDS][2]); + *((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[ROUNDS][3]); + } + + return 0; +} +#endif /* INTERMEDIATE_VALUE_KAT */ + +/** + * Decrypt a single block. + */ +int rijndaelDecrypt(word8 in[16], word8 out[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS) { + int r; + union { + word8 x8[16]; + word32 x32[4]; + } xa, xb; +#define a xa.x8 +#define b xb.x8 + union { + word8 x8[4][4]; + word32 x32[4]; + } xtemp; +#define temp xtemp.x8 + + memcpy(a, in, sizeof a); + + *((word32*)temp[0]) = *((word32*)(a )) ^ *((word32*)rk[ROUNDS][0]); + *((word32*)temp[1]) = *((word32*)(a+ 4)) ^ *((word32*)rk[ROUNDS][1]); + *((word32*)temp[2]) = *((word32*)(a+ 8)) ^ *((word32*)rk[ROUNDS][2]); + *((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[ROUNDS][3]); + + *((word32*)(b )) = *((const word32*)T5[temp[0][0]]) + ^ *((const word32*)T6[temp[3][1]]) + ^ *((const word32*)T7[temp[2][2]]) + ^ *((const word32*)T8[temp[1][3]]); + *((word32*)(b+ 4)) = *((const word32*)T5[temp[1][0]]) + ^ *((const word32*)T6[temp[0][1]]) + ^ *((const word32*)T7[temp[3][2]]) + ^ *((const word32*)T8[temp[2][3]]); + *((word32*)(b+ 8)) = *((const word32*)T5[temp[2][0]]) + ^ *((const word32*)T6[temp[1][1]]) + ^ *((const word32*)T7[temp[0][2]]) + ^ *((const word32*)T8[temp[3][3]]); + *((word32*)(b+12)) = *((const word32*)T5[temp[3][0]]) + ^ *((const word32*)T6[temp[2][1]]) + ^ *((const word32*)T7[temp[1][2]]) + ^ *((const word32*)T8[temp[0][3]]); + for (r = ROUNDS-1; r > 1; r--) { + *((word32*)temp[0]) = *((word32*)(b )) ^ *((word32*)rk[r][0]); + *((word32*)temp[1]) = *((word32*)(b+ 4)) ^ *((word32*)rk[r][1]); + *((word32*)temp[2]) = *((word32*)(b+ 8)) ^ *((word32*)rk[r][2]); + *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]); + *((word32*)(b )) = *((const word32*)T5[temp[0][0]]) + ^ *((const word32*)T6[temp[3][1]]) + ^ *((const word32*)T7[temp[2][2]]) + ^ *((const word32*)T8[temp[1][3]]); + *((word32*)(b+ 4)) = *((const word32*)T5[temp[1][0]]) + ^ *((const word32*)T6[temp[0][1]]) + ^ *((const word32*)T7[temp[3][2]]) + ^ *((const word32*)T8[temp[2][3]]); + *((word32*)(b+ 8)) = *((const word32*)T5[temp[2][0]]) + ^ *((const word32*)T6[temp[1][1]]) + ^ *((const word32*)T7[temp[0][2]]) + ^ *((const word32*)T8[temp[3][3]]); + *((word32*)(b+12)) = *((const word32*)T5[temp[3][0]]) + ^ *((const word32*)T6[temp[2][1]]) + ^ *((const word32*)T7[temp[1][2]]) + ^ *((const word32*)T8[temp[0][3]]); + } + /* last round is special */ + *((word32*)temp[0]) = *((word32*)(b )) ^ *((word32*)rk[1][0]); + *((word32*)temp[1]) = *((word32*)(b+ 4)) ^ *((word32*)rk[1][1]); + *((word32*)temp[2]) = *((word32*)(b+ 8)) ^ *((word32*)rk[1][2]); + *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[1][3]); + b[ 0] = S5[temp[0][0]]; + b[ 1] = S5[temp[3][1]]; + b[ 2] = S5[temp[2][2]]; + b[ 3] = S5[temp[1][3]]; + b[ 4] = S5[temp[1][0]]; + b[ 5] = S5[temp[0][1]]; + b[ 6] = S5[temp[3][2]]; + b[ 7] = S5[temp[2][3]]; + b[ 8] = S5[temp[2][0]]; + b[ 9] = S5[temp[1][1]]; + b[10] = S5[temp[0][2]]; + b[11] = S5[temp[3][3]]; + b[12] = S5[temp[3][0]]; + b[13] = S5[temp[2][1]]; + b[14] = S5[temp[1][2]]; + b[15] = S5[temp[0][3]]; + *((word32*)(b )) ^= *((word32*)rk[0][0]); + *((word32*)(b+ 4)) ^= *((word32*)rk[0][1]); + *((word32*)(b+ 8)) ^= *((word32*)rk[0][2]); + *((word32*)(b+12)) ^= *((word32*)rk[0][3]); + + memcpy(out, b, sizeof b /* XXX out */); + + return 0; +#undef a +#undef b +#undef temp +} + + +#ifdef INTERMEDIATE_VALUE_KAT +/** + * Decrypt only a certain number of rounds. + * Only used in the Intermediate Value Known Answer Test. + * Operations rearranged such that the intermediate values + * of decryption correspond with the intermediate values + * of encryption. + */ +int rijndaelDecryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS, int rounds) { + int r, i; + word8 temp[4], shift; + + /* make number of rounds sane */ + if (rounds > ROUNDS) { + rounds = ROUNDS; + } + /* first round is special: */ + *(word32 *)a[0] ^= *(word32 *)rk[ROUNDS][0]; + *(word32 *)a[1] ^= *(word32 *)rk[ROUNDS][1]; + *(word32 *)a[2] ^= *(word32 *)rk[ROUNDS][2]; + *(word32 *)a[3] ^= *(word32 *)rk[ROUNDS][3]; + for (i = 0; i < 4; i++) { + a[i][0] = Si[a[i][0]]; + a[i][1] = Si[a[i][1]]; + a[i][2] = Si[a[i][2]]; + a[i][3] = Si[a[i][3]]; + } + for (i = 1; i < 4; i++) { + shift = (4 - i) & 3; + temp[0] = a[(0 + shift) & 3][i]; + temp[1] = a[(1 + shift) & 3][i]; + temp[2] = a[(2 + shift) & 3][i]; + temp[3] = a[(3 + shift) & 3][i]; + a[0][i] = temp[0]; + a[1][i] = temp[1]; + a[2][i] = temp[2]; + a[3][i] = temp[3]; + } + /* ROUNDS-1 ordinary rounds */ + for (r = ROUNDS-1; r > rounds; r--) { + *(word32 *)a[0] ^= *(word32 *)rk[r][0]; + *(word32 *)a[1] ^= *(word32 *)rk[r][1]; + *(word32 *)a[2] ^= *(word32 *)rk[r][2]; + *(word32 *)a[3] ^= *(word32 *)rk[r][3]; + + *((word32*)a[0]) = + *((const word32*)U1[a[0][0]]) + ^ *((const word32*)U2[a[0][1]]) + ^ *((const word32*)U3[a[0][2]]) + ^ *((const word32*)U4[a[0][3]]); + + *((word32*)a[1]) = + *((const word32*)U1[a[1][0]]) + ^ *((const word32*)U2[a[1][1]]) + ^ *((const word32*)U3[a[1][2]]) + ^ *((const word32*)U4[a[1][3]]); + + *((word32*)a[2]) = + *((const word32*)U1[a[2][0]]) + ^ *((const word32*)U2[a[2][1]]) + ^ *((const word32*)U3[a[2][2]]) + ^ *((const word32*)U4[a[2][3]]); + + *((word32*)a[3]) = + *((const word32*)U1[a[3][0]]) + ^ *((const word32*)U2[a[3][1]]) + ^ *((const word32*)U3[a[3][2]]) + ^ *((const word32*)U4[a[3][3]]); + for (i = 0; i < 4; i++) { + a[i][0] = Si[a[i][0]]; + a[i][1] = Si[a[i][1]]; + a[i][2] = Si[a[i][2]]; + a[i][3] = Si[a[i][3]]; + } + for (i = 1; i < 4; i++) { + shift = (4 - i) & 3; + temp[0] = a[(0 + shift) & 3][i]; + temp[1] = a[(1 + shift) & 3][i]; + temp[2] = a[(2 + shift) & 3][i]; + temp[3] = a[(3 + shift) & 3][i]; + a[0][i] = temp[0]; + a[1][i] = temp[1]; + a[2][i] = temp[2]; + a[3][i] = temp[3]; + } + } + if (rounds == 0) { + /* End with the extra key addition */ + *(word32 *)a[0] ^= *(word32 *)rk[0][0]; + *(word32 *)a[1] ^= *(word32 *)rk[0][1]; + *(word32 *)a[2] ^= *(word32 *)rk[0][2]; + *(word32 *)a[3] ^= *(word32 *)rk[0][3]; + } + return 0; +} +#endif /* INTERMEDIATE_VALUE_KAT */ diff --git a/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-alg-fst.h b/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-alg-fst.h new file mode 100644 index 00000000..4afeca11 --- /dev/null +++ b/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-alg-fst.h @@ -0,0 +1,35 @@ +/* $NetBSD: rijndael-alg-fst.h,v 1.4 2006/09/09 16:22:36 manu Exp $ */ + +/* $KAME: rijndael-alg-fst.h,v 1.1.1.1 2001/08/08 09:56:23 sakane Exp $ */ + +/* + * rijndael-alg-fst.h v2.3 April '2000 + * + * Optimised ANSI C code + * + * #define INTERMEDIATE_VALUE_KAT to generate the Intermediate Value Known Answer Test. + */ + +#ifndef __RIJNDAEL_ALG_FST_H +#define __RIJNDAEL_ALG_FST_H + +#define RIJNDAEL_MAXKC (256/32) +#define RIJNDAEL_MAXROUNDS 14 + +int rijndaelKeySched(u_int8_t k[RIJNDAEL_MAXKC][4], u_int8_t rk[RIJNDAEL_MAXROUNDS+1][4][4], int ROUNDS); + +int rijndaelKeyEncToDec(u_int8_t W[RIJNDAEL_MAXROUNDS+1][4][4], int ROUNDS); + +int rijndaelEncrypt(u_int8_t a[16], u_int8_t b[16], u_int8_t rk[RIJNDAEL_MAXROUNDS+1][4][4], int ROUNDS); + +#ifdef INTERMEDIATE_VALUE_KAT +int rijndaelEncryptRound(u_int8_t a[4][4], u_int8_t rk[RIJNDAEL_MAXROUNDS+1][4][4], int ROUNDS, int rounds); +#endif /* INTERMEDIATE_VALUE_KAT */ + +int rijndaelDecrypt(u_int8_t a[16], u_int8_t b[16], u_int8_t rk[RIJNDAEL_MAXROUNDS+1][4][4], int ROUNDS); + +#ifdef INTERMEDIATE_VALUE_KAT +int rijndaelDecryptRound(u_int8_t a[4][4], u_int8_t rk[RIJNDAEL_MAXROUNDS+1][4][4], int ROUNDS, int rounds); +#endif /* INTERMEDIATE_VALUE_KAT */ + +#endif /* __RIJNDAEL_ALG_FST_H */ diff --git a/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-api-fst.c b/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-api-fst.c new file mode 100644 index 00000000..9b6f5fe0 --- /dev/null +++ b/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-api-fst.c @@ -0,0 +1,494 @@ +/* $NetBSD: rijndael-api-fst.c,v 1.4 2006/09/09 16:22:36 manu Exp $ */ + +/* $KAME: rijndael-api-fst.c,v 1.8 2002/11/18 23:32:54 itojun Exp $ */ + +/* + * rijndael-api-fst.c v2.3 April '2000 + * + * Optimised ANSI C code + * + * authors: v1.0: Antoon Bosselaers + * v2.0: Vincent Rijmen + * v2.1: Vincent Rijmen + * v2.2: Vincent Rijmen + * v2.3: Paulo Barreto + * v2.4: Vincent Rijmen + * + * This code is placed in the public domain. + */ + +#include "config.h" + +#include +#include +#ifdef _KERNEL +#include +#include +#else +#include +#endif +#include +#include +#include + +#include +#define bcopy(a, b, c) memcpy(b, a, c) +#define bzero(a, b) memset(a, 0, b) +#define panic(a) err(1, (a)) + +int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) { + word8 k[MAXKC][4]; + int i; + char *keyMat; + + if (key == NULL) { + return BAD_KEY_INSTANCE; + } + + if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) { + key->direction = direction; + } else { + return BAD_KEY_DIR; + } + + if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { + key->keyLen = keyLen; + } else { + return BAD_KEY_MAT; + } + + if (keyMaterial != NULL) { + bcopy(keyMaterial, key->keyMaterial, keyLen/8); + } + + key->ROUNDS = keyLen/32 + 6; + + /* initialize key schedule: */ + keyMat = key->keyMaterial; + for (i = 0; i < key->keyLen/8; i++) { + k[i >> 2][i & 3] = (word8)keyMat[i]; + } + rijndaelKeySched(k, key->keySched, key->ROUNDS); + if (direction == DIR_DECRYPT) { + rijndaelKeyEncToDec(key->keySched, key->ROUNDS); + } + + return TRUE; +} + +int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) { + if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { + cipher->mode = mode; + } else { + return BAD_CIPHER_MODE; + } + if (IV != NULL) { + bcopy(IV, cipher->IV, MAX_IV_SIZE); + } else { + bzero(cipher->IV, MAX_IV_SIZE); + } + return TRUE; +} + +int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputLen, BYTE *outBuffer) { + int i, k, numBlocks; + word8 block[16], iv[4][4]; + + if (cipher == NULL || + key == NULL || + key->direction == DIR_DECRYPT) { + return BAD_CIPHER_STATE; + } + if (input == NULL || inputLen <= 0) { + return 0; /* nothing to do */ + } + + numBlocks = inputLen/128; + + switch (cipher->mode) { + case MODE_ECB: + for (i = numBlocks; i > 0; i--) { + rijndaelEncrypt(input, outBuffer, key->keySched, key->ROUNDS); + input += 16; + outBuffer += 16; + } + break; + + case MODE_CBC: +#if 1 /*STRICT_ALIGN*/ + bcopy(cipher->IV, block, 16); + bcopy(input, iv, 16); + ((word32*)block)[0] ^= ((word32*)iv)[0]; + ((word32*)block)[1] ^= ((word32*)iv)[1]; + ((word32*)block)[2] ^= ((word32*)iv)[2]; + ((word32*)block)[3] ^= ((word32*)iv)[3]; +#else + ((word32*)block)[0] = ((word32*)cipher->IV)[0] ^ ((word32*)input)[0]; + ((word32*)block)[1] = ((word32*)cipher->IV)[1] ^ ((word32*)input)[1]; + ((word32*)block)[2] = ((word32*)cipher->IV)[2] ^ ((word32*)input)[2]; + ((word32*)block)[3] = ((word32*)cipher->IV)[3] ^ ((word32*)input)[3]; +#endif + rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); + input += 16; + for (i = numBlocks - 1; i > 0; i--) { +#if 1 /*STRICT_ALIGN*/ + bcopy(outBuffer, block, 16); + bcopy(input, iv, 16); + ((word32*)block)[0] ^= ((word32*)iv)[0]; + ((word32*)block)[1] ^= ((word32*)iv)[1]; + ((word32*)block)[2] ^= ((word32*)iv)[2]; + ((word32*)block)[3] ^= ((word32*)iv)[3]; +#else + ((word32*)block)[0] = ((word32*)outBuffer)[0] ^ ((word32*)input)[0]; + ((word32*)block)[1] = ((word32*)outBuffer)[1] ^ ((word32*)input)[1]; + ((word32*)block)[2] = ((word32*)outBuffer)[2] ^ ((word32*)input)[2]; + ((word32*)block)[3] = ((word32*)outBuffer)[3] ^ ((word32*)input)[3]; +#endif + outBuffer += 16; + rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); + input += 16; + } + break; + + case MODE_CFB1: +#if 1 /*STRICT_ALIGN*/ + bcopy(cipher->IV, iv, 16); +#else /* !STRICT_ALIGN */ + *((word32*)iv[0]) = *((word32*)(cipher->IV )); + *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4)); + *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8)); + *((word32*)iv[3]) = *((word32*)(cipher->IV+12)); +#endif /* ?STRICT_ALIGN */ + for (i = numBlocks; i > 0; i--) { + for (k = 0; k < 128; k++) { + *((word32*) block ) = *((word32*)iv[0]); + *((word32*)(block+ 4)) = *((word32*)iv[1]); + *((word32*)(block+ 8)) = *((word32*)iv[2]); + *((word32*)(block+12)) = *((word32*)iv[3]); + rijndaelEncrypt(block, block, key->keySched, key->ROUNDS); + outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); + iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); + iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); + iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); + iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); + iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); + iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); + iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); + iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); + iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); + iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); + iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); + iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); + iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); + iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); + iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); + iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1); + } + } + break; + + default: + return BAD_CIPHER_STATE; + } + + return 128*numBlocks; +} + +/** + * Encrypt data partitioned in octets, using RFC 2040-like padding. + * + * @param input data to be encrypted (octet sequence) + * @param inputOctets input length in octets (not bits) + * @param outBuffer encrypted output data + * + * @return length in octets (not bits) of the encrypted output buffer. + */ +int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputOctets, BYTE *outBuffer) { + int i, numBlocks, padLen; + word8 block[16], *iv, *cp; + + if (cipher == NULL || + key == NULL || + key->direction == DIR_DECRYPT) { + return BAD_CIPHER_STATE; + } + if (input == NULL || inputOctets <= 0) { + return 0; /* nothing to do */ + } + + numBlocks = inputOctets/16; + + switch (cipher->mode) { + case MODE_ECB: + for (i = numBlocks; i > 0; i--) { + rijndaelEncrypt(input, outBuffer, key->keySched, key->ROUNDS); + input += 16; + outBuffer += 16; + } + padLen = 16 - (inputOctets - 16*numBlocks); + if (padLen <= 0 || padLen > 16) + panic("rijndael_padEncrypt(ECB)"); + bcopy(input, block, 16 - padLen); + for (cp = block + 16 - padLen; cp < block + 16; cp++) + *cp = padLen; + rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); + break; + + case MODE_CBC: + iv = cipher->IV; + for (i = numBlocks; i > 0; i--) { + ((word32*)block)[0] = ((word32*)input)[0] ^ ((word32*)iv)[0]; + ((word32*)block)[1] = ((word32*)input)[1] ^ ((word32*)iv)[1]; + ((word32*)block)[2] = ((word32*)input)[2] ^ ((word32*)iv)[2]; + ((word32*)block)[3] = ((word32*)input)[3] ^ ((word32*)iv)[3]; + rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); + iv = outBuffer; + input += 16; + outBuffer += 16; + } + padLen = 16 - (inputOctets - 16*numBlocks); + if (padLen <= 0 || padLen > 16) + panic("rijndael_padEncrypt(CBC)"); + for (i = 0; i < 16 - padLen; i++) { + block[i] = input[i] ^ iv[i]; + } + for (i = 16 - padLen; i < 16; i++) { + block[i] = (BYTE)padLen ^ iv[i]; + } + rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); + break; + + default: + return BAD_CIPHER_STATE; + } + + return 16*(numBlocks + 1); +} + +int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputLen, BYTE *outBuffer) { + int i, k, numBlocks; + word8 block[16], iv[4][4]; + + if (cipher == NULL || + key == NULL || + (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) { + return BAD_CIPHER_STATE; + } + if (input == NULL || inputLen <= 0) { + return 0; /* nothing to do */ + } + + numBlocks = inputLen/128; + + switch (cipher->mode) { + case MODE_ECB: + for (i = numBlocks; i > 0; i--) { + rijndaelDecrypt(input, outBuffer, key->keySched, key->ROUNDS); + input += 16; + outBuffer += 16; + } + break; + + case MODE_CBC: +#if 1 /*STRICT_ALIGN */ + bcopy(cipher->IV, iv, 16); +#else + *((word32*)iv[0]) = *((word32*)(cipher->IV )); + *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4)); + *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8)); + *((word32*)iv[3]) = *((word32*)(cipher->IV+12)); +#endif + for (i = numBlocks; i > 0; i--) { + rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); + ((word32*)block)[0] ^= *((word32*)iv[0]); + ((word32*)block)[1] ^= *((word32*)iv[1]); + ((word32*)block)[2] ^= *((word32*)iv[2]); + ((word32*)block)[3] ^= *((word32*)iv[3]); +#if 1 /*STRICT_ALIGN*/ + bcopy(input, iv, 16); + bcopy(block, outBuffer, 16); +#else + *((word32*)iv[0]) = ((word32*)input)[0]; ((word32*)outBuffer)[0] = ((word32*)block)[0]; + *((word32*)iv[1]) = ((word32*)input)[1]; ((word32*)outBuffer)[1] = ((word32*)block)[1]; + *((word32*)iv[2]) = ((word32*)input)[2]; ((word32*)outBuffer)[2] = ((word32*)block)[2]; + *((word32*)iv[3]) = ((word32*)input)[3]; ((word32*)outBuffer)[3] = ((word32*)block)[3]; +#endif + input += 16; + outBuffer += 16; + } + break; + + case MODE_CFB1: +#if 1 /*STRICT_ALIGN */ + bcopy(cipher->IV, iv, 16); +#else + *((word32*)iv[0]) = *((word32*)(cipher->IV)); + *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4)); + *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8)); + *((word32*)iv[3]) = *((word32*)(cipher->IV+12)); +#endif + for (i = numBlocks; i > 0; i--) { + for (k = 0; k < 128; k++) { + *((word32*) block ) = *((word32*)iv[0]); + *((word32*)(block+ 4)) = *((word32*)iv[1]); + *((word32*)(block+ 8)) = *((word32*)iv[2]); + *((word32*)(block+12)) = *((word32*)iv[3]); + rijndaelEncrypt(block, block, key->keySched, key->ROUNDS); + iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); + iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); + iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); + iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); + iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); + iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); + iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); + iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); + iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); + iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); + iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); + iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); + iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); + iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); + iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); + iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1); + outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); + } + } + break; + + default: + return BAD_CIPHER_STATE; + } + + return 128*numBlocks; +} + +int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputOctets, BYTE *outBuffer) { + int i, numBlocks, padLen; + word8 block[16]; + word32 iv[4]; + + if (cipher == NULL || + key == NULL || + key->direction == DIR_ENCRYPT) { + return BAD_CIPHER_STATE; + } + if (input == NULL || inputOctets <= 0) { + return 0; /* nothing to do */ + } + if (inputOctets % 16 != 0) { + return BAD_DATA; + } + + numBlocks = inputOctets/16; + + switch (cipher->mode) { + case MODE_ECB: + /* all blocks but last */ + for (i = numBlocks - 1; i > 0; i--) { + rijndaelDecrypt(input, outBuffer, key->keySched, key->ROUNDS); + input += 16; + outBuffer += 16; + } + /* last block */ + rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); + padLen = block[15]; + if (padLen >= 16) { + return BAD_DATA; + } + for (i = 16 - padLen; i < 16; i++) { + if (block[i] != padLen) { + return BAD_DATA; + } + } + bcopy(block, outBuffer, 16 - padLen); + break; + + case MODE_CBC: + bcopy(cipher->IV, iv, 16); + /* all blocks but last */ + for (i = numBlocks - 1; i > 0; i--) { + rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); + ((word32*)block)[0] ^= iv[0]; + ((word32*)block)[1] ^= iv[1]; + ((word32*)block)[2] ^= iv[2]; + ((word32*)block)[3] ^= iv[3]; + bcopy(input, iv, 16); + bcopy(block, outBuffer, 16); + input += 16; + outBuffer += 16; + } + /* last block */ + rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); + ((word32*)block)[0] ^= iv[0]; + ((word32*)block)[1] ^= iv[1]; + ((word32*)block)[2] ^= iv[2]; + ((word32*)block)[3] ^= iv[3]; + padLen = block[15]; + if (padLen <= 0 || padLen > 16) { + return BAD_DATA; + } + for (i = 16 - padLen; i < 16; i++) { + if (block[i] != padLen) { + return BAD_DATA; + } + } + bcopy(block, outBuffer, 16 - padLen); + break; + + default: + return BAD_CIPHER_STATE; + } + + return 16*numBlocks - padLen; +} + +#ifdef INTERMEDIATE_VALUE_KAT +/** + * cipherUpdateRounds: + * + * Encrypts/Decrypts exactly one full block a specified number of rounds. + * Only used in the Intermediate Value Known Answer Test. + * + * Returns: + * TRUE - on success + * BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized) + */ +int rijndael_cipherUpdateRounds(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputLen, BYTE *outBuffer, int rounds) { + int j; + word8 block[4][4]; + + if (cipher == NULL || key == NULL) { + return BAD_CIPHER_STATE; + } + + for (j = 3; j >= 0; j--) { + /* parse input stream into rectangular array */ + *((word32*)block[j]) = *((word32*)(input+4*j)); + } + + switch (key->direction) { + case DIR_ENCRYPT: + rijndaelEncryptRound(block, key->keySched, key->ROUNDS, rounds); + break; + + case DIR_DECRYPT: + rijndaelDecryptRound(block, key->keySched, key->ROUNDS, rounds); + break; + + default: + return BAD_KEY_DIR; + } + + for (j = 3; j >= 0; j--) { + /* parse rectangular array into output ciphertext bytes */ + *((word32*)(outBuffer+4*j)) = *((word32*)block[j]); + } + + return TRUE; +} +#endif /* INTERMEDIATE_VALUE_KAT */ diff --git a/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-api-fst.h b/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-api-fst.h new file mode 100644 index 00000000..1d76a210 --- /dev/null +++ b/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael-api-fst.h @@ -0,0 +1,105 @@ +/* $NetBSD: rijndael-api-fst.h,v 1.4 2006/09/09 16:22:36 manu Exp $ */ + +/* $KAME: rijndael-api-fst.h,v 1.1.1.1 2001/08/08 09:56:27 sakane Exp $ */ + +/* + * rijndael-api-fst.h v2.3 April '2000 + * + * Optimised ANSI C code + * + * #define INTERMEDIATE_VALUE_KAT to generate the Intermediate Value Known Answer Test. + */ + +#ifndef __RIJNDAEL_API_FST_H +#define __RIJNDAEL_API_FST_H + +#include + +/* Defines: + Add any additional defines you need +*/ + +#define DIR_ENCRYPT 0 /* Are we encrpyting? */ +#define DIR_DECRYPT 1 /* Are we decrpyting? */ +#define MODE_ECB 1 /* Are we ciphering in ECB mode? */ +#define MODE_CBC 2 /* Are we ciphering in CBC mode? */ +#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */ +#define TRUE 1 +#define FALSE 0 +#define BITSPERBLOCK 128 /* Default number of bits in a cipher block */ + +/* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */ +#define BAD_KEY_DIR -1 /* Key direction is invalid, e.g., unknown value */ +#define BAD_KEY_MAT -2 /* Key material not of correct length */ +#define BAD_KEY_INSTANCE -3 /* Key passed is not valid */ +#define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */ +#define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */ +#define BAD_BLOCK_LENGTH -6 +#define BAD_CIPHER_INSTANCE -7 +#define BAD_DATA -8 /* Data contents are invalid, e.g., invalid padding */ +#define BAD_OTHER -9 /* Unknown error */ + +/* CHANGE POSSIBLE: inclusion of algorithm specific defines */ +#define MAX_KEY_SIZE 64 /* # of ASCII char's needed to represent a key */ +#define MAX_IV_SIZE 16 /* # bytes needed to represent an IV */ + +/* Typedefs: + + Typedef'ed data storage elements. Add any algorithm specific +parameters at the bottom of the structs as appropriate. +*/ + +/* The structure for key information */ +typedef struct { + u_int8_t direction; /* Key used for encrypting or decrypting? */ + int keyLen; /* Length of the key */ + char keyMaterial[MAX_KEY_SIZE+1]; /* Raw key data in ASCII, e.g., user input or KAT values */ + /* The following parameters are algorithm dependent, replace or add as necessary */ + int ROUNDS; /* key-length-dependent number of rounds */ + int blockLen; /* block length */ + union { + u_int8_t xkS8[RIJNDAEL_MAXROUNDS+1][4][4]; /* key schedule */ + u_int32_t xkS32[RIJNDAEL_MAXROUNDS+1][4]; /* key schedule */ + } xKeySched; +#define keySched xKeySched.xkS8 +} keyInstance; + +/* The structure for cipher information */ +typedef struct { /* changed order of the components */ + u_int8_t mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */ + u_int8_t IV[MAX_IV_SIZE]; /* A possible Initialization Vector for ciphering */ + /* Add any algorithm specific parameters needed here */ + int blockLen; /* Sample: Handles non-128 bit block sizes (if available) */ +} cipherInstance; + +/* Function prototypes */ +/* CHANGED: nothing + TODO: implement the following extensions to setup 192-bit and 256-bit block lengths: + makeKeyEx(): parameter blockLen added + -- this parameter is absolutely necessary if you want to + setup the round keys in a variable block length setting + cipherInitEx(): parameter blockLen added (for obvious reasons) + */ + +int rijndael_makeKey(keyInstance *key, u_int8_t direction, int keyLen, char *keyMaterial); + +int rijndael_cipherInit(cipherInstance *cipher, u_int8_t mode, char *IV); + +int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key, + u_int8_t *input, int inputLen, u_int8_t *outBuffer); + +int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key, + u_int8_t *input, int inputOctets, u_int8_t *outBuffer); + +int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key, + u_int8_t *input, int inputLen, u_int8_t *outBuffer); + +int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key, + u_int8_t *input, int inputOctets, u_int8_t *outBuffer); + +#ifdef INTERMEDIATE_VALUE_KAT +int rijndael_cipherUpdateRounds(cipherInstance *cipher, keyInstance *key, + u_int8_t *input, int inputLen, u_int8_t *outBuffer, int Rounds); +#endif /* INTERMEDIATE_VALUE_KAT */ + +#endif /* __RIJNDAEL_API_FST_H */ diff --git a/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael.h b/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael.h new file mode 100644 index 00000000..59c30777 --- /dev/null +++ b/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael.h @@ -0,0 +1,5 @@ +/* $NetBSD: rijndael.h,v 1.4 2006/09/09 16:22:36 manu Exp $ */ + +/* $KAME: rijndael.h,v 1.1.1.1 2001/08/08 09:56:27 sakane Exp $ */ + +#include diff --git a/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael_local.h b/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael_local.h new file mode 100644 index 00000000..e4463784 --- /dev/null +++ b/ipsec-tools/src/racoon/missing/crypto/rijndael/rijndael_local.h @@ -0,0 +1,12 @@ +/* $NetBSD: rijndael_local.h,v 1.4 2006/09/09 16:22:36 manu Exp $ */ + +/* $KAME: rijndael_local.h,v 1.1.1.1 2001/08/08 09:56:27 sakane Exp $ */ + +/* the file should not be used from outside */ +typedef u_int8_t BYTE; +typedef u_int8_t word8; +typedef u_int16_t word16; +typedef u_int32_t word32; + +#define MAXKC RIJNDAEL_MAXKC +#define MAXROUNDS RIJNDAEL_MAXROUNDS diff --git a/ipsec-tools/src/racoon/missing/crypto/sha2/sha2.c b/ipsec-tools/src/racoon/missing/crypto/sha2/sha2.c new file mode 100644 index 00000000..099cdb89 --- /dev/null +++ b/ipsec-tools/src/racoon/missing/crypto/sha2/sha2.c @@ -0,0 +1,1199 @@ +/* $NetBSD: sha2.c,v 1.4.40.1 2012/12/24 08:48:08 tteras Exp $ */ + +/* Id: sha2.c,v 1.6 2004/09/21 14:35:25 ludvigm Exp */ + +/* + * sha2.c + * + * Version 1.0.0beta1 + * + * Written by Aaron D. Gifford + * + * Copyright 2000 Aaron D. Gifford. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include "config.h" + +#include +#include +#ifndef __linux__ +#include +#endif +#include +#include + +/* get openssl/ssleay version number */ +#include + +#include +#include +#define bcopy(a, b, c) memcpy((b), (a), (c)) +#define bzero(a, b) memset((a), 0, (b)) +#define panic(a) err(1, (a)) + +#define HAVE_EVP_097 + +/* + * ASSERT NOTE: + * Some sanity checking code is included using assert(). On my FreeBSD + * system, this additional code can be removed by compiling with NDEBUG + * defined. Check your own systems manpage on assert() to see how to + * compile WITHOUT the sanity checking code on your system. + * + * UNROLLED TRANSFORM LOOP NOTE: + * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform + * loop version for the hash transform rounds (defined using macros + * later in this file). Either define on the command line, for example: + * + * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c + * + * or define below: + * + * #define SHA2_UNROLL_TRANSFORM + * + */ + +#define assert(x) + + +/*** SHA-256/384/512 Machine Architecture Definitions *****************/ +/* + * BYTE_ORDER NOTE: + * + * Please make sure that your system defines BYTE_ORDER. If your + * architecture is little-endian, make sure it also defines + * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are + * equivilent. + * + * If your system does not define the above, then you can do so by + * hand like this: + * + * #define LITTLE_ENDIAN 1234 + * #define BIG_ENDIAN 4321 + * + * And for little-endian machines, add: + * + * #define BYTE_ORDER LITTLE_ENDIAN + * + * Or for big-endian machines: + * + * #define BYTE_ORDER BIG_ENDIAN + * + * The FreeBSD machine this was written on defines BYTE_ORDER + * appropriately by including (which in turn includes + * where the appropriate definitions are actually + * made). + */ +#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) +#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN +#endif + +/* + * Define the followingsha2_* types to types of the correct length on + * the native archtecture. Most BSD systems and Linux define u_intXX_t + * types. Machines with very recent ANSI C headers, can use the + * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H + * during compile or in the sha.h header file. + * + * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t + * will need to define these three typedefs below (and the appropriate + * ones in sha.h too) by hand according to their system architecture. + * + * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t + * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. + */ +#if 0 /*def SHA2_USE_INTTYPES_H*/ + +typedef uint8_t sha2_byte; /* Exactly 1 byte */ +typedef uint32_t sha2_word32; /* Exactly 4 bytes */ +typedef uint64_t sha2_word64; /* Exactly 8 bytes */ + +#else /* SHA2_USE_INTTYPES_H */ + +typedef u_int8_t sha2_byte; /* Exactly 1 byte */ +typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ +typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ + +#endif /* SHA2_USE_INTTYPES_H */ + + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +/* NOTE: Most of these are in sha2.h */ +#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) +#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) +#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) + + +/*** ENDIAN REVERSAL MACROS *******************************************/ +#if BYTE_ORDER == LITTLE_ENDIAN +#define REVERSE32(w,x) { \ + sha2_word32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ +} +#define REVERSE64(w,x) { \ + sha2_word64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ + ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ + (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ + ((tmp & 0x0000ffff0000ffffULL) << 16); \ +} +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +/* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ +#define ADDINC128(w,n) { \ + (w)[0] += (sha2_word64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ +} + +/*** THE SIX LOGICAL FUNCTIONS ****************************************/ +/* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + * NOTE: The naming of R and S appears backwards here (R is a SHIFT and + * S is a ROTATION) because the SHA-256/384/512 description document + * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this + * same "backwards" definition. + */ +/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ +#define R(b,x) ((x) >> (b)) +/* 32-bit Rotate-right (used in SHA-256): */ +#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) +/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ +#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) + +/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +/* Four of six logical functions used in SHA-256: */ +#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) +#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) +#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) +#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) + +/* Four of six logical functions used in SHA-384 and SHA-512: */ +#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) +#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) +#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) +#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) + +/*** INTERNAL FUNCTION PROTOTYPES *************************************/ +/* NOTE: These should not be accessed directly from outside this + * library -- they are intended for private internal visibility/use + * only. + */ +void SHA512_Last(SHA512_CTX*); +void SHA256_Transform(SHA256_CTX*, const sha2_word32*); +void SHA512_Transform(SHA512_CTX*, const sha2_word64*); + + +/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ +/* Hash constant words K for SHA-256: */ +const static sha2_word32 K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Initial hash value H for SHA-256: */ +const static sha2_word32 sha256_initial_hash_value[8] = { + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL +}; + +/* Hash constant words K for SHA-384 and SHA-512: */ +const static sha2_word64 K512[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, + 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, + 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, + 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, + 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, + 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, + 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, + 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, + 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, + 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, + 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, + 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, + 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, + 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +/* Initial hash value H for SHA-384 */ +const static sha2_word64 sha384_initial_hash_value[8] = { + 0xcbbb9d5dc1059ed8ULL, + 0x629a292a367cd507ULL, + 0x9159015a3070dd17ULL, + 0x152fecd8f70e5939ULL, + 0x67332667ffc00b31ULL, + 0x8eb44a8768581511ULL, + 0xdb0c2e0d64f98fa7ULL, + 0x47b5481dbefa4fa4ULL +}; + +/* Initial hash value H for SHA-512 */ +const static sha2_word64 sha512_initial_hash_value[8] = { + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL +}; + +/* + * Constant used by SHA256/384/512_End() functions for converting the + * digest to a readable hexadecimal character string: + */ +static const char *sha2_hex_digits = "0123456789abcdef"; + + +/*** SHA-256: *********************************************************/ +void SHA256_Init(SHA256_CTX* context) { + if (context == (SHA256_CTX*)0) { + return; + } + bcopy(sha256_initial_hash_value, context->state, SHA256_DIGEST_LENGTH); + bzero(context->buffer, SHA256_BLOCK_LENGTH); + context->bitcount = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-256 round macros: */ + +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE32(*data++, W256[j]); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + W256[j]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256(a,b,c,d,e,f,g,h) \ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, T2, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Copy data while converting to host byte order */ + REVERSE32(*data++,W256[j]); + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-256 compression function to update a..h with copy */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j+1)&0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j+14)&0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + bcopy(data, &context->buffer[usedspace], freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Transform(context, (sha2_word32*)context->buffer); + } else { + /* The buffer is not yet full */ + bcopy(data, &context->buffer[usedspace], len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA256_Transform(context, (const sha2_word32*)data); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + bcopy(data, context->buffer, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { + sha2_word32 *d = (sha2_word32*)digest; + unsigned int usedspace; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount,context->bitcount); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + bzero(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA256_BLOCK_LENGTH) { + bzero(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + + /* And set-up for the last transform: */ + bzero(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + } + } else { + /* Set-up for the last transform: */ + bzero(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Set the bit count: */ + *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; + + /* Final transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE32(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + bcopy(context->state, d, SHA256_DIGEST_LENGTH); +#endif + } + + /* Clean up state data: */ + bzero(context, sizeof(*context)); + usedspace = 0; +} + +char *SHA256_End(SHA256_CTX* context, char buffer[]) { + sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + if (buffer != (char*)0) { + SHA256_Final(digest, context); + + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + bzero(context, sizeof(*context)); + } + bzero(digest, SHA256_DIGEST_LENGTH); + return buffer; +} + +char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { + SHA256_CTX context; + + SHA256_Init(&context); + SHA256_Update(&context, data, len); + return SHA256_End(&context, digest); +} + + +/*** SHA-512: *********************************************************/ +void SHA512_Init(SHA512_CTX* context) { + if (context == (SHA512_CTX*)0) { + return; + } + bcopy(sha512_initial_hash_value, context->state, SHA512_DIGEST_LENGTH); + bzero(context->buffer, SHA512_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-512 round macros: */ +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE64(*data++, W512[j]); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + W512[j]; \ + (d) += T1, \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + (W512[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512(a,b,c,d,e,f,g,h) \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + REVERSE64(*data++, W512[j]); + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-512 compression function to update a..h with copy */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j+1)&0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j+14)&0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA512_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + bcopy(data, &context->buffer[usedspace], freespace); + ADDINC128(context->bitcount, freespace << 3); + len -= freespace; + data += freespace; + SHA512_Transform(context, (sha2_word64*)context->buffer); + } else { + /* The buffer is not yet full */ + bcopy(data, &context->buffer[usedspace], len); + ADDINC128(context->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA512_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA512_Transform(context, (const sha2_word64*)data); + ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); + len -= SHA512_BLOCK_LENGTH; + data += SHA512_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + bcopy(data, context->buffer, len); + ADDINC128(context->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA512_Last(SHA512_CTX* context) { + unsigned int usedspace; + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount[0],context->bitcount[0]); + REVERSE64(context->bitcount[1],context->bitcount[1]); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + bzero(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA512_BLOCK_LENGTH) { + bzero(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); + + /* And set-up for the last transform: */ + bzero(context->buffer, SHA512_BLOCK_LENGTH - 2); + } + } else { + /* Prepare for final transform: */ + bzero(context->buffer, SHA512_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Store the length of input data (in bits): */ + *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; + *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; + + /* Final transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); +} + +void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last(context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + bcopy(context->state, d, SHA512_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + bzero(context, sizeof(*context)); +} + +char *SHA512_End(SHA512_CTX* context, char buffer[]) { + sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + if (buffer != (char*)0) { + SHA512_Final(digest, context); + + for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + bzero(context, sizeof(*context)); + } + bzero(digest, SHA512_DIGEST_LENGTH); + return buffer; +} + +char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { + SHA512_CTX context; + + SHA512_Init(&context); + SHA512_Update(&context, data, len); + return SHA512_End(&context, digest); +} + + +/*** SHA-384: *********************************************************/ +void SHA384_Init(SHA384_CTX* context) { + if (context == (SHA384_CTX*)0) { + return; + } + bcopy(sha384_initial_hash_value, context->state, SHA512_DIGEST_LENGTH); + bzero(context->buffer, SHA384_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { + SHA512_Update((SHA512_CTX*)context, data, len); +} + +void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last((SHA512_CTX*)context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 6; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + bcopy(context->state, d, SHA384_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + bzero(context, sizeof(*context)); +} + +char *SHA384_End(SHA384_CTX* context, char buffer[]) { + sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + if (buffer != (char*)0) { + SHA384_Final(digest, context); + + for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + bzero(context, sizeof(*context)); + } + bzero(digest, SHA384_DIGEST_LENGTH); + return buffer; +} + +char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { + SHA384_CTX context; + + SHA384_Init(&context); + SHA384_Update(&context, data, len); + return SHA384_End(&context, digest); +} + +/*glue*/ +#ifdef HAVE_EVP_097 + +/* SHA256 */ +#define data(ctx) ((SHA256_CTX *)(ctx)->md_data) +static int sha256_init(EVP_MD_CTX *ctx) +{ + SHA256_Init(data(ctx)); + return 1; +} +static int sha256_update(EVP_MD_CTX *ctx, const void *data, unsigned long count) +{ + SHA256_Update(data(ctx), data, count); + return 1; +} +static int sha256_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + SHA256_Final(md, data(ctx)); + return 1; +} +#undef data + +/* SHA384 */ +#define data(ctx) ((SHA384_CTX *)(ctx)->md_data) +static int sha384_init(EVP_MD_CTX *ctx) +{ + SHA384_Init(data(ctx)); + return 1; +} +static int sha384_update(EVP_MD_CTX *ctx, const void *data, unsigned long count) +{ + SHA384_Update(data(ctx), data, count); + return 1; +} +static int sha384_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + SHA384_Final(md, data(ctx)); + return 1; +} +#undef data + +/* SHA512 */ +#define data(ctx) ((SHA512_CTX *)(ctx)->md_data) +static int sha512_init(EVP_MD_CTX *ctx) +{ + SHA512_Init(data(ctx)); + return 1; +} +static int sha512_update(EVP_MD_CTX *ctx, const void *data, unsigned long count) +{ + SHA512_Update(data(ctx), data, count); + return 1; +} +static int sha512_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + SHA512_Final(md, data(ctx)); + return 1; +} +#undef data +#endif + +static struct env_md_st sha2_256_md = { + 0, /*NID_sha1*/ + 0, /*NID_sha1WithRSAEncryption*/ + SHA256_DIGEST_LENGTH, +#ifdef HAVE_EVP_097 + 0, /* flags */ + sha256_init, + sha256_update, + sha256_final, + NULL, /* copy */ + NULL, /* cleanup */ +#else + SHA256_Init, + SHA256_Update, + SHA256_Final, +#endif + NULL, NULL, {0, 0, 0, 0}, + SHA256_BLOCK_LENGTH, + sizeof(struct env_md_st *) + sizeof(SHA256_CTX), +}; + +struct env_md_st *EVP_sha2_256(void) +{ + return(&sha2_256_md); +} + +static struct env_md_st sha2_384_md = { + 0, /*NID_sha1*/ + 0, /*NID_sha1WithRSAEncryption*/ + SHA384_DIGEST_LENGTH, +#ifdef HAVE_EVP_097 + 0, /* flags */ + sha384_init, + sha384_update, + sha384_final, + NULL, /* copy */ + NULL, /* cleanup */ +#else + SHA384_Init, + SHA384_Update, + SHA384_Final, +#endif + NULL, NULL, {0, 0, 0, 0}, + SHA384_BLOCK_LENGTH, + sizeof(struct env_md_st *) + sizeof(SHA384_CTX), +}; + +struct env_md_st *EVP_sha2_384(void) +{ + return(&sha2_384_md); +} + +static struct env_md_st sha2_512_md = { + 0, /*NID_sha1*/ + 0, /*NID_sha1WithRSAEncryption*/ + SHA512_DIGEST_LENGTH, +#ifdef HAVE_EVP_097 + 0, /* flags */ + sha512_init, + sha512_update, + sha512_final, + NULL, /* copy */ + NULL, /* cleanup */ +#else + SHA512_Init, + SHA512_Update, + SHA512_Final, +#endif + NULL, NULL, {0, 0, 0, 0}, /*EVP_PKEY_RSA_method*/ + SHA512_BLOCK_LENGTH, + sizeof(struct env_md_st *) + sizeof(SHA512_CTX), +}; + +struct env_md_st *EVP_sha2_512(void) +{ + return(&sha2_512_md); +} diff --git a/ipsec-tools/src/racoon/missing/crypto/sha2/sha2.h b/ipsec-tools/src/racoon/missing/crypto/sha2/sha2.h new file mode 100644 index 00000000..42bcc2a3 --- /dev/null +++ b/ipsec-tools/src/racoon/missing/crypto/sha2/sha2.h @@ -0,0 +1,161 @@ +/* $NetBSD: sha2.h,v 1.4 2006/09/09 16:22:36 manu Exp $ */ + +/* $KAME: sha2.h,v 1.2 2001/08/08 22:09:27 sakane Exp $ */ + +/* + * sha2.h + * + * Version 1.0.0beta1 + * + * Written by Aaron D. Gifford + * + * Copyright 2000 Aaron D. Gifford. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef __SHA2_H__ +#define __SHA2_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA384_BLOCK_LENGTH 128 +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) +#define SHA512_BLOCK_LENGTH 128 +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) + + +/*** SHA-256/384/512 Context Structures *******************************/ +/* NOTE: If your architecture does not define either u_intXX_t types or + * uintXX_t (from inttypes.h), you may need to define things by hand + * for your system: + */ +#if 0 +typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ +typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ +typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ +#endif + +#ifndef HAVE_SHA2_IN_SHA_H +/* + * Most BSD systems already define u_intXX_t types, as does Linux. + * Some systems, however, like Compaq's Tru64 Unix instead can use + * uintXX_t types defined by very recent ANSI C standards and included + * in the file: + * + * #include + * + * If you choose to use then please define: + * + * #define SHA2_USE_INTTYPES_H + * + * Or on the command line during compile: + * + * cc -DSHA2_USE_INTTYPES_H ... + */ +#if 0 /*def SHA2_USE_INTTYPES_H*/ + +typedef struct _SHA256_CTX { + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + uint64_t state[8]; + uint64_t bitcount[2]; + uint8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +#else /* SHA2_USE_INTTYPES_H */ + +typedef struct _SHA256_CTX { + u_int32_t state[8]; + u_int64_t bitcount; + u_int8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + u_int64_t state[8]; + u_int64_t bitcount[2]; + u_int8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +#endif /* SHA2_USE_INTTYPES_H */ +#endif /* HAVE_SHA2_IN_SHA_H */ + +typedef SHA512_CTX SHA384_CTX; + + +/*** SHA-256/384/512 Function Prototypes ******************************/ + +#ifndef HAVE_SHA2_IN_SHA_H +void SHA256_Init __P((SHA256_CTX *)); +void SHA256_Update __P((SHA256_CTX*, const u_int8_t*, size_t)); +void SHA256_Final __P((u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*)); +#endif /* HAVE_SHA2_IN_SHA_H */ +char* SHA256_End __P((SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH])); +char* SHA256_Data __P((const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH])); + +#ifndef HAVE_SHA2_IN_SHA_H +void SHA384_Init __P((SHA384_CTX*)); +void SHA384_Update __P((SHA384_CTX*, const u_int8_t*, size_t)); +void SHA384_Final __P((u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*)); +#endif /* HAVE_SHA2_IN_SHA_H */ +char* SHA384_End __P((SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH])); +char* SHA384_Data __P((const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH])); + +#ifndef HAVE_SHA2_IN_SHA_H +void SHA512_Init __P((SHA512_CTX*)); +void SHA512_Update __P((SHA512_CTX*, const u_int8_t*, size_t)); +void SHA512_Final __P((u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*)); +#endif /* HAVE_SHA2_IN_SHA_H */ +char* SHA512_End __P((SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH])); +char* SHA512_Data __P((const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH])); + +struct env_md_st *EVP_sha2_256 __P((void)); +struct env_md_st *EVP_sha2_384 __P((void)); +struct env_md_st *EVP_sha2_512 __P((void)); + +#ifdef HAVE_SHA2_IN_SHA_H +#define EVP_sha2_256 EVP_sha256 +#define EVP_sha2_384 EVP_sha384 +#define EVP_sha2_512 EVP_sha512 +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __SHA2_H__ */ + diff --git a/ipsec-tools/src/racoon/nattraversal.c b/ipsec-tools/src/racoon/nattraversal.c new file mode 100644 index 00000000..b04cc1b5 --- /dev/null +++ b/ipsec-tools/src/racoon/nattraversal.c @@ -0,0 +1,553 @@ +/* $NetBSD: nattraversal.c,v 1.14 2011/03/14 17:18:13 tteras Exp $ */ + +/* + * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. + * Contributed by: Michal Ludvig , SUSE Labs + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include + +#ifdef __linux__ +#include +#endif +#if defined(__NetBSD__) || defined (__FreeBSD__) +#include +#endif + +#include +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "debug.h" + +#include "localconf.h" +#include "remoteconf.h" +#include "sockmisc.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "oakley.h" +#include "ipsec_doi.h" +#include "vendorid.h" +#include "handler.h" +#include "crypto_openssl.h" +#include "schedule.h" +#include "nattraversal.h" +#include "grabmyaddr.h" + +struct natt_ka_addrs { + struct sockaddr *src; + struct sockaddr *dst; + unsigned in_use; + + TAILQ_ENTRY(natt_ka_addrs) chain; +}; + +static TAILQ_HEAD(_natt_ka_addrs, natt_ka_addrs) ka_tree; +static struct sched sc_natt = SCHED_INITIALIZER(); + +/* + * check if the given vid is NAT-T. + */ +int +natt_vendorid (int vid) +{ + return ( +#ifdef ENABLE_NATT_00 + vid == VENDORID_NATT_00 || +#endif +#ifdef ENABLE_NATT_01 + vid == VENDORID_NATT_01 || +#endif +#ifdef ENABLE_NATT_02 + vid == VENDORID_NATT_02 || + vid == VENDORID_NATT_02_N || +#endif +#ifdef ENABLE_NATT_03 + vid == VENDORID_NATT_03 || +#endif +#ifdef ENABLE_NATT_04 + vid == VENDORID_NATT_04 || +#endif +#ifdef ENABLE_NATT_05 + vid == VENDORID_NATT_05 || +#endif +#ifdef ENABLE_NATT_06 + vid == VENDORID_NATT_06 || +#endif +#ifdef ENABLE_NATT_07 + vid == VENDORID_NATT_07 || +#endif +#ifdef ENABLE_NATT_08 + vid == VENDORID_NATT_08 || +#endif + /* Always enable NATT RFC if ENABLE_NATT + */ + vid == VENDORID_NATT_RFC); +} + +vchar_t * +natt_hash_addr (struct ph1handle *iph1, struct sockaddr *addr) +{ + vchar_t *natd; + vchar_t *buf; + char *ptr; + void *addr_ptr, *addr_port; + size_t buf_size, addr_size; + int natt_force = 0; + + if (iph1->rmconf != NULL && iph1->rmconf->nat_traversal == NATT_FORCE) + natt_force = 1; + + plog (LLV_INFO, LOCATION, addr, "Hashing %s with algo #%d %s\n", + saddr2str(addr), iph1->approval->hashtype, + natt_force?"(NAT-T forced)":""); + + if (addr->sa_family == AF_INET) { + addr_size = sizeof (struct in_addr); /* IPv4 address */ + addr_ptr = &((struct sockaddr_in *)addr)->sin_addr; + addr_port = &((struct sockaddr_in *)addr)->sin_port; + } + else if (addr->sa_family == AF_INET6) { + addr_size = sizeof (struct in6_addr); /* IPv6 address */ + addr_ptr = &((struct sockaddr_in6 *)addr)->sin6_addr; + addr_port = &((struct sockaddr_in6 *)addr)->sin6_port; + } + else { + plog (LLV_ERROR, LOCATION, addr, "Unsupported address family #0x%x\n", addr->sa_family); + return NULL; + } + + buf_size = 2 * sizeof (cookie_t); /* CKY-I + CKY+R */ + buf_size += addr_size + 2; /* Address + Port */ + + if ((buf = vmalloc (buf_size)) == NULL) + return NULL; + + ptr = buf->v; + + /* Copy-in CKY-I */ + memcpy (ptr, iph1->index.i_ck, sizeof (cookie_t)); + ptr += sizeof (cookie_t); + + /* Copy-in CKY-I */ + memcpy (ptr, iph1->index.r_ck, sizeof (cookie_t)); + ptr += sizeof (cookie_t); + + /* Copy-in Address (or zeroes if NATT_FORCE) */ + if (natt_force) + memset (ptr, 0, addr_size); + else + memcpy (ptr, addr_ptr, addr_size); + ptr += addr_size; + + /* Copy-in Port number */ + memcpy (ptr, addr_port, 2); + + natd = oakley_hash (buf, iph1); + vfree(buf); + + return natd; +} + +int +natt_compare_addr_hash (struct ph1handle *iph1, vchar_t *natd_received, + int natd_seq) +{ + vchar_t *natd_computed; + u_int32_t flag; + int verified = 0; + + if (iph1->rmconf != NULL && + iph1->rmconf->nat_traversal == NATT_FORCE) + return verified; + + if (natd_seq == 0) { + natd_computed = natt_hash_addr (iph1, iph1->local); + flag = NAT_DETECTED_ME; + } + else { + natd_computed = natt_hash_addr (iph1, iph1->remote); + flag = NAT_DETECTED_PEER; + } + + if (natd_computed == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "natd_computed allocation failed\n"); + return verified; /* XXX should abort */ + } + + if (natd_received->l == natd_computed->l && + memcmp (natd_received->v, natd_computed->v, natd_received->l) == 0) { + iph1->natt_flags &= ~flag; + verified = 1; + } + + vfree (natd_computed); + + return verified; +} + +int +natt_udp_encap (int encmode) +{ + return (encmode == IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC || + encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC || + encmode == IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT || + encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT); +} + +int +natt_fill_options (struct ph1natt_options *opts, int version) +{ + if (! opts) + return -1; + + opts->version = version; + + switch (version) { + case VENDORID_NATT_00: + case VENDORID_NATT_01: + opts->float_port = 0; /* No port floating for those drafts */ + opts->payload_nat_d = ISAKMP_NPTYPE_NATD_DRAFT; + opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_DRAFT; + opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT; + opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT; + opts->encaps_type = UDP_ENCAP_ESPINUDP_NON_IKE; + break; + + case VENDORID_NATT_02: + case VENDORID_NATT_02_N: + case VENDORID_NATT_03: + opts->float_port = lcconf->port_isakmp_natt; + opts->payload_nat_d = ISAKMP_NPTYPE_NATD_DRAFT; + opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_DRAFT; + opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT; + opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT; + opts->encaps_type = UDP_ENCAP_ESPINUDP; + break; + case VENDORID_NATT_04: + case VENDORID_NATT_05: + case VENDORID_NATT_06: + case VENDORID_NATT_07: + case VENDORID_NATT_08: + opts->float_port = lcconf->port_isakmp_natt; + opts->payload_nat_d = ISAKMP_NPTYPE_NATD_BADDRAFT; + opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_BADDRAFT; + opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC; + opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC; + opts->encaps_type = UDP_ENCAP_ESPINUDP; + break; + case VENDORID_NATT_RFC: + opts->float_port = lcconf->port_isakmp_natt; + opts->payload_nat_d = ISAKMP_NPTYPE_NATD_RFC; + opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_RFC; + opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC; + opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC; + opts->encaps_type = UDP_ENCAP_ESPINUDP; + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "unsupported NAT-T version: %s\n", + vid_string_by_id(version)); + return -1; + } + + opts->mode_udp_diff = opts->mode_udp_tunnel - IPSECDOI_ATTR_ENC_MODE_TUNNEL; + + return 0; +} + +void +natt_float_ports (struct ph1handle *iph1) +{ + if (! (iph1->natt_flags & NAT_DETECTED) ) + return; + if (! iph1->natt_options->float_port){ + /* Drafts 00 / 01, just schedule keepalive */ + natt_keepalive_add_ph1 (iph1); + return; + } + + set_port (iph1->local, iph1->natt_options->float_port); + set_port (iph1->remote, iph1->natt_options->float_port); + iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER; + + natt_keepalive_add_ph1 (iph1); +} + +static int +natt_is_enabled (struct remoteconf *rmconf, void *args) +{ + if (rmconf->nat_traversal) + return 1; + return 0; +} + +void +natt_handle_vendorid (struct ph1handle *iph1, int vid_numeric) +{ + if (iph1->rmconf == NULL) { + /* Check if any candidate remote conf allows nat-t */ + struct rmconfselector rmconf; + rmconf_selector_from_ph1(&rmconf, iph1); + if (enumrmconf(&rmconf, natt_is_enabled, NULL) == 0) + return; + } else { + if (!iph1->rmconf->nat_traversal) + return; + } + + if (! iph1->natt_options) + iph1->natt_options = racoon_calloc (1, sizeof (*iph1->natt_options)); + + if (! iph1->natt_options) { + plog (LLV_ERROR, LOCATION, NULL, + "Allocating memory for natt_options failed!\n"); + return; + } + + if (iph1->natt_options->version < vid_numeric) + if (natt_fill_options (iph1->natt_options, vid_numeric) == 0) + iph1->natt_flags |= NAT_ANNOUNCED; +} + +static void +natt_keepalive_delete (struct natt_ka_addrs *ka) +{ + TAILQ_REMOVE (&ka_tree, ka, chain); + racoon_free (ka->src); + racoon_free (ka->dst); + racoon_free (ka); +} + +/* NAT keepalive functions */ +static void +natt_keepalive_send (struct sched *param) +{ + struct natt_ka_addrs *ka, *next = NULL; + char keepalive_packet[] = { 0xff }; + size_t len; + int s; + + for (ka = TAILQ_FIRST(&ka_tree); ka; ka = next) { + next = TAILQ_NEXT(ka, chain); + + s = myaddr_getfd(ka->src); + if (s == -1) { + natt_keepalive_delete(ka); + continue; + } + plog (LLV_DEBUG, LOCATION, NULL, "KA: %s\n", + saddr2str_fromto("%s->%s", ka->src, ka->dst)); + len = sendfromto(s, keepalive_packet, sizeof (keepalive_packet), + ka->src, ka->dst, 1); + if (len == -1) + plog(LLV_ERROR, LOCATION, NULL, "KA: sendfromto failed: %s\n", + strerror (errno)); + } + + sched_schedule (&sc_natt, lcconf->natt_ka_interval, natt_keepalive_send); +} + +void +natt_keepalive_init (void) +{ + TAILQ_INIT(&ka_tree); + + /* To disable sending KAs set natt_ka_interval=0 */ + if (lcconf->natt_ka_interval > 0) + sched_schedule (&sc_natt, lcconf->natt_ka_interval, natt_keepalive_send); +} + +int +natt_keepalive_add (struct sockaddr *src, struct sockaddr *dst) +{ + struct natt_ka_addrs *ka = NULL, *new_addr; + + TAILQ_FOREACH (ka, &ka_tree, chain) { + if (cmpsaddr(ka->src, src) == CMPSADDR_MATCH && + cmpsaddr(ka->dst, dst) == CMPSADDR_MATCH) { + ka->in_use++; + plog (LLV_INFO, LOCATION, NULL, "KA found: %s (in_use=%u)\n", + saddr2str_fromto("%s->%s", src, dst), ka->in_use); + return 0; + } + } + + plog (LLV_INFO, LOCATION, NULL, "KA list add: %s\n", saddr2str_fromto("%s->%s", src, dst)); + + new_addr = (struct natt_ka_addrs *)racoon_malloc(sizeof(*new_addr)); + if (! new_addr) { + plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n"); + return -1; + } + + if ((new_addr->src = dupsaddr(src)) == NULL) { + racoon_free(new_addr); + plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n"); + return -1; + } + if ((new_addr->dst = dupsaddr(dst)) == NULL) { + racoon_free(new_addr); + plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n"); + return -1; + } + new_addr->in_use = 1; + TAILQ_INSERT_TAIL(&ka_tree, new_addr, chain); + + return 0; +} + +int +natt_keepalive_add_ph1 (struct ph1handle *iph1) +{ + int ret = 0; + + /* Should only the NATed host send keepalives? + If yes, add '(iph1->natt_flags & NAT_DETECTED_ME)' + to the following condition. */ + if (iph1->natt_flags & NAT_DETECTED && + ! (iph1->natt_flags & NAT_KA_QUEUED)) { + ret = natt_keepalive_add (iph1->local, iph1->remote); + if (ret == 0) + iph1->natt_flags |= NAT_KA_QUEUED; + } + + return ret; +} + +void +natt_keepalive_remove (struct sockaddr *src, struct sockaddr *dst) +{ + struct natt_ka_addrs *ka, *next = NULL; + + plog (LLV_INFO, LOCATION, NULL, "KA remove: %s\n", saddr2str_fromto("%s->%s", src, dst)); + + for (ka = TAILQ_FIRST(&ka_tree); ka; ka = next) { + next = TAILQ_NEXT(ka, chain); + + plog (LLV_DEBUG, LOCATION, NULL, "KA tree dump: %s (in_use=%u)\n", + saddr2str_fromto("%s->%s", src, dst), ka->in_use); + + if (cmpsaddr(ka->src, src) == CMPSADDR_MATCH && + cmpsaddr(ka->dst, dst) == CMPSADDR_MATCH && + -- ka->in_use <= 0) { + + plog (LLV_DEBUG, LOCATION, NULL, "KA removing this one...\n"); + + natt_keepalive_delete (ka); + /* Should we break here? Every pair of addresses should + be inserted only once, but who knows :-) Lets traverse + the whole list... */ + } + } +} + +static int +natt_enabled_in_rmconf_stub (struct remoteconf *rmconf, void *data) +{ + return rmconf->nat_traversal ? 1 : 0; +} + +int +natt_enabled_in_rmconf () +{ + return enumrmconf(NULL, natt_enabled_in_rmconf_stub, NULL) != 0; +} + + +struct payload_list * +isakmp_plist_append_natt_vids (struct payload_list *plist, vchar_t *vid_natt[MAX_NATT_VID_COUNT]){ + int i, vid_natt_i = 0; + + if(vid_natt == NULL) + return NULL; + + for (i = 0; i < MAX_NATT_VID_COUNT; i++) + vid_natt[i]=NULL; + + /* Puts the olders VIDs last, as some implementations may choose the first + * NATT VID given + */ + + /* Always set RFC VID + */ + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_RFC)) != NULL) + vid_natt_i++; +#ifdef ENABLE_NATT_08 + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_08)) != NULL) + vid_natt_i++; +#endif +#ifdef ENABLE_NATT_07 + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_07)) != NULL) + vid_natt_i++; +#endif +#ifdef ENABLE_NATT_06 + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_06)) != NULL) + vid_natt_i++; +#endif +#ifdef ENABLE_NATT_05 + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_05)) != NULL) + vid_natt_i++; +#endif +#ifdef ENABLE_NATT_04 + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_04)) != NULL) + vid_natt_i++; +#endif +#ifdef ENABLE_NATT_03 + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_03)) != NULL) + vid_natt_i++; +#endif +#ifdef ENABLE_NATT_02 + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02)) != NULL) + vid_natt_i++; + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02_N)) != NULL) + vid_natt_i++; +#endif +#ifdef ENABLE_NATT_01 + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_01)) != NULL) + vid_natt_i++; +#endif +#ifdef ENABLE_NATT_00 + if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_00)) != NULL) + vid_natt_i++; +#endif + /* set VID payload for NAT-T */ + for (i = 0; i < vid_natt_i; i++) + plist = isakmp_plist_append(plist, vid_natt[i], ISAKMP_NPTYPE_VID); + + return plist; +} diff --git a/ipsec-tools/src/racoon/nattraversal.h b/ipsec-tools/src/racoon/nattraversal.h new file mode 100644 index 00000000..3b0b03ba --- /dev/null +++ b/ipsec-tools/src/racoon/nattraversal.h @@ -0,0 +1,99 @@ +/* $NetBSD: nattraversal.h,v 1.7 2010/09/22 07:34:51 vanhu Exp $ */ + +/* + * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. + * Contributed by: Michal Ludvig , SUSE Labs + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _NATTRAVERSAL_H +#define _NATTRAVERSAL_H + +#include "vendorid.h" + +#define NAT_ANNOUNCED (1L<<0) +#define NAT_DETECTED_ME (1L<<1) +#define NAT_DETECTED_PEER (1L<<2) +#define NAT_PORTS_CHANGED (1L<<3) +#define NAT_KA_QUEUED (1L<<4) +#define NAT_ADD_NON_ESP_MARKER (1L<<5) + +#define NATT_AVAILABLE(_ph1) ((_ph1)->natt_flags & NAT_ANNOUNCED) + +#define NAT_DETECTED (NAT_DETECTED_ME | NAT_DETECTED_PEER) + +#define NON_ESP_MARKER_LEN sizeof(u_int32_t) +#define NON_ESP_MARKER_USE(_ph1) ((_ph1)->natt_flags & NAT_ADD_NON_ESP_MARKER) + +/* These are the values from parsing "remote {}" + block of the config file. */ +#define NATT_OFF FLASE /* = 0 */ +#define NATT_ON TRUE /* = 1 */ +#define NATT_FORCE 2 + +struct ph1natt_options { + int version; + u_int16_t float_port; + u_int16_t mode_udp_tunnel; + u_int16_t mode_udp_transport; + u_int16_t encaps_type; /* ESPINUDP / ESPINUDP_NON_IKE */ + u_int16_t mode_udp_diff; + u_int16_t payload_nat_d; + u_int16_t payload_nat_oa; +}; + +struct ph2natt { + u_int8_t type; + u_int16_t sport; + u_int16_t dport; + struct sockaddr *oa; + u_int16_t frag; +}; + +int natt_vendorid (int vid); +vchar_t *natt_hash_addr (struct ph1handle *iph1, struct sockaddr *addr); +int natt_compare_addr_hash (struct ph1handle *iph1, vchar_t *natd_received, int natd_seq); +int natt_udp_encap (int encmode); +int natt_fill_options (struct ph1natt_options *opts, int version); +void natt_float_ports (struct ph1handle *iph1); +void natt_handle_vendorid (struct ph1handle *iph1, int vid_numeric); + + +struct payload_list * +isakmp_plist_append_natt_vids (struct payload_list *plist, vchar_t *vid_natt[MAX_NATT_VID_COUNT]); + + +/* NAT keepalive functions */ +void natt_keepalive_init (void); +int natt_keepalive_add (struct sockaddr *src, struct sockaddr *dst); +int natt_keepalive_add_ph1 (struct ph1handle *iph1); +void natt_keepalive_remove (struct sockaddr *src, struct sockaddr *dst); + +/* Walk through all rmconfigs and tell if NAT-T is enabled in at least one. */ +int natt_enabled_in_rmconf (void); + +#endif /* _NATTRAVERSAL_H */ diff --git a/ipsec-tools/src/racoon/netdb_dnssec.h b/ipsec-tools/src/racoon/netdb_dnssec.h new file mode 100644 index 00000000..a11209db --- /dev/null +++ b/ipsec-tools/src/racoon/netdb_dnssec.h @@ -0,0 +1,74 @@ +/* $NetBSD: netdb_dnssec.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: netdb_dnssec.h,v 1.3 2004/06/11 16:00:17 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _NETDB_DNSSEC_H +#define _NETDB_DNSSEC_H + +#ifndef T_CERT +#define T_CERT 37 /* defined by RFC2538 section 2 */ +#endif + +/* RFC2538 section 2.1 */ +#define DNSSEC_TYPE_PKIX 1 +#define DNSSEC_TYPE_SPKI 2 +#define DNSSEC_TYPE_PGP 3 +#define DNSSEC_TYPE_URI 4 +#define DNSSEC_TYPE_OID 5 + +/* RFC2535 section 3.2 */ +#define DNSSEC_ALG_RSAMD5 1 +#define DNSSEC_ALG_DH 2 +#define DNSSEC_ALG_DSA 3 +#define DNSSEC_ALG_ECC 4 +#define DNSSEC_ALG_PRIVATEDNS 5 +#define DNSSEC_ALG_PRIVATEOID 6 + +/* + * Structures returned by network data base library. All addresses are + * supplied in host order, and returned in network order (suitable for + * use in system calls). + */ +struct certinfo { + int ci_type; /* certificate type */ + int ci_keytag; /* keytag */ + int ci_algorithm; /* algorithm */ + int ci_flags; /* currently, 1:valid or 0:uncertain */ + size_t ci_certlen; /* length of certificate */ + char *ci_cert; /* certificate */ + struct certinfo *ci_next; /* next structure */ +}; + +extern void freecertinfo __P((struct certinfo *)); +extern int getcertsbyname __P((char *, struct certinfo **)); + +#endif /* _NETDB_DNSSEC_H */ diff --git a/ipsec-tools/src/racoon/oakley.c b/ipsec-tools/src/racoon/oakley.c new file mode 100644 index 00000000..cad68744 --- /dev/null +++ b/ipsec-tools/src/racoon/oakley.c @@ -0,0 +1,3211 @@ +/* $NetBSD: oakley.c,v 1.22.2.2 2012/08/29 11:35:09 tteras Exp $ */ + +/* Id: oakley.c,v 1.32 2006/05/26 12:19:46 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include /* XXX for subjectaltname */ +#include /* XXX for subjectaltname */ + +#include +#include + +#include +#include +#include +#include + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#ifdef ENABLE_HYBRID +#include +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "str2val.h" +#include "plog.h" +#include "debug.h" + +#include "isakmp_var.h" +#include "isakmp.h" +#ifdef ENABLE_HYBRID +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif +#include "oakley.h" +#include "admin.h" +#include "privsep.h" +#include "localconf.h" +#include "remoteconf.h" +#include "policy.h" +#include "handler.h" +#include "ipsec_doi.h" +#include "algorithm.h" +#include "dhgroup.h" +#include "sainfo.h" +#include "proposal.h" +#include "crypto_openssl.h" +#include "dnssec.h" +#include "sockmisc.h" +#include "strnames.h" +#include "gcmalloc.h" +#include "rsalist.h" + +#ifdef HAVE_GSSAPI +#include "gssapi.h" +#endif + +#define OUTBOUND_SA 0 +#define INBOUND_SA 1 + +#define INITDHVAL(a, s, d, t) \ +do { \ + vchar_t buf; \ + buf.v = str2val((s), 16, &buf.l); \ + memset(&a, 0, sizeof(struct dhgroup)); \ + a.type = (t); \ + a.prime = vdup(&buf); \ + a.gen1 = 2; \ + a.gen2 = 0; \ + racoon_free(buf.v); \ +} while(0); + +struct dhgroup dh_modp768; +struct dhgroup dh_modp1024; +struct dhgroup dh_modp1536; +struct dhgroup dh_modp2048; +struct dhgroup dh_modp3072; +struct dhgroup dh_modp4096; +struct dhgroup dh_modp6144; +struct dhgroup dh_modp8192; + + +static int oakley_check_dh_pub __P((vchar_t *, vchar_t **)); +static int oakley_compute_keymat_x __P((struct ph2handle *, int, int)); +static int oakley_check_certid __P((struct ph1handle *iph1)); +static int check_typeofcertname __P((int, int)); +static int oakley_padlen __P((int, int)); +static int get_plainrsa_fromlocal __P((struct ph1handle *, int)); + +int oakley_get_certtype(cert) + vchar_t *cert; +{ + if (cert == NULL) + return ISAKMP_CERT_NONE; + + return cert->v[0]; +} + +static vchar_t * +dump_isakmp_payload(gen) + struct isakmp_gen *gen; +{ + vchar_t p; + + if (ntohs(gen->len) <= sizeof(*gen)) { + plog(LLV_ERROR, LOCATION, NULL, + "Len is too small !!.\n"); + return NULL; + } + + p.v = (caddr_t) (gen + 1); + p.l = ntohs(gen->len) - sizeof(*gen); + + return vdup(&p); +} + +static vchar_t * +dump_x509(cert) + X509 *cert; +{ + vchar_t *pl; + u_char *bp; + int len; + + len = i2d_X509(cert, NULL); + + pl = vmalloc(len + 1); + if (pl == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Failed to copy CERT from packet.\n"); + return NULL; + } + + pl->v[0] = ISAKMP_CERT_X509SIGN; + bp = (u_char *) &pl->v[1]; + i2d_X509(cert, &bp); + + return pl; +} + + + +int +oakley_get_defaultlifetime() +{ + return OAKLEY_ATTR_SA_LD_SEC_DEFAULT; +} + +int +oakley_dhinit() +{ + /* set DH MODP */ + INITDHVAL(dh_modp768, OAKLEY_PRIME_MODP768, + OAKLEY_ATTR_GRP_DESC_MODP768, OAKLEY_ATTR_GRP_TYPE_MODP); + INITDHVAL(dh_modp1024, OAKLEY_PRIME_MODP1024, + OAKLEY_ATTR_GRP_DESC_MODP1024, OAKLEY_ATTR_GRP_TYPE_MODP); + INITDHVAL(dh_modp1536, OAKLEY_PRIME_MODP1536, + OAKLEY_ATTR_GRP_DESC_MODP1536, OAKLEY_ATTR_GRP_TYPE_MODP); + INITDHVAL(dh_modp2048, OAKLEY_PRIME_MODP2048, + OAKLEY_ATTR_GRP_DESC_MODP2048, OAKLEY_ATTR_GRP_TYPE_MODP); + INITDHVAL(dh_modp3072, OAKLEY_PRIME_MODP3072, + OAKLEY_ATTR_GRP_DESC_MODP3072, OAKLEY_ATTR_GRP_TYPE_MODP); + INITDHVAL(dh_modp4096, OAKLEY_PRIME_MODP4096, + OAKLEY_ATTR_GRP_DESC_MODP4096, OAKLEY_ATTR_GRP_TYPE_MODP); + INITDHVAL(dh_modp6144, OAKLEY_PRIME_MODP6144, + OAKLEY_ATTR_GRP_DESC_MODP6144, OAKLEY_ATTR_GRP_TYPE_MODP); + INITDHVAL(dh_modp8192, OAKLEY_PRIME_MODP8192, + OAKLEY_ATTR_GRP_DESC_MODP8192, OAKLEY_ATTR_GRP_TYPE_MODP); + + return 0; +} + +void +oakley_dhgrp_free(dhgrp) + struct dhgroup *dhgrp; +{ + if (dhgrp->prime) + vfree(dhgrp->prime); + if (dhgrp->curve_a) + vfree(dhgrp->curve_a); + if (dhgrp->curve_b) + vfree(dhgrp->curve_b); + if (dhgrp->order) + vfree(dhgrp->order); + racoon_free(dhgrp); +} + +/* + * RFC2409 5 + * The length of the Diffie-Hellman public value MUST be equal to the + * length of the prime modulus over which the exponentiation was + * performed, prepending zero bits to the value if necessary. + */ +static int +oakley_check_dh_pub(prime, pub0) + vchar_t *prime, **pub0; +{ + vchar_t *tmp; + vchar_t *pub = *pub0; + + if (prime->l == pub->l) + return 0; + + if (prime->l < pub->l) { + /* what should i do ? */ + plog(LLV_ERROR, LOCATION, NULL, + "invalid public information was generated.\n"); + return -1; + } + + /* prime->l > pub->l */ + tmp = vmalloc(prime->l); + if (tmp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get DH buffer.\n"); + return -1; + } + memcpy(tmp->v + prime->l - pub->l, pub->v, pub->l); + + vfree(*pub0); + *pub0 = tmp; + + return 0; +} + +/* + * compute sharing secret of DH + * IN: *dh, *pub, *priv, *pub_p + * OUT: **gxy + */ +int +oakley_dh_compute(dh, pub, priv, pub_p, gxy) + const struct dhgroup *dh; + vchar_t *pub, *priv, *pub_p, **gxy; +{ +#ifdef ENABLE_STATS + struct timeval start, end; +#endif + if ((*gxy = vmalloc(dh->prime->l)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get DH buffer.\n"); + return -1; + } + +#ifdef ENABLE_STATS + gettimeofday(&start, NULL); +#endif + switch (dh->type) { + case OAKLEY_ATTR_GRP_TYPE_MODP: + if (eay_dh_compute(dh->prime, dh->gen1, pub, priv, pub_p, gxy) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute dh value.\n"); + return -1; + } + break; + case OAKLEY_ATTR_GRP_TYPE_ECP: + case OAKLEY_ATTR_GRP_TYPE_EC2N: + plog(LLV_ERROR, LOCATION, NULL, + "dh type %d isn't supported.\n", dh->type); + return -1; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid dh type %d.\n", dh->type); + return -1; + } + +#ifdef ENABLE_STATS + gettimeofday(&end, NULL); + syslog(LOG_NOTICE, "%s(%s%zu): %8.6f", __func__, + s_attr_isakmp_group(dh->type), dh->prime->l << 3, + timedelta(&start, &end)); +#endif + + plog(LLV_DEBUG, LOCATION, NULL, "compute DH's shared.\n"); + plogdump(LLV_DEBUG, (*gxy)->v, (*gxy)->l); + + return 0; +} + +/* + * generate values of DH + * IN: *dh + * OUT: **pub, **priv + */ +int +oakley_dh_generate(dh, pub, priv) + const struct dhgroup *dh; + vchar_t **pub, **priv; +{ +#ifdef ENABLE_STATS + struct timeval start, end; + gettimeofday(&start, NULL); +#endif + switch (dh->type) { + case OAKLEY_ATTR_GRP_TYPE_MODP: + if (eay_dh_generate(dh->prime, dh->gen1, dh->gen2, pub, priv) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute dh value.\n"); + return -1; + } + break; + + case OAKLEY_ATTR_GRP_TYPE_ECP: + case OAKLEY_ATTR_GRP_TYPE_EC2N: + plog(LLV_ERROR, LOCATION, NULL, + "dh type %d isn't supported.\n", dh->type); + return -1; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid dh type %d.\n", dh->type); + return -1; + } + +#ifdef ENABLE_STATS + gettimeofday(&end, NULL); + syslog(LOG_NOTICE, "%s(%s%zu): %8.6f", __func__, + s_attr_isakmp_group(dh->type), dh->prime->l << 3, + timedelta(&start, &end)); +#endif + + if (oakley_check_dh_pub(dh->prime, pub) != 0) + return -1; + + plog(LLV_DEBUG, LOCATION, NULL, "compute DH's private.\n"); + plogdump(LLV_DEBUG, (*priv)->v, (*priv)->l); + plog(LLV_DEBUG, LOCATION, NULL, "compute DH's public.\n"); + plogdump(LLV_DEBUG, (*pub)->v, (*pub)->l); + + return 0; +} + +/* + * copy pre-defined dhgroup values. + */ +int +oakley_setdhgroup(group, dhgrp) + int group; + struct dhgroup **dhgrp; +{ + struct dhgroup *g; + + *dhgrp = NULL; /* just make sure, initialize */ + + g = alg_oakley_dhdef_group(group); + if (g == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid DH parameter grp=%d.\n", group); + return -1; + } + + if (!g->type || !g->prime || !g->gen1) { + /* unsuported */ + plog(LLV_ERROR, LOCATION, NULL, + "unsupported DH parameters grp=%d.\n", group); + return -1; + } + + *dhgrp = racoon_calloc(1, sizeof(struct dhgroup)); + if (*dhgrp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get DH buffer.\n"); + return 0; + } + + /* set defined dh vlaues */ + memcpy(*dhgrp, g, sizeof(*g)); + (*dhgrp)->prime = vdup(g->prime); + + return 0; +} + +/* + * PRF + * + * NOTE: we do not support prf with different input/output bitwidth, + * so we do not implement RFC2409 Appendix B (DOORAK-MAC example) in + * oakley_compute_keymat(). If you add support for such prf function, + * modify oakley_compute_keymat() accordingly. + */ +vchar_t * +oakley_prf(key, buf, iph1) + vchar_t *key, *buf; + struct ph1handle *iph1; +{ + vchar_t *res = NULL; + int type; + + if (iph1->approval == NULL) { + /* + * it's before negotiating hash algorithm. + * We use md5 as default. + */ + type = OAKLEY_ATTR_HASH_ALG_MD5; + } else + type = iph1->approval->hashtype; + + res = alg_oakley_hmacdef_one(type, key, buf); + if (res == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid hmac algorithm %d.\n", type); + return NULL; + } + + return res; +} + +/* + * hash + */ +vchar_t * +oakley_hash(buf, iph1) + vchar_t *buf; + struct ph1handle *iph1; +{ + vchar_t *res = NULL; + int type; + + if (iph1->approval == NULL) { + /* + * it's before negotiating hash algorithm. + * We use md5 as default. + */ + type = OAKLEY_ATTR_HASH_ALG_MD5; + } else + type = iph1->approval->hashtype; + + res = alg_oakley_hashdef_one(type, buf); + if (res == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid hash algorithm %d.\n", type); + return NULL; + } + + return res; +} + +/* + * compute KEYMAT + * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05. + */ +int +oakley_compute_keymat(iph2, side) + struct ph2handle *iph2; + int side; +{ + int error = -1; + + /* compute sharing secret of DH when PFS */ + if (iph2->approval->pfs_group && iph2->dhpub_p) { + if (oakley_dh_compute(iph2->pfsgrp, iph2->dhpub, + iph2->dhpriv, iph2->dhpub_p, &iph2->dhgxy) < 0) + goto end; + } + + /* compute keymat */ + if (oakley_compute_keymat_x(iph2, side, INBOUND_SA) < 0 + || oakley_compute_keymat_x(iph2, side, OUTBOUND_SA) < 0) + goto end; + + plog(LLV_DEBUG, LOCATION, NULL, "KEYMAT computed.\n"); + + error = 0; + +end: + return error; +} + +/* + * compute KEYMAT. + * KEYMAT = prf(SKEYID_d, protocol | SPI | Ni_b | Nr_b). + * If PFS is desired and KE payloads were exchanged, + * KEYMAT = prf(SKEYID_d, g(qm)^xy | protocol | SPI | Ni_b | Nr_b) + * + * NOTE: we do not support prf with different input/output bitwidth, + * so we do not implement RFC2409 Appendix B (DOORAK-MAC example). + */ +static int +oakley_compute_keymat_x(iph2, side, sa_dir) + struct ph2handle *iph2; + int side; + int sa_dir; +{ + vchar_t *buf = NULL, *res = NULL, *bp; + char *p; + int len; + int error = -1; + int pfs = 0; + int dupkeymat; /* generate K[1-dupkeymat] */ + struct saproto *pr; + struct satrns *tr; + int encklen, authklen, l; + + pfs = ((iph2->approval->pfs_group && iph2->dhgxy) ? 1 : 0); + + len = pfs ? iph2->dhgxy->l : 0; + len += (1 + + sizeof(u_int32_t) /* XXX SPI size */ + + iph2->nonce->l + + iph2->nonce_p->l); + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get keymat buffer.\n"); + goto end; + } + + for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { + p = buf->v; + + /* if PFS */ + if (pfs) { + memcpy(p, iph2->dhgxy->v, iph2->dhgxy->l); + p += iph2->dhgxy->l; + } + + p[0] = pr->proto_id; + p += 1; + + memcpy(p, (sa_dir == INBOUND_SA ? &pr->spi : &pr->spi_p), + sizeof(pr->spi)); + p += sizeof(pr->spi); + + bp = (side == INITIATOR ? iph2->nonce : iph2->nonce_p); + memcpy(p, bp->v, bp->l); + p += bp->l; + + bp = (side == INITIATOR ? iph2->nonce_p : iph2->nonce); + memcpy(p, bp->v, bp->l); + p += bp->l; + + /* compute IV */ + plog(LLV_DEBUG, LOCATION, NULL, "KEYMAT compute with\n"); + plogdump(LLV_DEBUG, buf->v, buf->l); + + /* res = K1 */ + res = oakley_prf(iph2->ph1->skeyid_d, buf, iph2->ph1); + if (res == NULL) + goto end; + + /* compute key length needed */ + encklen = authklen = 0; + switch (pr->proto_id) { + case IPSECDOI_PROTO_IPSEC_ESP: + for (tr = pr->head; tr; tr = tr->next) { + l = alg_ipsec_encdef_keylen(tr->trns_id, + tr->encklen); + if (l > encklen) + encklen = l; + + l = alg_ipsec_hmacdef_hashlen(tr->authtype); + if (l > authklen) + authklen = l; + } + break; + case IPSECDOI_PROTO_IPSEC_AH: + for (tr = pr->head; tr; tr = tr->next) { + l = alg_ipsec_hmacdef_hashlen(tr->trns_id); + if (l > authklen) + authklen = l; + } + break; + default: + break; + } + plog(LLV_DEBUG, LOCATION, NULL, "encklen=%d authklen=%d\n", + encklen, authklen); + + dupkeymat = (encklen + authklen) / 8 / res->l; + dupkeymat += 2; /* safety mergin */ + if (dupkeymat < 3) + dupkeymat = 3; + plog(LLV_DEBUG, LOCATION, NULL, + "generating %zu bits of key (dupkeymat=%d)\n", + dupkeymat * 8 * res->l, dupkeymat); + if (0 < --dupkeymat) { + vchar_t *prev = res; /* K(n-1) */ + vchar_t *seed = NULL; /* seed for Kn */ + size_t l; + + /* + * generating long key (isakmp-oakley-08 5.5) + * KEYMAT = K1 | K2 | K3 | ... + * where + * src = [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b + * K1 = prf(SKEYID_d, src) + * K2 = prf(SKEYID_d, K1 | src) + * K3 = prf(SKEYID_d, K2 | src) + * Kn = prf(SKEYID_d, K(n-1) | src) + */ + plog(LLV_DEBUG, LOCATION, NULL, + "generating K1...K%d for KEYMAT.\n", + dupkeymat + 1); + + seed = vmalloc(prev->l + buf->l); + if (seed == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get keymat buffer.\n"); + if (prev && prev != res) + vfree(prev); + goto end; + } + + while (dupkeymat--) { + vchar_t *this = NULL; /* Kn */ + int update_prev; + + memcpy(seed->v, prev->v, prev->l); + memcpy(seed->v + prev->l, buf->v, buf->l); + this = oakley_prf(iph2->ph1->skeyid_d, seed, + iph2->ph1); + if (!this) { + plog(LLV_ERROR, LOCATION, NULL, + "oakley_prf memory overflow\n"); + if (prev && prev != res) + vfree(prev); + vfree(this); + vfree(seed); + goto end; + } + + update_prev = (prev && prev == res) ? 1 : 0; + + l = res->l; + res = vrealloc(res, l + this->l); + + if (update_prev) + prev = res; + + if (res == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get keymat buffer.\n"); + if (prev && prev != res) + vfree(prev); + vfree(this); + vfree(seed); + goto end; + } + memcpy(res->v + l, this->v, this->l); + + if (prev && prev != res) + vfree(prev); + prev = this; + this = NULL; + } + + if (prev && prev != res) + vfree(prev); + vfree(seed); + } + + plogdump(LLV_DEBUG, res->v, res->l); + + if (sa_dir == INBOUND_SA) + pr->keymat = res; + else + pr->keymat_p = res; + res = NULL; + } + + error = 0; + +end: + if (error) { + for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { + if (pr->keymat) { + vfree(pr->keymat); + pr->keymat = NULL; + } + if (pr->keymat_p) { + vfree(pr->keymat_p); + pr->keymat_p = NULL; + } + } + } + + if (buf != NULL) + vfree(buf); + if (res) + vfree(res); + + return error; +} + +#if notyet +/* + * NOTE: Must terminate by NULL. + */ +vchar_t * +oakley_compute_hashx(struct ph1handle *iph1, ...) +{ + vchar_t *buf, *res; + vchar_t *s; + caddr_t p; + int len; + + va_list ap; + + /* get buffer length */ + va_start(ap, iph1); + len = 0; + while ((s = va_arg(ap, vchar_t *)) != NULL) { + len += s->l + } + va_end(ap); + + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get hash buffer\n"); + return NULL; + } + + /* set buffer */ + va_start(ap, iph1); + p = buf->v; + while ((s = va_arg(ap, char *)) != NULL) { + memcpy(p, s->v, s->l); + p += s->l; + } + va_end(ap); + + plog(LLV_DEBUG, LOCATION, NULL, "HASH with: \n"); + plogdump(LLV_DEBUG, buf->v, buf->l); + + /* compute HASH */ + res = oakley_prf(iph1->skeyid_a, buf, iph1); + vfree(buf); + if (res == NULL) + return NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n"); + plogdump(LLV_DEBUG, res->v, res->l); + + return res; +} +#endif + +/* + * compute HASH(3) prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) + * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05. + */ +vchar_t * +oakley_compute_hash3(iph1, msgid, body) + struct ph1handle *iph1; + u_int32_t msgid; + vchar_t *body; +{ + vchar_t *buf = 0, *res = 0; + int len; + int error = -1; + + /* create buffer */ + len = 1 + sizeof(u_int32_t) + body->l; + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "failed to get hash buffer\n"); + goto end; + } + + buf->v[0] = 0; + + memcpy(buf->v + 1, (char *)&msgid, sizeof(msgid)); + + memcpy(buf->v + 1 + sizeof(u_int32_t), body->v, body->l); + + plog(LLV_DEBUG, LOCATION, NULL, "HASH with: \n"); + plogdump(LLV_DEBUG, buf->v, buf->l); + + /* compute HASH */ + res = oakley_prf(iph1->skeyid_a, buf, iph1); + if (res == NULL) + goto end; + + error = 0; + + plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n"); + plogdump(LLV_DEBUG, res->v, res->l); + +end: + if (buf != NULL) + vfree(buf); + return res; +} + +/* + * compute HASH type of prf(SKEYID_a, M-ID | buffer) + * e.g. + * for quick mode HASH(1): + * prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr ]) + * for quick mode HASH(2): + * prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr ]) + * for Informational exchange: + * prf(SKEYID_a, M-ID | N/D) + */ +vchar_t * +oakley_compute_hash1(iph1, msgid, body) + struct ph1handle *iph1; + u_int32_t msgid; + vchar_t *body; +{ + vchar_t *buf = NULL, *res = NULL; + char *p; + int len; + int error = -1; + + /* create buffer */ + len = sizeof(u_int32_t) + body->l; + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "failed to get hash buffer\n"); + goto end; + } + + p = buf->v; + + memcpy(buf->v, (char *)&msgid, sizeof(msgid)); + p += sizeof(u_int32_t); + + memcpy(p, body->v, body->l); + + plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n"); + plogdump(LLV_DEBUG, buf->v, buf->l); + + /* compute HASH */ + res = oakley_prf(iph1->skeyid_a, buf, iph1); + if (res == NULL) + goto end; + + error = 0; + + plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n"); + plogdump(LLV_DEBUG, res->v, res->l); + +end: + if (buf != NULL) + vfree(buf); + return res; +} + +/* + * compute phase1 HASH + * main/aggressive + * I-digest = prf(SKEYID, g^i | g^r | CKY-I | CKY-R | SAi_b | ID_i1_b) + * R-digest = prf(SKEYID, g^r | g^i | CKY-R | CKY-I | SAi_b | ID_r1_b) + * for gssapi, also include all GSS tokens, and call gss_wrap on the result + */ +vchar_t * +oakley_ph1hash_common(iph1, sw) + struct ph1handle *iph1; + int sw; +{ + vchar_t *buf = NULL, *res = NULL, *bp; + char *p, *bp2; + int len, bl; + int error = -1; +#ifdef HAVE_GSSAPI + vchar_t *gsstokens = NULL; +#endif + + /* create buffer */ + len = iph1->dhpub->l + + iph1->dhpub_p->l + + sizeof(cookie_t) * 2 + + iph1->sa->l + + (sw == GENERATE ? iph1->id->l : iph1->id_p->l); + +#ifdef HAVE_GSSAPI + if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { + if (iph1->gi_i != NULL && iph1->gi_r != NULL) { + bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r); + len += bp->l; + } + if (sw == GENERATE) + gssapi_get_itokens(iph1, &gsstokens); + else + gssapi_get_rtokens(iph1, &gsstokens); + if (gsstokens == NULL) + return NULL; + len += gsstokens->l; + } +#endif + + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get hash buffer\n"); + goto end; + } + + p = buf->v; + + bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p); + memcpy(p, bp->v, bp->l); + p += bp->l; + + bp = (sw == GENERATE ? iph1->dhpub_p : iph1->dhpub); + memcpy(p, bp->v, bp->l); + p += bp->l; + + if (iph1->side == INITIATOR) + bp2 = (sw == GENERATE ? + (char *)&iph1->index.i_ck : (char *)&iph1->index.r_ck); + else + bp2 = (sw == GENERATE ? + (char *)&iph1->index.r_ck : (char *)&iph1->index.i_ck); + bl = sizeof(cookie_t); + memcpy(p, bp2, bl); + p += bl; + + if (iph1->side == INITIATOR) + bp2 = (sw == GENERATE ? + (char *)&iph1->index.r_ck : (char *)&iph1->index.i_ck); + else + bp2 = (sw == GENERATE ? + (char *)&iph1->index.i_ck : (char *)&iph1->index.r_ck); + bl = sizeof(cookie_t); + memcpy(p, bp2, bl); + p += bl; + + bp = iph1->sa; + memcpy(p, bp->v, bp->l); + p += bp->l; + + bp = (sw == GENERATE ? iph1->id : iph1->id_p); + memcpy(p, bp->v, bp->l); + p += bp->l; + +#ifdef HAVE_GSSAPI + if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { + if (iph1->gi_i != NULL && iph1->gi_r != NULL) { + bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r); + memcpy(p, bp->v, bp->l); + p += bp->l; + } + memcpy(p, gsstokens->v, gsstokens->l); + p += gsstokens->l; + } +#endif + + plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n"); + plogdump(LLV_DEBUG, buf->v, buf->l); + + /* compute HASH */ + res = oakley_prf(iph1->skeyid, buf, iph1); + if (res == NULL) + goto end; + + error = 0; + + plog(LLV_DEBUG, LOCATION, NULL, "HASH (%s) computed:\n", + iph1->side == INITIATOR ? "init" : "resp"); + plogdump(LLV_DEBUG, res->v, res->l); + +end: + if (buf != NULL) + vfree(buf); +#ifdef HAVE_GSSAPI + if (gsstokens != NULL) + vfree(gsstokens); +#endif + return res; +} + +/* + * compute HASH_I on base mode. + * base:psk,rsa + * HASH_I = prf(SKEYID, g^xi | CKY-I | CKY-R | SAi_b | IDii_b) + * base:sig + * HASH_I = prf(hash(Ni_b | Nr_b), g^xi | CKY-I | CKY-R | SAi_b | IDii_b) + */ +vchar_t * +oakley_ph1hash_base_i(iph1, sw) + struct ph1handle *iph1; + int sw; +{ + vchar_t *buf = NULL, *res = NULL, *bp; + vchar_t *hashkey = NULL; + vchar_t *hash = NULL; /* for signature mode */ + char *p; + int len; + int error = -1; + + /* sanity check */ + if (iph1->etype != ISAKMP_ETYPE_BASE) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid etype for this hash function\n"); + return NULL; + } + + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_PSKEY: + case OAKLEY_ATTR_AUTH_METHOD_RSAENC: + case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif + if (iph1->skeyid == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n"); + return NULL; + } + hashkey = iph1->skeyid; + break; + + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef HAVE_GSSAPI + case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: +#endif +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: +#endif + /* make hash for seed */ + len = iph1->nonce->l + iph1->nonce_p->l; + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get hash buffer\n"); + goto end; + } + p = buf->v; + + bp = (sw == GENERATE ? iph1->nonce_p : iph1->nonce); + memcpy(p, bp->v, bp->l); + p += bp->l; + + bp = (sw == GENERATE ? iph1->nonce : iph1->nonce_p); + memcpy(p, bp->v, bp->l); + p += bp->l; + + hash = oakley_hash(buf, iph1); + if (hash == NULL) + goto end; + vfree(buf); + buf = NULL; + + hashkey = hash; + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "not supported authentication method %d\n", + iph1->approval->authmethod); + return NULL; + + } + + len = (sw == GENERATE ? iph1->dhpub->l : iph1->dhpub_p->l) + + sizeof(cookie_t) * 2 + + iph1->sa->l + + (sw == GENERATE ? iph1->id->l : iph1->id_p->l); + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get hash buffer\n"); + goto end; + } + p = buf->v; + + bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p); + memcpy(p, bp->v, bp->l); + p += bp->l; + + memcpy(p, &iph1->index.i_ck, sizeof(cookie_t)); + p += sizeof(cookie_t); + memcpy(p, &iph1->index.r_ck, sizeof(cookie_t)); + p += sizeof(cookie_t); + + memcpy(p, iph1->sa->v, iph1->sa->l); + p += iph1->sa->l; + + bp = (sw == GENERATE ? iph1->id : iph1->id_p); + memcpy(p, bp->v, bp->l); + p += bp->l; + + plog(LLV_DEBUG, LOCATION, NULL, "HASH_I with:\n"); + plogdump(LLV_DEBUG, buf->v, buf->l); + + /* compute HASH */ + res = oakley_prf(hashkey, buf, iph1); + if (res == NULL) + goto end; + + error = 0; + + plog(LLV_DEBUG, LOCATION, NULL, "HASH_I computed:\n"); + plogdump(LLV_DEBUG, res->v, res->l); + +end: + if (hash != NULL) + vfree(hash); + if (buf != NULL) + vfree(buf); + return res; +} + +/* + * compute HASH_R on base mode for signature method. + * base: + * HASH_R = prf(hash(Ni_b | Nr_b), g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b) + */ +vchar_t * +oakley_ph1hash_base_r(iph1, sw) + struct ph1handle *iph1; + int sw; +{ + vchar_t *buf = NULL, *res = NULL, *bp; + vchar_t *hash = NULL; + char *p; + int len; + int error = -1; + + /* sanity check */ + if (iph1->etype != ISAKMP_ETYPE_BASE) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid etype for this hash function\n"); + return NULL; + } + + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: +#endif + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "not supported authentication method %d\n", + iph1->approval->authmethod); + return NULL; + break; + } + + /* make hash for seed */ + len = iph1->nonce->l + iph1->nonce_p->l; + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get hash buffer\n"); + goto end; + } + p = buf->v; + + bp = (sw == GENERATE ? iph1->nonce_p : iph1->nonce); + memcpy(p, bp->v, bp->l); + p += bp->l; + + bp = (sw == GENERATE ? iph1->nonce : iph1->nonce_p); + memcpy(p, bp->v, bp->l); + p += bp->l; + + hash = oakley_hash(buf, iph1); + if (hash == NULL) + goto end; + vfree(buf); + buf = NULL; + + /* make really hash */ + len = (sw == GENERATE ? iph1->dhpub_p->l : iph1->dhpub->l) + + (sw == GENERATE ? iph1->dhpub->l : iph1->dhpub_p->l) + + sizeof(cookie_t) * 2 + + iph1->sa->l + + (sw == GENERATE ? iph1->id_p->l : iph1->id->l); + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get hash buffer\n"); + goto end; + } + p = buf->v; + + + bp = (sw == GENERATE ? iph1->dhpub_p : iph1->dhpub); + memcpy(p, bp->v, bp->l); + p += bp->l; + + bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p); + memcpy(p, bp->v, bp->l); + p += bp->l; + + memcpy(p, &iph1->index.i_ck, sizeof(cookie_t)); + p += sizeof(cookie_t); + memcpy(p, &iph1->index.r_ck, sizeof(cookie_t)); + p += sizeof(cookie_t); + + memcpy(p, iph1->sa->v, iph1->sa->l); + p += iph1->sa->l; + + bp = (sw == GENERATE ? iph1->id_p : iph1->id); + memcpy(p, bp->v, bp->l); + p += bp->l; + + plog(LLV_DEBUG, LOCATION, NULL, "HASH_R with:\n"); + plogdump(LLV_DEBUG, buf->v, buf->l); + + /* compute HASH */ + res = oakley_prf(hash, buf, iph1); + if (res == NULL) + goto end; + + error = 0; + + plog(LLV_DEBUG, LOCATION, NULL, "HASH_R computed:\n"); + plogdump(LLV_DEBUG, res->v, res->l); + +end: + if (buf != NULL) + vfree(buf); + if (hash) + vfree(hash); + return res; +} + +/* + * compute each authentication method in phase 1. + * OUT: + * 0: OK + * -1: error + * other: error to be reply with notification. + * the value is notification type. + */ +int +oakley_validate_auth(iph1) + struct ph1handle *iph1; +{ + vchar_t *my_hash = NULL; + int result; + int no_verify_needed = -1; +#ifdef HAVE_GSSAPI + vchar_t *gsshash = NULL; +#endif +#ifdef ENABLE_STATS + struct timeval start, end; +#endif + +#ifdef ENABLE_STATS + gettimeofday(&start, NULL); +#endif + + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif + /* validate HASH */ + { + char *r_hash; + + if (iph1->id_p == NULL || iph1->pl_hash == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "few isakmp message received.\n"); + return ISAKMP_NTYPE_PAYLOAD_MALFORMED; + } +#ifdef ENABLE_HYBRID + if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I && + ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0)) + { + plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, " + "hybrid auth is enabled, " + "but peer is no Xauth compliant\n"); + return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED; + break; + } +#endif + r_hash = (caddr_t)(iph1->pl_hash + 1); + + plog(LLV_DEBUG, LOCATION, NULL, "HASH received:\n"); + plogdump(LLV_DEBUG, r_hash, + ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash)); + + switch (iph1->etype) { + case ISAKMP_ETYPE_IDENT: + case ISAKMP_ETYPE_AGG: + my_hash = oakley_ph1hash_common(iph1, VALIDATE); + break; + case ISAKMP_ETYPE_BASE: + if (iph1->side == INITIATOR) + my_hash = oakley_ph1hash_common(iph1, VALIDATE); + else + my_hash = oakley_ph1hash_base_i(iph1, VALIDATE); + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid etype %d\n", iph1->etype); + return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE; + } + if (my_hash == NULL) + return ISAKMP_INTERNAL_ERROR; + + result = memcmp(my_hash->v, r_hash, my_hash->l); + vfree(my_hash); + + if (result) { + plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n"); + return ISAKMP_NTYPE_INVALID_HASH_INFORMATION; + } + + plog(LLV_DEBUG, LOCATION, NULL, "HASH for PSK validated.\n"); + } + break; +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + no_verify_needed = 0; +#endif + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: + { + int error = 0; + int certtype; + + /* validation */ + if (iph1->id_p == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "no ID payload was passed.\n"); + return ISAKMP_NTYPE_PAYLOAD_MALFORMED; + } + if (iph1->sig_p == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "no SIG payload was passed.\n"); + return ISAKMP_NTYPE_PAYLOAD_MALFORMED; + } + + plog(LLV_DEBUG, LOCATION, NULL, "SIGN passed:\n"); + plogdump(LLV_DEBUG, iph1->sig_p->v, iph1->sig_p->l); + + /* get peer's cert */ + certtype = oakley_get_certtype(iph1->rmconf->peerscert); + switch (certtype) { + case ISAKMP_CERT_NONE: + /* expect to receive one from peer */ + if (iph1->cert_p == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no peer's CERT payload found.\n"); + return ISAKMP_INTERNAL_ERROR; + } + /* verify the cert if needed */ + if (!iph1->rmconf->verify_cert) + break; + + switch (oakley_get_certtype(iph1->cert_p)) { + case ISAKMP_CERT_X509SIGN: { + char path[MAXPATHLEN]; + char *ca; + + if (iph1->rmconf->cacertfile != NULL) { + getpathname(path, sizeof(path), + LC_PATHTYPE_CERT, + iph1->rmconf->cacertfile); + ca = path; + } else { + ca = NULL; + } + + error = eay_check_x509cert( + iph1->cert_p, + lcconf->pathinfo[LC_PATHTYPE_CERT], + ca, 0); + break; + } + default: + plog(LLV_ERROR, LOCATION, NULL, + "peers_cert certtype %d was not expected\n", + certtype); + return ISAKMP_INTERNAL_ERROR; + } + + if (error != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "the peer's certificate is not verified.\n"); + return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY; + } + break; + case ISAKMP_CERT_X509SIGN: + if (iph1->rmconf->peerscert == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no peer's CERT file found.\n"); + return ISAKMP_INTERNAL_ERROR; + } + /* don't use received cert */ + if (iph1->cert_p != NULL) { + vfree(iph1->cert_p); + iph1->cert_p = NULL; + } + /* copy from remoteconf instead */ + iph1->cert_p = vdup(iph1->rmconf->peerscert); + break; + case ISAKMP_CERT_PLAINRSA: + if (get_plainrsa_fromlocal(iph1, 0)) + return ISAKMP_INTERNAL_ERROR; + /* suppress CERT validation warning, unless hybrid mode in use */ + if (no_verify_needed == -1) + no_verify_needed = 1; + break; + case ISAKMP_CERT_DNS: + /* don't use received cert */ + if (iph1->cert_p != NULL) { + vfree(iph1->cert_p); + iph1->cert_p = NULL; + } + + iph1->cert_p = dnssec_getcert(iph1->id_p); + if (iph1->cert_p == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no CERT RR found.\n"); + return ISAKMP_INTERNAL_ERROR; + } + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid certificate type: %d\n", + oakley_get_certtype(iph1->rmconf->peerscert)); + return ISAKMP_INTERNAL_ERROR; + } + + /* compare ID payload and certificate name */ + if ((error = oakley_check_certid(iph1)) != 0) + return error; + + /* Generate a warning unless verify_cert */ + if (iph1->rmconf->verify_cert) { + plog(LLV_DEBUG, LOCATION, iph1->remote, + "CERT validated\n"); + } else if (no_verify_needed != 1) { + plog(LLV_WARNING, LOCATION, iph1->remote, + "CERT validation disabled by configuration\n"); + } + + /* compute hash */ + switch (iph1->etype) { + case ISAKMP_ETYPE_IDENT: + case ISAKMP_ETYPE_AGG: + my_hash = oakley_ph1hash_common(iph1, VALIDATE); + break; + case ISAKMP_ETYPE_BASE: + if (iph1->side == INITIATOR) + my_hash = oakley_ph1hash_base_r(iph1, VALIDATE); + else + my_hash = oakley_ph1hash_base_i(iph1, VALIDATE); + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid etype %d\n", iph1->etype); + return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE; + } + if (my_hash == NULL) + return ISAKMP_INTERNAL_ERROR; + + /* check signature */ + certtype = oakley_get_certtype(iph1->cert_p); + if (certtype == ISAKMP_CERT_NONE) + certtype = oakley_get_certtype(iph1->rmconf->peerscert); + switch (certtype) { + case ISAKMP_CERT_X509SIGN: + case ISAKMP_CERT_DNS: + error = eay_check_x509sign(my_hash, + iph1->sig_p, + iph1->cert_p); + break; + case ISAKMP_CERT_PLAINRSA: + iph1->rsa_p = rsa_try_check_rsasign(my_hash, + iph1->sig_p, iph1->rsa_candidates); + error = iph1->rsa_p ? 0 : -1; + genlist_free(iph1->rsa_candidates, NULL); + iph1->rsa_candidates = NULL; + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "cannot check signature for certtype %d\n", + certtype); + vfree(my_hash); + return ISAKMP_INTERNAL_ERROR; + } + + vfree(my_hash); + if (error != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Invalid SIG.\n"); + return ISAKMP_NTYPE_INVALID_SIGNATURE; + } + plog(LLV_DEBUG, LOCATION, NULL, "SIG authenticated\n"); + } + break; +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + { + if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) { + plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, " + "hybrid auth is enabled, " + "but peer is no Xauth compliant\n"); + return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED; + break; + } + plog(LLV_INFO, LOCATION, NULL, "No SIG was passed, " + "but hybrid auth is enabled\n"); + + return 0; + break; + } +#endif +#ifdef HAVE_GSSAPI + case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: + /* check if we're not into XAUTH_PSKEY_I instead */ +#ifdef ENABLE_HYBRID + if (iph1->rmconf->xauth) + break; +#endif + switch (iph1->etype) { + case ISAKMP_ETYPE_IDENT: + case ISAKMP_ETYPE_AGG: + my_hash = oakley_ph1hash_common(iph1, VALIDATE); + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid etype %d\n", iph1->etype); + return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE; + } + + if (my_hash == NULL) { + if (gssapi_more_tokens(iph1)) + return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE; + else + return ISAKMP_NTYPE_INVALID_HASH_INFORMATION; + } + + gsshash = gssapi_unwraphash(iph1); + if (gsshash == NULL) { + vfree(my_hash); + return ISAKMP_NTYPE_INVALID_HASH_INFORMATION; + } + + result = memcmp(my_hash->v, gsshash->v, my_hash->l); + vfree(my_hash); + vfree(gsshash); + + if (result) { + plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n"); + return ISAKMP_NTYPE_INVALID_HASH_INFORMATION; + } + plog(LLV_DEBUG, LOCATION, NULL, "hash compared OK\n"); + break; +#endif + case OAKLEY_ATTR_AUTH_METHOD_RSAENC: + case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif + if (iph1->id_p == NULL || iph1->pl_hash == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "few isakmp message received.\n"); + return ISAKMP_NTYPE_PAYLOAD_MALFORMED; + } + plog(LLV_ERROR, LOCATION, iph1->remote, + "not supported authmethod type %s\n", + s_oakley_attr_method(iph1->approval->authmethod)); + return ISAKMP_INTERNAL_ERROR; + default: + plog(LLV_ERROR, LOCATION, iph1->remote, + "invalid authmethod %d why ?\n", + iph1->approval->authmethod); + return ISAKMP_INTERNAL_ERROR; + } +#ifdef ENABLE_STATS + gettimeofday(&end, NULL); + syslog(LOG_NOTICE, "%s(%s): %8.6f", __func__, + s_oakley_attr_method(iph1->approval->authmethod), + timedelta(&start, &end)); +#endif + + return 0; +} + +/* get my certificate + * NOTE: include certificate type. + */ +int +oakley_getmycert(iph1) + struct ph1handle *iph1; +{ + switch (oakley_get_certtype(iph1->rmconf->mycert)) { + case ISAKMP_CERT_X509SIGN: + if (iph1->cert) + return 0; + iph1->cert = vdup(iph1->rmconf->mycert); + break; + case ISAKMP_CERT_PLAINRSA: + if (iph1->rsa) + return 0; + return get_plainrsa_fromlocal(iph1, 1); + default: + plog(LLV_ERROR, LOCATION, NULL, + "Unknown certtype #%d\n", + oakley_get_certtype(iph1->rmconf->mycert)); + return -1; + } + + return 0; +} + +static int +get_plainrsa_fromlocal(iph1, my) + struct ph1handle *iph1; + int my; +{ + char path[MAXPATHLEN]; + vchar_t *cert = NULL; + char *certfile; + int error = -1; + + iph1->rsa_candidates = rsa_lookup_keys(iph1, my); + if (!iph1->rsa_candidates || + rsa_list_count(iph1->rsa_candidates) == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "%s RSA key not found for %s\n", + my ? "Private" : "Public", + saddr2str_fromto("%s <-> %s", + iph1->local, iph1->remote)); + goto end; + } + + if (my && rsa_list_count(iph1->rsa_candidates) > 1) { + plog(LLV_WARNING, LOCATION, NULL, + "More than one (=%lu) private " + "PlainRSA key found for %s\n", + rsa_list_count(iph1->rsa_candidates), + saddr2str_fromto("%s <-> %s", + iph1->local, iph1->remote)); + plog(LLV_WARNING, LOCATION, NULL, + "This may have unpredictable results, " + "i.e. wrong key could be used!\n"); + plog(LLV_WARNING, LOCATION, NULL, + "Consider using only one single private " + "key for all peers...\n"); + } + if (my) { + iph1->rsa = ((struct rsa_key *) + genlist_next(iph1->rsa_candidates, NULL))->rsa; + + genlist_free(iph1->rsa_candidates, NULL); + iph1->rsa_candidates = NULL; + + if (iph1->rsa == NULL) + goto end; + } + + error = 0; + +end: + return error; +} + +/* get signature */ +int +oakley_getsign(iph1) + struct ph1handle *iph1; +{ + char path[MAXPATHLEN]; + vchar_t *privkey = NULL; + int error = -1; + + switch (oakley_get_certtype(iph1->rmconf->mycert)) { + case ISAKMP_CERT_X509SIGN: + case ISAKMP_CERT_DNS: + if (iph1->rmconf->myprivfile == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "no cert defined.\n"); + goto end; + } + + /* make private file name */ + getpathname(path, sizeof(path), + LC_PATHTYPE_CERT, + iph1->rmconf->myprivfile); + privkey = privsep_eay_get_pkcs1privkey(path); + if (privkey == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get private key.\n"); + goto end; + } + plog(LLV_DEBUG2, LOCATION, NULL, "private key:\n"); + plogdump(LLV_DEBUG2, privkey->v, privkey->l); + iph1->sig = eay_get_x509sign(iph1->hash, privkey); + break; + case ISAKMP_CERT_PLAINRSA: + iph1->sig = eay_get_rsasign(iph1->hash, iph1->rsa); + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "Unknown certtype #%d\n", + oakley_get_certtype(iph1->rmconf->mycert)); + goto end; + } + + if (iph1->sig == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "failed to sign.\n"); + goto end; + } + + plog(LLV_DEBUG, LOCATION, NULL, "SIGN computed:\n"); + plogdump(LLV_DEBUG, iph1->sig->v, iph1->sig->l); + + error = 0; + +end: + if (privkey != NULL) + vfree(privkey); + + return error; +} + +/* + * compare certificate name and ID value. + */ +static int +oakley_check_certid(iph1) + struct ph1handle *iph1; +{ + struct ipsecdoi_id_b *id_b; + vchar_t *name = NULL; + char *altname = NULL; + int idlen, type; + int error; + + if (iph1->rmconf == NULL || iph1->rmconf->verify_cert == FALSE) + return 0; + + if (iph1->id_p == NULL || iph1->cert_p == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, "no ID nor CERT found.\n"); + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + } + + id_b = (struct ipsecdoi_id_b *)iph1->id_p->v; + idlen = iph1->id_p->l - sizeof(*id_b); + + switch (id_b->type) { + case IPSECDOI_ID_DER_ASN1_DN: + name = eay_get_x509asn1subjectname(iph1->cert_p); + if (!name) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to get subjectName\n"); + return ISAKMP_NTYPE_INVALID_CERTIFICATE; + } + if (idlen != name->l) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "Invalid ID length in phase 1.\n"); + vfree(name); + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + } + error = memcmp(id_b + 1, name->v, idlen); + if (error != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "ID mismatched with ASN1 SubjectName.\n"); + plogdump(LLV_DEBUG, id_b + 1, idlen); + plogdump(LLV_DEBUG, name->v, idlen); + if (iph1->rmconf->verify_identifier) { + vfree(name); + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + } + } + vfree(name); + return 0; + case IPSECDOI_ID_IPV4_ADDR: + case IPSECDOI_ID_IPV6_ADDR: + { + /* + * converting to binary from string because openssl return + * a string even if object is a binary. + * XXX fix it ! access by ASN.1 directly without. + */ + struct addrinfo hints, *res; + caddr_t a = NULL; + int pos; + + for (pos = 1; ; pos++) { + if (eay_get_x509subjectaltname(iph1->cert_p, + &altname, &type, pos) !=0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get subjectAltName\n"); + return ISAKMP_NTYPE_INVALID_CERTIFICATE; + } + + /* it's the end condition of the loop. */ + if (!altname) { + plog(LLV_ERROR, LOCATION, NULL, + "no proper subjectAltName.\n"); + return ISAKMP_NTYPE_INVALID_CERTIFICATE; + } + + if (check_typeofcertname(id_b->type, type) == 0) + break; + + /* next name */ + racoon_free(altname); + altname = NULL; + } + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_RAW; + hints.ai_flags = AI_NUMERICHOST; + error = getaddrinfo(altname, NULL, &hints, &res); + racoon_free(altname); + altname = NULL; + if (error != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "no proper subjectAltName.\n"); + return ISAKMP_NTYPE_INVALID_CERTIFICATE; + } + switch (res->ai_family) { + case AF_INET: + a = (caddr_t)&((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr; + break; +#ifdef INET6 + case AF_INET6: + a = (caddr_t)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr; + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "family not supported: %d.\n", res->ai_family); + freeaddrinfo(res); + return ISAKMP_NTYPE_INVALID_CERTIFICATE; + } + error = memcmp(id_b + 1, a, idlen); + freeaddrinfo(res); + vfree(name); + if (error != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "ID mismatched with subjectAltName.\n"); + plogdump(LLV_DEBUG, id_b + 1, idlen); + plogdump(LLV_DEBUG, a, idlen); + if (iph1->rmconf->verify_identifier) + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + } + return 0; + } + case IPSECDOI_ID_FQDN: + case IPSECDOI_ID_USER_FQDN: + { + int pos; + + for (pos = 1; ; pos++) { + if (eay_get_x509subjectaltname(iph1->cert_p, + &altname, &type, pos) != 0){ + plog(LLV_ERROR, LOCATION, NULL, + "failed to get subjectAltName\n"); + return ISAKMP_NTYPE_INVALID_CERTIFICATE; + } + + /* it's the end condition of the loop. */ + if (!altname) { + plog(LLV_ERROR, LOCATION, NULL, + "no proper subjectAltName.\n"); + return ISAKMP_NTYPE_INVALID_CERTIFICATE; + } + + if (check_typeofcertname(id_b->type, type) == 0) + break; + + /* next name */ + racoon_free(altname); + altname = NULL; + } + if (idlen != strlen(altname)) { + plog(LLV_ERROR, LOCATION, NULL, + "Invalid ID length in phase 1.\n"); + racoon_free(altname); + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + } + if (check_typeofcertname(id_b->type, type) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "ID type mismatched. ID: %s CERT: %s.\n", + s_ipsecdoi_ident(id_b->type), + s_ipsecdoi_ident(type)); + racoon_free(altname); + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + } + error = memcmp(id_b + 1, altname, idlen); + if (error) { + plog(LLV_ERROR, LOCATION, NULL, "ID mismatched.\n"); + plogdump(LLV_DEBUG, id_b + 1, idlen); + plogdump(LLV_DEBUG, altname, idlen); + racoon_free(altname); + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + } + racoon_free(altname); + return 0; + } + default: + plog(LLV_ERROR, LOCATION, NULL, + "Inpropper ID type passed: %s.\n", + s_ipsecdoi_ident(id_b->type)); + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + } + /*NOTREACHED*/ +} + +static int +check_typeofcertname(doi, genid) + int doi, genid; +{ + switch (doi) { + case IPSECDOI_ID_IPV4_ADDR: + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + case IPSECDOI_ID_IPV6_ADDR: + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + case IPSECDOI_ID_IPV4_ADDR_RANGE: + case IPSECDOI_ID_IPV6_ADDR_RANGE: + if (genid != GENT_IPADD) + return -1; + return 0; + case IPSECDOI_ID_FQDN: + if (genid != GENT_DNS) + return -1; + return 0; + case IPSECDOI_ID_USER_FQDN: + if (genid != GENT_EMAIL) + return -1; + return 0; + case IPSECDOI_ID_DER_ASN1_DN: /* should not be passed to this function*/ + case IPSECDOI_ID_DER_ASN1_GN: + case IPSECDOI_ID_KEY_ID: + default: + return -1; + } + /*NOTREACHED*/ +} + +/* + * save certificate including certificate type. + */ +int +oakley_savecert(iph1, gen) + struct ph1handle *iph1; + struct isakmp_gen *gen; +{ + vchar_t **c; + u_int8_t type; + STACK_OF(X509) *certs=NULL; + PKCS7 *p7; + + type = *(u_int8_t *)(gen + 1) & 0xff; + + switch (type) { + case ISAKMP_CERT_DNS: + plog(LLV_WARNING, LOCATION, NULL, + "CERT payload is unnecessary in DNSSEC. " + "ignore this CERT payload.\n"); + return 0; + case ISAKMP_CERT_PKCS7: + case ISAKMP_CERT_PGP: + case ISAKMP_CERT_X509SIGN: + case ISAKMP_CERT_KERBEROS: + case ISAKMP_CERT_SPKI: + c = &iph1->cert_p; + break; + case ISAKMP_CERT_CRL: + c = &iph1->crl_p; + break; + case ISAKMP_CERT_X509KE: + case ISAKMP_CERT_X509ATTR: + case ISAKMP_CERT_ARL: + plog(LLV_ERROR, LOCATION, NULL, + "No supported such CERT type %d\n", type); + return -1; + default: + plog(LLV_ERROR, LOCATION, NULL, + "Invalid CERT type %d\n", type); + return -1; + } + + /* XXX choice the 1th cert, ignore after the cert. */ + /* XXX should be processed. */ + if (*c) { + plog(LLV_WARNING, LOCATION, NULL, + "ignore 2nd CERT payload.\n"); + return 0; + } + + if (type == ISAKMP_CERT_PKCS7) { + u_char *bp; + int i; + + /* Skip the header */ + bp = (u_char *)(gen + 1); + /* And the first byte is the certificate type, + * we know that already + */ + bp++; + p7 = d2i_PKCS7(NULL, (void *)&bp, + ntohs(gen->len) - sizeof(*gen) - 1); + + if (!p7) { + plog(LLV_ERROR, LOCATION, NULL, + "Failed to parse PKCS#7 CERT.\n"); + return -1; + } + + /* Copied this from the openssl pkcs7 application; + * there"s little by way of documentation for any of + * it. I can only presume it"s correct. + */ + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + certs=p7->d.sign->cert; + break; + case NID_pkcs7_signedAndEnveloped: + certs=p7->d.signed_and_enveloped->cert; + break; + default: + break; + } + + if (!certs) { + plog(LLV_ERROR, LOCATION, NULL, + "CERT PKCS#7 bundle contains no certs.\n"); + PKCS7_free(p7); + return -1; + } + + for (i = 0; i < sk_X509_num(certs); i++) { + int len; + u_char *bp; + X509 *cert = sk_X509_value(certs,i); + + plog(LLV_DEBUG, LOCATION, NULL, + "Trying PKCS#7 cert %d.\n", i); + + /* We'll just try each cert in turn */ + *c = dump_x509(cert); + + if (!*c) { + plog(LLV_ERROR, LOCATION, NULL, + "Failed to get CERT buffer.\n"); + continue; + } + + /* Ignore cert if it doesn't match identity + * XXX If verify cert is disabled, we still just take + * the first certificate.... + */ + if (oakley_check_certid(iph1)) { + plog(LLV_DEBUG, LOCATION, NULL, + "Discarding CERT: does not match ID.\n"); + vfree((*c)); + *c = NULL; + continue; + } + + { + char *p = eay_get_x509text(*c); + plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n"); + plogdump(LLV_DEBUG, (*c)->v, (*c)->l); + plog(LLV_DEBUG, LOCATION, NULL, "%s", + p ? p : "\n"); + racoon_free(p); + } + break; + } + PKCS7_free(p7); + } else { + *c = dump_isakmp_payload(gen); + if (!*c) { + plog(LLV_ERROR, LOCATION, NULL, + "Failed to get CERT buffer.\n"); + return -1; + } + + switch (type) { + case ISAKMP_CERT_PGP: + case ISAKMP_CERT_X509SIGN: + case ISAKMP_CERT_KERBEROS: + case ISAKMP_CERT_SPKI: + /* Ignore cert if it doesn't match identity + * XXX If verify cert is disabled, we still just take + * the first certificate.... + */ + if (oakley_check_certid(iph1)){ + plog(LLV_DEBUG, LOCATION, NULL, + "Discarding CERT: does not match ID.\n"); + vfree((*c)); + *c = NULL; + return 0; + } + + { + char *p = eay_get_x509text(*c); + plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n"); + plogdump(LLV_DEBUG, (*c)->v, (*c)->l); + plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n"); + racoon_free(p); + } + break; + case ISAKMP_CERT_CRL: + plog(LLV_DEBUG, LOCATION, NULL, "CRL saved:\n"); + plogdump(LLV_DEBUG, (*c)->v, (*c)->l); + break; + case ISAKMP_CERT_X509KE: + case ISAKMP_CERT_X509ATTR: + case ISAKMP_CERT_ARL: + default: + /* XXX */ + vfree(*c); + *c = NULL; + return 0; + } + } + + return 0; +} + +/* + * save certificate including certificate type. + */ +int +oakley_savecr(iph1, gen) + struct ph1handle *iph1; + struct isakmp_gen *gen; +{ + vchar_t *cert; + vchar_t **c; + u_int8_t type; + + type = *(u_int8_t *)(gen + 1) & 0xff; + switch (type) { + case ISAKMP_CERT_DNS: + plog(LLV_WARNING, LOCATION, NULL, + "CERT payload is unnecessary in DNSSEC\n"); + /*FALLTHRU*/ + case ISAKMP_CERT_PKCS7: + case ISAKMP_CERT_PGP: + case ISAKMP_CERT_X509SIGN: + case ISAKMP_CERT_KERBEROS: + case ISAKMP_CERT_SPKI: + c = &iph1->cr_p; + break; + case ISAKMP_CERT_X509KE: + case ISAKMP_CERT_X509ATTR: + case ISAKMP_CERT_ARL: + plog(LLV_ERROR, LOCATION, NULL, + "No supported such CR type %d\n", type); + return -1; + case ISAKMP_CERT_CRL: + default: + plog(LLV_ERROR, LOCATION, NULL, + "Invalid CR type %d\n", type); + return -1; + } + + /* Already found an acceptable CR? */ + if (*c != NULL) + return 0; + + cert = dump_isakmp_payload(gen); + if (cert == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Failed to get CR buffer.\n"); + return -1; + } + + plog(LLV_DEBUG, LOCATION, NULL, "CR received:\n"); + plogdump(LLV_DEBUG, cert->v, cert->l); + + *c = cert; + if (resolveph1rmconf(iph1) == 0) { + /* Found unique match */ + plog(LLV_DEBUG, LOCATION, NULL, "CR saved.\n"); + } else { + /* Still ambiguous or matches nothing, ignore this CR */ + *c = NULL; + vfree(cert); + } + return 0; +} + +/* + * Add a single CR. + */ +struct append_cr_ctx { + struct ph1handle *iph1; + struct payload_list *plist; +}; + +static int +oakley_append_rmconf_cr(rmconf, ctx) + struct remoteconf *rmconf; + void *ctx; +{ + struct append_cr_ctx *actx = (struct append_cr_ctx *) ctx; + vchar_t *buf, *asn1dn = NULL; + int type; + + /* Do we want to send CR about this? */ + if (rmconf->send_cr == FALSE) + return 0; + + if (rmconf->peerscert != NULL) { + type = oakley_get_certtype(rmconf->peerscert); + asn1dn = eay_get_x509asn1issuername(rmconf->peerscert); + } else if (rmconf->cacert != NULL) { + type = oakley_get_certtype(rmconf->cacert); + asn1dn = eay_get_x509asn1subjectname(rmconf->cacert); + } else + return 0; + + if (asn1dn == NULL) { + plog(LLV_ERROR, LOCATION, actx->iph1->remote, + "Failed to get CR ASN1 DN from certificate\n"); + return 0; + } + + buf = vmalloc(1 + asn1dn->l); + if (buf == NULL) + goto err; + + buf->v[0] = type; + memcpy(&buf->v[1], asn1dn->v, asn1dn->l); + + plog(LLV_DEBUG, LOCATION, actx->iph1->remote, + "appending CR: %s\n", + s_isakmp_certtype(buf->v[0])); + plogdump(LLV_DEBUG, buf->v, buf->l); + + actx->plist = isakmp_plist_append_full(actx->plist, buf, ISAKMP_NPTYPE_CR, 1); + +err: + vfree(asn1dn); + return 0; +} + +/* + * Append list of acceptable CRs. + * RFC2048 3.10 + */ +struct payload_list * +oakley_append_cr(plist, iph1) + struct payload_list *plist; + struct ph1handle *iph1; +{ + struct append_cr_ctx ctx; + struct rmconfselector sel; + + ctx.iph1 = iph1; + ctx.plist = plist; + if (iph1->rmconf == NULL) { + rmconf_selector_from_ph1(&sel, iph1); + enumrmconf(&sel, oakley_append_rmconf_cr, &ctx); + } else { + oakley_append_rmconf_cr(iph1->rmconf, &ctx); + } + + return ctx.plist; +} + +/* + * check peer's CR. + */ +int +oakley_checkcr(iph1) + struct ph1handle *iph1; +{ + int type; + + if (iph1->cr_p == NULL) + return 0; + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "peer transmitted CR: %s\n", + s_isakmp_certtype(oakley_get_certtype(iph1->cr_p))); + + type = oakley_get_certtype(iph1->cr_p); + if (type != oakley_get_certtype(iph1->rmconf->mycert)) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "such a cert type isn't supported: %d\n", + type); + return -1; + } + + return 0; +} + +/* + * check to need CR payload. + */ +int +oakley_needcr(type) + int type; +{ + switch (type) { + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: +#endif + return 1; + default: + return 0; + } + /*NOTREACHED*/ +} + +/* + * compute SKEYID + * see seciton 5. Exchanges in RFC 2409 + * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b) + * sig: SKEYID = prf(Ni_b | Nr_b, g^ir) + * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R) + */ +int +oakley_skeyid(iph1) + struct ph1handle *iph1; +{ + vchar_t *buf = NULL, *bp; + char *p; + int len; + int error = -1; + + /* SKEYID */ + switch (iph1->approval->authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif + if (iph1->etype != ISAKMP_ETYPE_IDENT) { + iph1->authstr = getpskbyname(iph1->id_p); + if (iph1->authstr == NULL) { + if (iph1->rmconf->verify_identifier) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "couldn't find the pskey.\n"); + goto end; + } + plog(LLV_NOTIFY, LOCATION, iph1->remote, + "couldn't find the proper pskey, " + "try to get one by the peer's address.\n"); + } + } + if (iph1->authstr == NULL) { + /* + * If the exchange type is the main mode or if it's + * failed to get the psk by ID, racoon try to get + * the psk by remote IP address. + * It may be nonsense. + */ + iph1->authstr = getpskbyaddr(iph1->remote); + if (iph1->authstr == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "couldn't find the pskey for %s.\n", + saddrwop2str(iph1->remote)); + goto end; + } + } + plog(LLV_DEBUG, LOCATION, NULL, "the psk found.\n"); + /* should be secret PSK */ + plog(LLV_DEBUG2, LOCATION, NULL, "psk: "); + plogdump(LLV_DEBUG2, iph1->authstr->v, iph1->authstr->l); + + len = iph1->nonce->l + iph1->nonce_p->l; + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get skeyid buffer\n"); + goto end; + } + p = buf->v; + + bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p); + plog(LLV_DEBUG, LOCATION, NULL, "nonce 1: "); + plogdump(LLV_DEBUG, bp->v, bp->l); + memcpy(p, bp->v, bp->l); + p += bp->l; + + bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce); + plog(LLV_DEBUG, LOCATION, NULL, "nonce 2: "); + plogdump(LLV_DEBUG, bp->v, bp->l); + memcpy(p, bp->v, bp->l); + p += bp->l; + + iph1->skeyid = oakley_prf(iph1->authstr, buf, iph1); + if (iph1->skeyid == NULL) + goto end; + break; + + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: +#endif +#ifdef HAVE_GSSAPI + case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: +#endif + len = iph1->nonce->l + iph1->nonce_p->l; + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get nonce buffer\n"); + goto end; + } + p = buf->v; + + bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p); + plog(LLV_DEBUG, LOCATION, NULL, "nonce1: "); + plogdump(LLV_DEBUG, bp->v, bp->l); + memcpy(p, bp->v, bp->l); + p += bp->l; + + bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce); + plog(LLV_DEBUG, LOCATION, NULL, "nonce2: "); + plogdump(LLV_DEBUG, bp->v, bp->l); + memcpy(p, bp->v, bp->l); + p += bp->l; + + iph1->skeyid = oakley_prf(buf, iph1->dhgxy, iph1); + if (iph1->skeyid == NULL) + goto end; + break; + case OAKLEY_ATTR_AUTH_METHOD_RSAENC: + case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif + plog(LLV_WARNING, LOCATION, NULL, + "not supported authentication method %s\n", + s_oakley_attr_method(iph1->approval->authmethod)); + goto end; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid authentication method %d\n", + iph1->approval->authmethod); + goto end; + } + + plog(LLV_DEBUG, LOCATION, NULL, "SKEYID computed:\n"); + plogdump(LLV_DEBUG, iph1->skeyid->v, iph1->skeyid->l); + + error = 0; + +end: + if (buf != NULL) + vfree(buf); + return error; +} + +/* + * compute SKEYID_[dae] + * see seciton 5. Exchanges in RFC 2409 + * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0) + * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1) + * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2) + */ +int +oakley_skeyid_dae(iph1) + struct ph1handle *iph1; +{ + vchar_t *buf = NULL; + char *p; + int len; + int error = -1; + + if (iph1->skeyid == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n"); + goto end; + } + + /* SKEYID D */ + /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */ + len = iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1; + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get skeyid buffer\n"); + goto end; + } + p = buf->v; + + memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l); + p += iph1->dhgxy->l; + memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t)); + p += sizeof(cookie_t); + memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t)); + p += sizeof(cookie_t); + *p = 0; + iph1->skeyid_d = oakley_prf(iph1->skeyid, buf, iph1); + if (iph1->skeyid_d == NULL) + goto end; + + vfree(buf); + buf = NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_d computed:\n"); + plogdump(LLV_DEBUG, iph1->skeyid_d->v, iph1->skeyid_d->l); + + /* SKEYID A */ + /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */ + len = iph1->skeyid_d->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1; + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get skeyid buffer\n"); + goto end; + } + p = buf->v; + memcpy(p, iph1->skeyid_d->v, iph1->skeyid_d->l); + p += iph1->skeyid_d->l; + memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l); + p += iph1->dhgxy->l; + memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t)); + p += sizeof(cookie_t); + memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t)); + p += sizeof(cookie_t); + *p = 1; + iph1->skeyid_a = oakley_prf(iph1->skeyid, buf, iph1); + if (iph1->skeyid_a == NULL) + goto end; + + vfree(buf); + buf = NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_a computed:\n"); + plogdump(LLV_DEBUG, iph1->skeyid_a->v, iph1->skeyid_a->l); + + /* SKEYID E */ + /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */ + len = iph1->skeyid_a->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1; + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get skeyid buffer\n"); + goto end; + } + p = buf->v; + memcpy(p, iph1->skeyid_a->v, iph1->skeyid_a->l); + p += iph1->skeyid_a->l; + memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l); + p += iph1->dhgxy->l; + memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t)); + p += sizeof(cookie_t); + memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t)); + p += sizeof(cookie_t); + *p = 2; + iph1->skeyid_e = oakley_prf(iph1->skeyid, buf, iph1); + if (iph1->skeyid_e == NULL) + goto end; + + vfree(buf); + buf = NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_e computed:\n"); + plogdump(LLV_DEBUG, iph1->skeyid_e->v, iph1->skeyid_e->l); + + error = 0; + +end: + if (buf != NULL) + vfree(buf); + return error; +} + +/* + * compute final encryption key. + * see Appendix B. + */ +int +oakley_compute_enckey(iph1) + struct ph1handle *iph1; +{ + u_int keylen, prflen; + int error = -1; + + /* RFC2409 p39 */ + keylen = alg_oakley_encdef_keylen(iph1->approval->enctype, + iph1->approval->encklen); + if (keylen == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid encryption algorithm %d, " + "or invalid key length %d.\n", + iph1->approval->enctype, + iph1->approval->encklen); + goto end; + } + iph1->key = vmalloc(keylen >> 3); + if (iph1->key == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get key buffer\n"); + goto end; + } + + /* set prf length */ + prflen = alg_oakley_hashdef_hashlen(iph1->approval->hashtype); + if (prflen == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid hash type %d.\n", iph1->approval->hashtype); + goto end; + } + + /* see isakmp-oakley-08 5.3. */ + if (iph1->key->l <= iph1->skeyid_e->l) { + /* + * if length(Ka) <= length(SKEYID_e) + * Ka = first length(K) bit of SKEYID_e + */ + memcpy(iph1->key->v, iph1->skeyid_e->v, iph1->key->l); + } else { + vchar_t *buf = NULL, *res = NULL; + u_char *p, *ep; + int cplen; + int subkey; + + /* + * otherwise, + * Ka = K1 | K2 | K3 + * where + * K1 = prf(SKEYID_e, 0) + * K2 = prf(SKEYID_e, K1) + * K3 = prf(SKEYID_e, K2) + */ + plog(LLV_DEBUG, LOCATION, NULL, + "len(SKEYID_e) < len(Ka) (%zu < %zu), " + "generating long key (Ka = K1 | K2 | ...)\n", + iph1->skeyid_e->l, iph1->key->l); + + if ((buf = vmalloc(prflen >> 3)) == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get key buffer\n"); + goto end; + } + p = (u_char *)iph1->key->v; + ep = p + iph1->key->l; + + subkey = 1; + while (p < ep) { + if (p == (u_char *)iph1->key->v) { + /* just for computing K1 */ + buf->v[0] = 0; + buf->l = 1; + } + res = oakley_prf(iph1->skeyid_e, buf, iph1); + if (res == NULL) { + vfree(buf); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, + "compute intermediate encryption key K%d\n", + subkey); + plogdump(LLV_DEBUG, buf->v, buf->l); + plogdump(LLV_DEBUG, res->v, res->l); + + cplen = (res->l < ep - p) ? res->l : ep - p; + memcpy(p, res->v, cplen); + p += cplen; + + buf->l = prflen >> 3; /* to cancel K1 speciality */ + if (res->l != buf->l) { + plog(LLV_ERROR, LOCATION, NULL, + "internal error: res->l=%zu buf->l=%zu\n", + res->l, buf->l); + vfree(res); + vfree(buf); + goto end; + } + memcpy(buf->v, res->v, res->l); + vfree(res); + subkey++; + } + + vfree(buf); + } + + /* + * don't check any weak key or not. + * draft-ietf-ipsec-ike-01.txt Appendix B. + * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3. + */ +#if 0 + /* weakkey check */ + if (iph1->approval->enctype > ARRAYLEN(oakley_encdef) + || oakley_encdef[iph1->approval->enctype].weakkey == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "encryption algorithm %d isn't supported.\n", + iph1->approval->enctype); + goto end; + } + if ((oakley_encdef[iph1->approval->enctype].weakkey)(iph1->key)) { + plog(LLV_ERROR, LOCATION, NULL, + "weakkey was generated.\n"); + goto end; + } +#endif + + plog(LLV_DEBUG, LOCATION, NULL, "final encryption key computed:\n"); + plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l); + + error = 0; + +end: + return error; +} + +/* + * compute IV and set to ph1handle + * IV = hash(g^xi | g^xr) + * see 4.1 Phase 1 state in draft-ietf-ipsec-ike. + */ +int +oakley_newiv(iph1) + struct ph1handle *iph1; +{ + struct isakmp_ivm *newivm = NULL; + vchar_t *buf = NULL, *bp; + char *p; + int len; + + /* create buffer */ + len = iph1->dhpub->l + iph1->dhpub_p->l; + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get iv buffer\n"); + return -1; + } + + p = buf->v; + + bp = (iph1->side == INITIATOR ? iph1->dhpub : iph1->dhpub_p); + memcpy(p, bp->v, bp->l); + p += bp->l; + + bp = (iph1->side == INITIATOR ? iph1->dhpub_p : iph1->dhpub); + memcpy(p, bp->v, bp->l); + p += bp->l; + + /* allocate IVm */ + newivm = racoon_calloc(1, sizeof(struct isakmp_ivm)); + if (newivm == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get iv buffer\n"); + vfree(buf); + return -1; + } + + /* compute IV */ + newivm->iv = oakley_hash(buf, iph1); + if (newivm->iv == NULL) { + vfree(buf); + oakley_delivm(newivm); + return -1; + } + + /* adjust length of iv */ + newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype); + if (newivm->iv->l == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid encryption algorithm %d.\n", + iph1->approval->enctype); + vfree(buf); + oakley_delivm(newivm); + return -1; + } + + /* create buffer to save iv */ + if ((newivm->ive = vdup(newivm->iv)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "vdup (%s)\n", strerror(errno)); + vfree(buf); + oakley_delivm(newivm); + return -1; + } + + vfree(buf); + + plog(LLV_DEBUG, LOCATION, NULL, "IV computed:\n"); + plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l); + + iph1->ivm = newivm; + + return 0; +} + +/* + * compute IV for the payload after phase 1. + * It's not limited for phase 2. + * if pahse 1 was encrypted. + * IV = hash(last CBC block of Phase 1 | M-ID) + * if phase 1 was not encrypted. + * IV = hash(phase 1 IV | M-ID) + * see 4.2 Phase 2 state in draft-ietf-ipsec-ike. + */ +struct isakmp_ivm * +oakley_newiv2(iph1, msgid) + struct ph1handle *iph1; + u_int32_t msgid; +{ + struct isakmp_ivm *newivm = NULL; + vchar_t *buf = NULL; + char *p; + int len; + int error = -1; + + /* create buffer */ + len = iph1->ivm->iv->l + sizeof(msgid_t); + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get iv buffer\n"); + goto end; + } + + p = buf->v; + + memcpy(p, iph1->ivm->iv->v, iph1->ivm->iv->l); + p += iph1->ivm->iv->l; + + memcpy(p, &msgid, sizeof(msgid)); + + plog(LLV_DEBUG, LOCATION, NULL, "compute IV for phase2\n"); + plog(LLV_DEBUG, LOCATION, NULL, "phase1 last IV:\n"); + plogdump(LLV_DEBUG, buf->v, buf->l); + + /* allocate IVm */ + newivm = racoon_calloc(1, sizeof(struct isakmp_ivm)); + if (newivm == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get iv buffer\n"); + goto end; + } + + /* compute IV */ + if ((newivm->iv = oakley_hash(buf, iph1)) == NULL) + goto end; + + /* adjust length of iv */ + newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype); + if (newivm->iv->l == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid encryption algorithm %d.\n", + iph1->approval->enctype); + goto end; + } + + /* create buffer to save new iv */ + if ((newivm->ive = vdup(newivm->iv)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "vdup (%s)\n", strerror(errno)); + goto end; + } + + error = 0; + + plog(LLV_DEBUG, LOCATION, NULL, "phase2 IV computed:\n"); + plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l); + +end: + if (error && newivm != NULL){ + oakley_delivm(newivm); + newivm=NULL; + } + if (buf != NULL) + vfree(buf); + return newivm; +} + +void +oakley_delivm(ivm) + struct isakmp_ivm *ivm; +{ + if (ivm == NULL) + return; + + if (ivm->iv != NULL) + vfree(ivm->iv); + if (ivm->ive != NULL) + vfree(ivm->ive); + racoon_free(ivm); + plog(LLV_DEBUG, LOCATION, NULL, "IV freed\n"); + + return; +} + +/* + * decrypt packet. + * save new iv and old iv. + */ +vchar_t * +oakley_do_decrypt(iph1, msg, ivdp, ivep) + struct ph1handle *iph1; + vchar_t *msg, *ivdp, *ivep; +{ + vchar_t *buf = NULL, *new = NULL; + char *pl; + int len; + u_int8_t padlen; + int blen; + int error = -1; + + plog(LLV_DEBUG, LOCATION, NULL, "begin decryption.\n"); + + blen = alg_oakley_encdef_blocklen(iph1->approval->enctype); + if (blen == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid encryption algorithm %d.\n", + iph1->approval->enctype); + goto end; + } + + /* save IV for next, but not sync. */ + memset(ivep->v, 0, ivep->l); + memcpy(ivep->v, (caddr_t)&msg->v[msg->l - blen], blen); + + plog(LLV_DEBUG, LOCATION, NULL, + "IV was saved for next processing:\n"); + plogdump(LLV_DEBUG, ivep->v, ivep->l); + + pl = msg->v + sizeof(struct isakmp); + + len = msg->l - sizeof(struct isakmp); + + /* create buffer */ + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to decrypt.\n"); + goto end; + } + memcpy(buf->v, pl, len); + + /* do decrypt */ + new = alg_oakley_encdef_decrypt(iph1->approval->enctype, + buf, iph1->key, ivdp); + if (new == NULL || new->v == NULL || new->l == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "decryption %d failed.\n", iph1->approval->enctype); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "with key:\n"); + plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l); + + vfree(buf); + buf = NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "decrypted payload by IV:\n"); + plogdump(LLV_DEBUG, ivdp->v, ivdp->l); + + plog(LLV_DEBUG, LOCATION, NULL, + "decrypted payload, but not trimed.\n"); + plogdump(LLV_DEBUG, new->v, new->l); + + /* get padding length */ + if (lcconf->pad_excltail) + padlen = new->v[new->l - 1] + 1; + else + padlen = new->v[new->l - 1]; + plog(LLV_DEBUG, LOCATION, NULL, "padding len=%u\n", padlen); + + /* trim padding */ + if (lcconf->pad_strict) { + if (padlen > new->l) { + plog(LLV_ERROR, LOCATION, NULL, + "invalied padding len=%u, buflen=%zu.\n", + padlen, new->l); + plogdump(LLV_ERROR, new->v, new->l); + goto end; + } + new->l -= padlen; + plog(LLV_DEBUG, LOCATION, NULL, "trimmed padding\n"); + } else { + plog(LLV_DEBUG, LOCATION, NULL, "skip to trim padding.\n"); + } + + /* create new buffer */ + len = sizeof(struct isakmp) + new->l; + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to decrypt.\n"); + goto end; + } + memcpy(buf->v, msg->v, sizeof(struct isakmp)); + memcpy(buf->v + sizeof(struct isakmp), new->v, new->l); + ((struct isakmp *)buf->v)->len = htonl(buf->l); + + plog(LLV_DEBUG, LOCATION, NULL, "decrypted.\n"); + plogdump(LLV_DEBUG, buf->v, buf->l); + +#ifdef HAVE_PRINT_ISAKMP_C + isakmp_printpacket(buf, iph1->remote, iph1->local, 1); +#endif + + error = 0; + +end: + if (error && buf != NULL) { + vfree(buf); + buf = NULL; + } + if (new != NULL) + vfree(new); + + return buf; +} + +/* + * encrypt packet. + */ +vchar_t * +oakley_do_encrypt(iph1, msg, ivep, ivp) + struct ph1handle *iph1; + vchar_t *msg, *ivep, *ivp; +{ + vchar_t *buf = 0, *new = 0; + char *pl; + int len; + u_int padlen; + int blen; + int error = -1; + + plog(LLV_DEBUG, LOCATION, NULL, "begin encryption.\n"); + + /* set cbc block length */ + blen = alg_oakley_encdef_blocklen(iph1->approval->enctype); + if (blen == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid encryption algorithm %d.\n", + iph1->approval->enctype); + goto end; + } + + pl = msg->v + sizeof(struct isakmp); + len = msg->l - sizeof(struct isakmp); + + /* add padding */ + padlen = oakley_padlen(len, blen); + plog(LLV_DEBUG, LOCATION, NULL, "pad length = %u\n", padlen); + + /* create buffer */ + buf = vmalloc(len + padlen); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to encrypt.\n"); + goto end; + } + if (padlen) { + int i; + char *p = &buf->v[len]; + if (lcconf->pad_random) { + for (i = 0; i < padlen; i++) + *p++ = eay_random() & 0xff; + } + } + memcpy(buf->v, pl, len); + + /* make pad into tail */ + if (lcconf->pad_excltail) + buf->v[len + padlen - 1] = padlen - 1; + else + buf->v[len + padlen - 1] = padlen; + + plogdump(LLV_DEBUG, buf->v, buf->l); + + /* do encrypt */ + new = alg_oakley_encdef_encrypt(iph1->approval->enctype, + buf, iph1->key, ivep); + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "encryption %d failed.\n", iph1->approval->enctype); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "with key:\n"); + plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l); + + vfree(buf); + buf = NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "encrypted payload by IV:\n"); + plogdump(LLV_DEBUG, ivep->v, ivep->l); + + /* save IV for next */ + memset(ivp->v, 0, ivp->l); + memcpy(ivp->v, (caddr_t)&new->v[new->l - blen], blen); + + plog(LLV_DEBUG, LOCATION, NULL, "save IV for next:\n"); + plogdump(LLV_DEBUG, ivp->v, ivp->l); + + /* create new buffer */ + len = sizeof(struct isakmp) + new->l; + buf = vmalloc(len); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to encrypt.\n"); + goto end; + } + memcpy(buf->v, msg->v, sizeof(struct isakmp)); + memcpy(buf->v + sizeof(struct isakmp), new->v, new->l); + ((struct isakmp *)buf->v)->len = htonl(buf->l); + + error = 0; + + plog(LLV_DEBUG, LOCATION, NULL, "encrypted.\n"); + +end: + if (error && buf != NULL) { + vfree(buf); + buf = NULL; + } + if (new != NULL) + vfree(new); + + return buf; +} + +/* culculate padding length */ +static int +oakley_padlen(len, base) + int len, base; +{ + int padlen; + + padlen = base - len % base; + + if (lcconf->pad_randomlen) + padlen += ((eay_random() % (lcconf->pad_maxsize + 1) + 1) * + base); + + return padlen; +} + diff --git a/ipsec-tools/src/racoon/oakley.h b/ipsec-tools/src/racoon/oakley.h new file mode 100644 index 00000000..f8cdb761 --- /dev/null +++ b/ipsec-tools/src/racoon/oakley.h @@ -0,0 +1,218 @@ +/* $NetBSD: oakley.h,v 1.7 2009/03/12 10:57:26 tteras Exp $ */ + +/* Id: oakley.h,v 1.13 2005/05/30 20:12:43 fredsen Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _OAKLEY_H +#define _OAKLEY_H + +#include "vmbuf.h" + +/* refer to RFC 2409 */ + +/* Attribute Classes */ +#define OAKLEY_ATTR_ENC_ALG 1 /* B */ +#define OAKLEY_ATTR_ENC_ALG_DES 1 +#define OAKLEY_ATTR_ENC_ALG_IDEA 2 +#define OAKLEY_ATTR_ENC_ALG_BLOWFISH 3 +#define OAKLEY_ATTR_ENC_ALG_RC5 4 +#define OAKLEY_ATTR_ENC_ALG_3DES 5 +#define OAKLEY_ATTR_ENC_ALG_CAST 6 +#define OAKLEY_ATTR_ENC_ALG_AES 7 +#define OAKLEY_ATTR_ENC_ALG_CAMELLIA 8 + /* 65001 - 65535 Private Use */ +#define OAKLEY_ATTR_HASH_ALG 2 /* B */ +#define OAKLEY_ATTR_HASH_ALG_MD5 1 +#define OAKLEY_ATTR_HASH_ALG_SHA 2 +#define OAKLEY_ATTR_HASH_ALG_TIGER 3 +#if defined(WITH_SHA2) +#define OAKLEY_ATTR_HASH_ALG_SHA2_256 4 +#define OAKLEY_ATTR_HASH_ALG_SHA2_384 5 +#define OAKLEY_ATTR_HASH_ALG_SHA2_512 6 +#endif + /* 65001 - 65535 Private Use */ +#define OAKLEY_ATTR_AUTH_METHOD 3 /* B */ +#define OAKLEY_ATTR_AUTH_METHOD_PSKEY 1 +#define OAKLEY_ATTR_AUTH_METHOD_DSSSIG 2 +#define OAKLEY_ATTR_AUTH_METHOD_RSASIG 3 +#define OAKLEY_ATTR_AUTH_METHOD_RSAENC 4 +#define OAKLEY_ATTR_AUTH_METHOD_RSAREV 5 +#define OAKLEY_ATTR_AUTH_METHOD_EGENC 6 +#define OAKLEY_ATTR_AUTH_METHOD_EGREV 7 + /* Hybrid Auth */ +#ifdef ENABLE_HYBRID +#define OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I 64221 +#define OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R 64222 +#define OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I 64223 +#define OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R 64224 + + /* 65001 - 65535 Private Use */ + + /* Plain Xauth */ +#define OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I 65001 +#define OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R 65002 +#define OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I 65003 +#define OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R 65004 +#define OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I 65005 +#define OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R 65006 +#define OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I 65007 +#define OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R 65008 +#define OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I 65009 +#define OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R 65010 +#endif + +/* + * The following are valid when the Vendor ID is one of + * the following: + * + * MD5("A GSS-API Authentication Method for IKE") + * MD5("GSSAPI") (recognized by Windows 2000) + * MD5("MS NT5 ISAKMPOAKLEY") (sent by Windows 2000) + */ + +#define OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB (65001 + 0x10000) +#define OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB_REAL 65001 + +#define OAKLEY_ATTR_GRP_DESC 4 /* B */ +#define OAKLEY_ATTR_GRP_DESC_MODP768 1 +#define OAKLEY_ATTR_GRP_DESC_MODP1024 2 +#define OAKLEY_ATTR_GRP_DESC_EC2N155 3 +#define OAKLEY_ATTR_GRP_DESC_EC2N185 4 +#define OAKLEY_ATTR_GRP_DESC_MODP1536 5 +#define OAKLEY_ATTR_GRP_DESC_MODP2048 14 +#define OAKLEY_ATTR_GRP_DESC_MODP3072 15 +#define OAKLEY_ATTR_GRP_DESC_MODP4096 16 +#define OAKLEY_ATTR_GRP_DESC_MODP6144 17 +#define OAKLEY_ATTR_GRP_DESC_MODP8192 18 + /* 32768 - 65535 Private Use */ +#define OAKLEY_ATTR_GRP_TYPE 5 /* B */ +#define OAKLEY_ATTR_GRP_TYPE_MODP 1 +#define OAKLEY_ATTR_GRP_TYPE_ECP 2 +#define OAKLEY_ATTR_GRP_TYPE_EC2N 3 + /* 65001 - 65535 Private Use */ +#define OAKLEY_ATTR_GRP_PI 6 /* V */ +#define OAKLEY_ATTR_GRP_GEN_ONE 7 /* V */ +#define OAKLEY_ATTR_GRP_GEN_TWO 8 /* V */ +#define OAKLEY_ATTR_GRP_CURVE_A 9 /* V */ +#define OAKLEY_ATTR_GRP_CURVE_B 10 /* V */ +#define OAKLEY_ATTR_SA_LD_TYPE 11 /* B */ +#define OAKLEY_ATTR_SA_LD_TYPE_DEFAULT 1 +#define OAKLEY_ATTR_SA_LD_TYPE_SEC 1 +#define OAKLEY_ATTR_SA_LD_TYPE_KB 2 +#define OAKLEY_ATTR_SA_LD_TYPE_MAX 3 + /* 65001 - 65535 Private Use */ +#define OAKLEY_ATTR_SA_LD 12 /* V */ +#define OAKLEY_ATTR_SA_LD_SEC_DEFAULT 28800 /* 8 hours */ +#define OAKLEY_ATTR_PRF 13 /* B */ +#define OAKLEY_ATTR_KEY_LEN 14 /* B */ +#define OAKLEY_ATTR_FIELD_SIZE 15 /* B */ +#define OAKLEY_ATTR_GRP_ORDER 16 /* V */ +#define OAKLEY_ATTR_BLOCK_SIZE 17 /* B */ + /* 16384 - 32767 Private Use */ + + /* + * The following are valid when the Vendor ID is one of + * the following: + * + * MD5("A GSS-API Authentication Method for IKE") + * MD5("GSSAPI") (recognized by Windows 2000) + * MD5("MS NT5 ISAKMPOAKLEY") (sent by Windows 2000) + */ +#define OAKLEY_ATTR_GSS_ID 16384 + +#define MAXPADLWORD 20 + +struct dhgroup { + int type; + vchar_t *prime; + int gen1; + int gen2; + vchar_t *curve_a; + vchar_t *curve_b; + vchar_t *order; +}; + +struct ph1handle; +struct ph2handle; +struct isakmp_ivm; + +extern int oakley_get_defaultlifetime __P((void)); + +extern int oakley_dhinit __P((void)); +extern void oakley_dhgrp_free __P((struct dhgroup *)); +extern int oakley_dh_compute __P((const struct dhgroup *, + vchar_t *, vchar_t *, vchar_t *, vchar_t **)); +extern int oakley_dh_generate __P((const struct dhgroup *, + vchar_t **, vchar_t **)); +extern int oakley_setdhgroup __P((int, struct dhgroup **)); + +extern vchar_t *oakley_prf __P((vchar_t *, vchar_t *, struct ph1handle *)); +extern vchar_t *oakley_hash __P((vchar_t *, struct ph1handle *)); + +extern int oakley_compute_keymat __P((struct ph2handle *, int)); + +#if notyet +extern vchar_t *oakley_compute_hashx __P((void)); +#endif +extern vchar_t *oakley_compute_hash3 __P((struct ph1handle *, + u_int32_t, vchar_t *)); +extern vchar_t *oakley_compute_hash1 __P((struct ph1handle *, + u_int32_t, vchar_t *)); +extern vchar_t *oakley_ph1hash_common __P((struct ph1handle *, int)); +extern vchar_t *oakley_ph1hash_base_i __P((struct ph1handle *, int)); +extern vchar_t *oakley_ph1hash_base_r __P((struct ph1handle *, int)); + +extern int oakley_get_certtype __P((vchar_t *)); +extern int oakley_validate_auth __P((struct ph1handle *)); +extern int oakley_getmycert __P((struct ph1handle *)); +extern int oakley_getsign __P((struct ph1handle *)); +extern vchar_t *oakley_getcr __P((struct ph1handle *)); +extern struct payload_list *oakley_append_cr __P((struct payload_list *, + struct ph1handle *)); +extern int oakley_checkcr __P((struct ph1handle *)); +extern int oakley_needcr __P((int)); +struct isakmp_gen; +extern int oakley_savecert __P((struct ph1handle *, struct isakmp_gen *)); +extern int oakley_savecr __P((struct ph1handle *, struct isakmp_gen *)); + +extern int oakley_skeyid __P((struct ph1handle *)); +extern int oakley_skeyid_dae __P((struct ph1handle *)); + +extern int oakley_compute_enckey __P((struct ph1handle *)); +extern int oakley_newiv __P((struct ph1handle *)); +extern struct isakmp_ivm *oakley_newiv2 __P((struct ph1handle *, u_int32_t)); +extern void oakley_delivm __P((struct isakmp_ivm *)); +extern vchar_t *oakley_do_decrypt __P((struct ph1handle *, + vchar_t *, vchar_t *, vchar_t *)); +extern vchar_t *oakley_do_encrypt __P((struct ph1handle *, + vchar_t *, vchar_t *, vchar_t *)); + +#endif /* _OAKLEY_H */ diff --git a/ipsec-tools/src/racoon/pfkey.c b/ipsec-tools/src/racoon/pfkey.c new file mode 100644 index 00000000..d00b166d --- /dev/null +++ b/ipsec-tools/src/racoon/pfkey.c @@ -0,0 +1,3993 @@ +/* $NetBSD: pfkey.c,v 1.57 2011/03/15 13:20:14 vanhu Exp $ */ + +/* $Id: pfkey.c,v 1.57 2011/03/15 13:20:14 vanhu Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include + +#ifdef ENABLE_NATT +# ifdef __linux__ +# include +# endif +# if defined(__NetBSD__) || defined(__FreeBSD__) || \ + (defined(__APPLE__) && defined(__MACH__)) +# include +# endif +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include PATH_IPSEC_H +#include + +#include "libpfkey.h" + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "session.h" +#include "debug.h" + +#include "schedule.h" +#include "localconf.h" +#include "remoteconf.h" +#include "handler.h" +#include "policy.h" +#include "proposal.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "isakmp_inf.h" +#include "ipsec_doi.h" +#include "oakley.h" +#include "pfkey.h" +#include "algorithm.h" +#include "sainfo.h" +#include "admin.h" +#include "evt.h" +#include "privsep.h" +#include "strnames.h" +#include "backupsa.h" +#include "gcmalloc.h" +#include "nattraversal.h" +#include "crypto_openssl.h" +#include "grabmyaddr.h" + +#if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC) +#define SADB_X_EALG_AESCBC SADB_X_EALG_RIJNDAELCBC +#endif + +/* prototype */ +static u_int ipsecdoi2pfkey_aalg __P((u_int)); +static u_int ipsecdoi2pfkey_ealg __P((u_int)); +static u_int ipsecdoi2pfkey_calg __P((u_int)); +static u_int ipsecdoi2pfkey_alg __P((u_int, u_int)); +static u_int keylen_aalg __P((u_int)); +static u_int keylen_ealg __P((u_int, int)); + +static int pk_recvgetspi __P((caddr_t *)); +static int pk_recvupdate __P((caddr_t *)); +static int pk_recvadd __P((caddr_t *)); +static int pk_recvdelete __P((caddr_t *)); +static int pk_recvacquire __P((caddr_t *)); +static int pk_recvexpire __P((caddr_t *)); +static int pk_recvflush __P((caddr_t *)); +static int getsadbpolicy __P((caddr_t *, int *, int, struct ph2handle *)); +static int pk_recvspdupdate __P((caddr_t *)); +static int pk_recvspdadd __P((caddr_t *)); +static int pk_recvspddelete __P((caddr_t *)); +static int pk_recvspdexpire __P((caddr_t *)); +static int pk_recvspdget __P((caddr_t *)); +static int pk_recvspddump __P((caddr_t *)); +static int pk_recvspdflush __P((caddr_t *)); +#if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS) +static int pk_recvmigrate __P((caddr_t *)); +#endif +static struct sadb_msg *pk_recv __P((int, int *)); + +static int (*pkrecvf[]) __P((caddr_t *)) = { +NULL, +pk_recvgetspi, +pk_recvupdate, +pk_recvadd, +pk_recvdelete, +NULL, /* SADB_GET */ +pk_recvacquire, +NULL, /* SABD_REGISTER */ +pk_recvexpire, +pk_recvflush, +NULL, /* SADB_DUMP */ +NULL, /* SADB_X_PROMISC */ +NULL, /* SADB_X_PCHANGE */ +pk_recvspdupdate, +pk_recvspdadd, +pk_recvspddelete, +pk_recvspdget, +NULL, /* SADB_X_SPDACQUIRE */ +pk_recvspddump, +pk_recvspdflush, +NULL, /* SADB_X_SPDSETIDX */ +pk_recvspdexpire, +NULL, /* SADB_X_SPDDELETE2 */ +NULL, /* SADB_X_NAT_T_NEW_MAPPING */ +#if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS) +pk_recvmigrate, +#else +NULL, /* SADB_X_MIGRATE */ +#endif +#if (SADB_MAX > 24) +#error "SADB extra message?" +#endif +}; + +static int addnewsp __P((caddr_t *, struct sockaddr *, struct sockaddr *)); + +/* cope with old kame headers - ugly */ +#ifndef SADB_X_AALG_MD5 +#define SADB_X_AALG_MD5 SADB_AALG_MD5 +#endif +#ifndef SADB_X_AALG_SHA +#define SADB_X_AALG_SHA SADB_AALG_SHA +#endif +#ifndef SADB_X_AALG_NULL +#define SADB_X_AALG_NULL SADB_AALG_NULL +#endif + +#ifndef SADB_X_EALG_BLOWFISHCBC +#define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC +#endif +#ifndef SADB_X_EALG_CAST128CBC +#define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC +#endif +#ifndef SADB_X_EALG_RC5CBC +#ifdef SADB_EALG_RC5CBC +#define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC +#endif +#endif + +/* + * PF_KEY packet handler + * 0: success + * -1: fail + */ +static int +pfkey_handler(ctx, fd) + void *ctx; + int fd; +{ + struct sadb_msg *msg; + int len; + caddr_t mhp[SADB_EXT_MAX + 1]; + int error = -1; + + /* receive pfkey message. */ + len = 0; + msg = (struct sadb_msg *) pk_recv(fd, &len); + if (msg == NULL) { + if (len < 0) { + /* do not report EAGAIN as error; well get + * called from main loop later. and it's normal + * when spd dump is received during reload and + * this function is called in loop. */ + if (errno == EAGAIN) + goto end; + + plog(LLV_ERROR, LOCATION, NULL, + "failed to recv from pfkey (%s)\n", + strerror(errno)); + goto end; + } else { + /* short message - msg not ready */ + return 0; + } + } + + plog(LLV_DEBUG, LOCATION, NULL, "got pfkey %s message\n", + s_pfkey_type(msg->sadb_msg_type)); + plogdump(LLV_DEBUG2, msg, msg->sadb_msg_len << 3); + + /* validity check */ + if (msg->sadb_msg_errno) { + int pri; + + /* when SPD is empty, treat the state as no error. */ + if (msg->sadb_msg_type == SADB_X_SPDDUMP && + msg->sadb_msg_errno == ENOENT) + pri = LLV_DEBUG; + else + pri = LLV_ERROR; + + plog(pri, LOCATION, NULL, + "pfkey %s failed: %s\n", + s_pfkey_type(msg->sadb_msg_type), + strerror(msg->sadb_msg_errno)); + + goto end; + } + + /* check pfkey message. */ + if (pfkey_align(msg, mhp)) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed pfkey align (%s)\n", + ipsec_strerror()); + goto end; + } + if (pfkey_check(mhp)) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed pfkey check (%s)\n", + ipsec_strerror()); + goto end; + } + msg = (struct sadb_msg *)mhp[0]; + + /* safety check */ + if (msg->sadb_msg_type >= ARRAYLEN(pkrecvf)) { + plog(LLV_ERROR, LOCATION, NULL, + "unknown PF_KEY message type=%u\n", + msg->sadb_msg_type); + goto end; + } + + if (pkrecvf[msg->sadb_msg_type] == NULL) { + plog(LLV_INFO, LOCATION, NULL, + "unsupported PF_KEY message %s\n", + s_pfkey_type(msg->sadb_msg_type)); + goto end; + } + + if ((pkrecvf[msg->sadb_msg_type])(mhp) < 0) + goto end; + + error = 1; +end: + if (msg) + racoon_free(msg); + return(error); +} + +/* + * dump SADB + */ +vchar_t * +pfkey_dump_sadb(satype) + int satype; +{ + int s; + vchar_t *buf = NULL; + pid_t pid = getpid(); + struct sadb_msg *msg = NULL; + size_t bl, ml; + int len; + int bufsiz; + + if ((s = privsep_socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed pfkey open: %s\n", + ipsec_strerror()); + return NULL; + } + + if ((bufsiz = pfkey_set_buffer_size(s, lcconf->pfkey_buffer_size)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed pfkey set buffer size to %d: %s\n", + lcconf->pfkey_buffer_size, ipsec_strerror()); + return NULL; + } else if (bufsiz < lcconf->pfkey_buffer_size) { + plog(LLV_WARNING, LOCATION, NULL, + "pfkey socket receive buffer set to %dKB, instead of %d\n", + bufsiz, lcconf->pfkey_buffer_size); + } + + plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_dump\n"); + if (pfkey_send_dump(s, satype) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed dump: %s\n", ipsec_strerror()); + goto fail; + } + + while (1) { + if (msg) + racoon_free(msg); + msg = pk_recv(s, &len); + if (msg == NULL) { + if (len < 0) + goto done; + else + continue; + } + + if (msg->sadb_msg_type != SADB_DUMP || msg->sadb_msg_pid != pid) + { + plog(LLV_DEBUG, LOCATION, NULL, + "discarding non-sadb dump msg %p, our pid=%i\n", msg, pid); + plog(LLV_DEBUG, LOCATION, NULL, + "type %i, pid %i\n", msg->sadb_msg_type, msg->sadb_msg_pid); + continue; + } + + + ml = msg->sadb_msg_len << 3; + bl = buf ? buf->l : 0; + buf = vrealloc(buf, bl + ml); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to reallocate buffer to dump.\n"); + goto fail; + } + memcpy(buf->v + bl, msg, ml); + + if (msg->sadb_msg_seq == 0) + break; + } + goto done; + +fail: + if (buf) + vfree(buf); + buf = NULL; +done: + if (msg) + racoon_free(msg); + close(s); + return buf; +} + +#ifdef ENABLE_ADMINPORT +/* + * flush SADB + */ +void +pfkey_flush_sadb(proto) + u_int proto; +{ + int satype; + + /* convert to SADB_SATYPE */ + if ((satype = admin2pfkey_proto(proto)) < 0) + return; + + plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_flush\n"); + if (pfkey_send_flush(lcconf->sock_pfkey, satype) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed send flush (%s)\n", ipsec_strerror()); + return; + } + + return; +} +#endif + +/* + * These are the SATYPEs that we manage. We register to get + * PF_KEY messages related to these SATYPEs, and we also use + * this list to determine which SATYPEs to delete SAs for when + * we receive an INITIAL-CONTACT. + */ +const struct pfkey_satype pfkey_satypes[] = { + { SADB_SATYPE_AH, "AH" }, + { SADB_SATYPE_ESP, "ESP" }, + { SADB_X_SATYPE_IPCOMP, "IPCOMP" }, +}; +const int pfkey_nsatypes = + sizeof(pfkey_satypes) / sizeof(pfkey_satypes[0]); + +/* + * PF_KEY initialization + */ +int +pfkey_init() +{ + int i, reg_fail; + int bufsiz; + + if ((lcconf->sock_pfkey = pfkey_open()) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed pfkey open (%s)\n", ipsec_strerror()); + return -1; + } + if ((bufsiz = pfkey_set_buffer_size(lcconf->sock_pfkey, + lcconf->pfkey_buffer_size)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed to set pfkey buffer size to %d (%s)\n", + lcconf->pfkey_buffer_size, ipsec_strerror()); + return -1; + } else if (bufsiz < lcconf->pfkey_buffer_size) { + plog(LLV_WARNING, LOCATION, NULL, + "pfkey socket receive buffer set to %dKB, instead of %d\n", + bufsiz, lcconf->pfkey_buffer_size); + } + + if (fcntl(lcconf->sock_pfkey, F_SETFL, O_NONBLOCK) == -1) + plog(LLV_WARNING, LOCATION, NULL, + "failed to set the pfkey socket to NONBLOCK\n"); + + for (i = 0, reg_fail = 0; i < pfkey_nsatypes; i++) { + plog(LLV_DEBUG, LOCATION, NULL, + "call pfkey_send_register for %s\n", + pfkey_satypes[i].ps_name); + if (pfkey_send_register(lcconf->sock_pfkey, + pfkey_satypes[i].ps_satype) < 0 || + pfkey_recv_register(lcconf->sock_pfkey) < 0) { + plog(LLV_WARNING, LOCATION, NULL, + "failed to register %s (%s)\n", + pfkey_satypes[i].ps_name, + ipsec_strerror()); + reg_fail++; + } + } + + if (reg_fail == pfkey_nsatypes) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to regist any protocol.\n"); + pfkey_close(lcconf->sock_pfkey); + return -1; + } + + initsp(); + + if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec sending spddump failed: %s\n", + ipsec_strerror()); + pfkey_close(lcconf->sock_pfkey); + return -1; + } +#if 0 + if (pfkey_promisc_toggle(1) < 0) { + pfkey_close(lcconf->sock_pfkey); + return -1; + } +#endif + monitor_fd(lcconf->sock_pfkey, pfkey_handler, NULL, 0); + return 0; +} + +int +pfkey_reload() +{ + flushsp(); + + if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec sending spddump failed: %s\n", + ipsec_strerror()); + return -1; + } + + while (pfkey_handler(NULL, lcconf->sock_pfkey) > 0) + continue; + + return 0; +} + +/* %%% for conversion */ +/* IPSECDOI_ATTR_AUTH -> SADB_AALG */ +static u_int +ipsecdoi2pfkey_aalg(hashtype) + u_int hashtype; +{ + switch (hashtype) { + case IPSECDOI_ATTR_AUTH_HMAC_MD5: + return SADB_AALG_MD5HMAC; + case IPSECDOI_ATTR_AUTH_HMAC_SHA1: + return SADB_AALG_SHA1HMAC; + case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256: +#if (defined SADB_X_AALG_SHA2_256) && !defined(SADB_X_AALG_SHA2_256HMAC) + return SADB_X_AALG_SHA2_256; +#else + return SADB_X_AALG_SHA2_256HMAC; +#endif + case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384: +#if (defined SADB_X_AALG_SHA2_384) && !defined(SADB_X_AALG_SHA2_384HMAC) + return SADB_X_AALG_SHA2_384; +#else + return SADB_X_AALG_SHA2_384HMAC; +#endif + case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512: +#if (defined SADB_X_AALG_SHA2_512) && !defined(SADB_X_AALG_SHA2_512HMAC) + return SADB_X_AALG_SHA2_512; +#else + return SADB_X_AALG_SHA2_512HMAC; +#endif + case IPSECDOI_ATTR_AUTH_KPDK: /* need special care */ + return SADB_AALG_NONE; + + /* not supported */ + case IPSECDOI_ATTR_AUTH_DES_MAC: + plog(LLV_ERROR, LOCATION, NULL, + "Not supported hash type: %u\n", hashtype); + return ~0; + + case 0: /* reserved */ + default: + return SADB_AALG_NONE; + + plog(LLV_ERROR, LOCATION, NULL, + "Invalid hash type: %u\n", hashtype); + return ~0; + } + /*NOTREACHED*/ +} + +/* IPSECDOI_ESP -> SADB_EALG */ +static u_int +ipsecdoi2pfkey_ealg(t_id) + u_int t_id; +{ + switch (t_id) { + case IPSECDOI_ESP_DES_IV64: /* sa_flags |= SADB_X_EXT_OLD */ + return SADB_EALG_DESCBC; + case IPSECDOI_ESP_DES: + return SADB_EALG_DESCBC; + case IPSECDOI_ESP_3DES: + return SADB_EALG_3DESCBC; +#ifdef SADB_X_EALG_RC5CBC + case IPSECDOI_ESP_RC5: + return SADB_X_EALG_RC5CBC; +#endif + case IPSECDOI_ESP_CAST: + return SADB_X_EALG_CAST128CBC; + case IPSECDOI_ESP_BLOWFISH: + return SADB_X_EALG_BLOWFISHCBC; + case IPSECDOI_ESP_DES_IV32: /* flags |= (SADB_X_EXT_OLD| + SADB_X_EXT_IV4B)*/ + return SADB_EALG_DESCBC; + case IPSECDOI_ESP_NULL: + return SADB_EALG_NULL; +#ifdef SADB_X_EALG_AESCBC + case IPSECDOI_ESP_AES: + return SADB_X_EALG_AESCBC; +#endif +#ifdef SADB_X_EALG_TWOFISHCBC + case IPSECDOI_ESP_TWOFISH: + return SADB_X_EALG_TWOFISHCBC; +#endif +#ifdef SADB_X_EALG_CAMELLIACBC + case IPSECDOI_ESP_CAMELLIA: + return SADB_X_EALG_CAMELLIACBC; +#endif + + /* not supported */ + case IPSECDOI_ESP_3IDEA: + case IPSECDOI_ESP_IDEA: + case IPSECDOI_ESP_RC4: + plog(LLV_ERROR, LOCATION, NULL, + "Not supported transform: %u\n", t_id); + return ~0; + + case 0: /* reserved */ + default: + plog(LLV_ERROR, LOCATION, NULL, + "Invalid transform id: %u\n", t_id); + return ~0; + } + /*NOTREACHED*/ +} + +/* IPCOMP -> SADB_CALG */ +static u_int +ipsecdoi2pfkey_calg(t_id) + u_int t_id; +{ + switch (t_id) { + case IPSECDOI_IPCOMP_OUI: + return SADB_X_CALG_OUI; + case IPSECDOI_IPCOMP_DEFLATE: + return SADB_X_CALG_DEFLATE; + case IPSECDOI_IPCOMP_LZS: + return SADB_X_CALG_LZS; + + case 0: /* reserved */ + default: + plog(LLV_ERROR, LOCATION, NULL, + "Invalid transform id: %u\n", t_id); + return ~0; + } + /*NOTREACHED*/ +} + +/* IPSECDOI_PROTO -> SADB_SATYPE */ +u_int +ipsecdoi2pfkey_proto(proto) + u_int proto; +{ + switch (proto) { + case IPSECDOI_PROTO_IPSEC_AH: + return SADB_SATYPE_AH; + case IPSECDOI_PROTO_IPSEC_ESP: + return SADB_SATYPE_ESP; + case IPSECDOI_PROTO_IPCOMP: + return SADB_X_SATYPE_IPCOMP; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "Invalid ipsec_doi proto: %u\n", proto); + return ~0; + } + /*NOTREACHED*/ +} + +static u_int +ipsecdoi2pfkey_alg(algclass, type) + u_int algclass, type; +{ + switch (algclass) { + case IPSECDOI_ATTR_AUTH: + return ipsecdoi2pfkey_aalg(type); + case IPSECDOI_PROTO_IPSEC_ESP: + return ipsecdoi2pfkey_ealg(type); + case IPSECDOI_PROTO_IPCOMP: + return ipsecdoi2pfkey_calg(type); + default: + plog(LLV_ERROR, LOCATION, NULL, + "Invalid ipsec_doi algclass: %u\n", algclass); + return ~0; + } + /*NOTREACHED*/ +} + +/* SADB_SATYPE -> IPSECDOI_PROTO */ +u_int +pfkey2ipsecdoi_proto(satype) + u_int satype; +{ + switch (satype) { + case SADB_SATYPE_AH: + return IPSECDOI_PROTO_IPSEC_AH; + case SADB_SATYPE_ESP: + return IPSECDOI_PROTO_IPSEC_ESP; + case SADB_X_SATYPE_IPCOMP: + return IPSECDOI_PROTO_IPCOMP; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "Invalid pfkey proto: %u\n", satype); + return ~0; + } + /*NOTREACHED*/ +} + +/* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */ +u_int +ipsecdoi2pfkey_mode(mode) + u_int mode; +{ + switch (mode) { + case IPSECDOI_ATTR_ENC_MODE_TUNNEL: +#ifdef ENABLE_NATT + case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC: + case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT: +#endif + return IPSEC_MODE_TUNNEL; + case IPSECDOI_ATTR_ENC_MODE_TRNS: +#ifdef ENABLE_NATT + case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC: + case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT: +#endif + return IPSEC_MODE_TRANSPORT; + default: + plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode); + return ~0; + } + /*NOTREACHED*/ +} + +/* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */ +u_int +pfkey2ipsecdoi_mode(mode) + u_int mode; +{ + switch (mode) { + case IPSEC_MODE_TUNNEL: + return IPSECDOI_ATTR_ENC_MODE_TUNNEL; + case IPSEC_MODE_TRANSPORT: + return IPSECDOI_ATTR_ENC_MODE_TRNS; + case IPSEC_MODE_ANY: + return IPSECDOI_ATTR_ENC_MODE_ANY; + default: + plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode); + return ~0; + } + /*NOTREACHED*/ +} + +/* default key length for encryption algorithm */ +static u_int +keylen_aalg(hashtype) + u_int hashtype; +{ + int res; + + if (hashtype == 0) + return SADB_AALG_NONE; + + res = alg_ipsec_hmacdef_hashlen(hashtype); + if (res == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid hmac algorithm %u.\n", hashtype); + return ~0; + } + return res; +} + +/* default key length for encryption algorithm */ +static u_int +keylen_ealg(enctype, encklen) + u_int enctype; + int encklen; +{ + int res; + + res = alg_ipsec_encdef_keylen(enctype, encklen); + if (res == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid encryption algorithm %u.\n", enctype); + return ~0; + } + return res; +} + +void +pk_fixup_sa_addresses(mhp) + caddr_t *mhp; +{ + struct sockaddr *src, *dst; + + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + set_port(src, PORT_ISAKMP); + set_port(dst, PORT_ISAKMP); + +#ifdef ENABLE_NATT + if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) { + /* NAT-T is enabled for this SADB entry; copy + * the ports from NAT-T extensions */ + if(mhp[SADB_X_EXT_NAT_T_SPORT] != NULL) + set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT])); + if(mhp[SADB_X_EXT_NAT_T_DPORT] != NULL) + set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT])); + } +#endif +} + +int +pfkey_convertfromipsecdoi(proto_id, t_id, hashtype, + e_type, e_keylen, a_type, a_keylen, flags) + u_int proto_id; + u_int t_id; + u_int hashtype; + u_int *e_type; + u_int *e_keylen; + u_int *a_type; + u_int *a_keylen; + u_int *flags; +{ + *flags = 0; + switch (proto_id) { + case IPSECDOI_PROTO_IPSEC_ESP: + if ((*e_type = ipsecdoi2pfkey_ealg(t_id)) == ~0) + goto bad; + if ((*e_keylen = keylen_ealg(t_id, *e_keylen)) == ~0) + goto bad; + *e_keylen >>= 3; + + if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0) + goto bad; + if ((*a_keylen = keylen_aalg(hashtype)) == ~0) + goto bad; + *a_keylen >>= 3; + + if (*e_type == SADB_EALG_NONE) { + plog(LLV_ERROR, LOCATION, NULL, "no ESP algorithm.\n"); + goto bad; + } + break; + + case IPSECDOI_PROTO_IPSEC_AH: + if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0) + goto bad; + if ((*a_keylen = keylen_aalg(hashtype)) == ~0) + goto bad; + *a_keylen >>= 3; + + if (t_id == IPSECDOI_ATTR_AUTH_HMAC_MD5 + && hashtype == IPSECDOI_ATTR_AUTH_KPDK) { + /* AH_MD5 + Auth(KPDK) = RFC1826 keyed-MD5 */ + *a_type = SADB_X_AALG_MD5; + *flags |= SADB_X_EXT_OLD; + } + *e_type = SADB_EALG_NONE; + *e_keylen = 0; + if (*a_type == SADB_AALG_NONE) { + plog(LLV_ERROR, LOCATION, NULL, "no AH algorithm.\n"); + goto bad; + } + break; + + case IPSECDOI_PROTO_IPCOMP: + if ((*e_type = ipsecdoi2pfkey_calg(t_id)) == ~0) + goto bad; + *e_keylen = 0; + + *flags = SADB_X_EXT_RAWCPI; + + *a_type = SADB_AALG_NONE; + *a_keylen = 0; + if (*e_type == SADB_X_CALG_NONE) { + plog(LLV_ERROR, LOCATION, NULL, "no IPCOMP algorithm.\n"); + goto bad; + } + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, "unknown IPsec protocol.\n"); + goto bad; + } + + return 0; + + bad: + errno = EINVAL; + return -1; +} + +/*%%%*/ +/* send getspi message per ipsec protocol per remote address */ +/* + * the local address and remote address in ph1handle are dealed + * with destination address and source address respectively. + * Because SPI is decided by responder. + */ +int +pk_sendgetspi(iph2) + struct ph2handle *iph2; +{ + struct sockaddr *src = NULL, *dst = NULL; + u_int satype, mode; + struct saprop *pp; + struct saproto *pr; + u_int32_t minspi, maxspi; + u_int8_t natt_type = 0; + u_int16_t sport = 0, dport = 0; + + if (iph2->side == INITIATOR) + pp = iph2->proposal; + else + pp = iph2->approval; + + if (iph2->sa_src && iph2->sa_dst) { + /* MIPv6: Use SA addresses, not IKE ones */ + src = dupsaddr(iph2->sa_src); + dst = dupsaddr(iph2->sa_dst); + } else { + /* Common case: SA addresses and IKE ones are the same */ + src = dupsaddr(iph2->src); + dst = dupsaddr(iph2->dst); + } + + if (src == NULL || dst == NULL) { + racoon_free(src); + racoon_free(dst); + return -1; + } + + for (pr = pp->head; pr != NULL; pr = pr->next) { + + /* validity check */ + satype = ipsecdoi2pfkey_proto(pr->proto_id); + if (satype == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid proto_id %d\n", pr->proto_id); + racoon_free(src); + racoon_free(dst); + return -1; + } + /* this works around a bug in Linux kernel where it allocates 4 byte + spi's for IPCOMP */ + else if (satype == SADB_X_SATYPE_IPCOMP) { + minspi = 0x100; + maxspi = 0xffff; + } + else { + minspi = 0; + maxspi = 0; + } + mode = ipsecdoi2pfkey_mode(pr->encmode); + if (mode == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid encmode %d\n", pr->encmode); + racoon_free(src); + racoon_free(dst); + return -1; + } + +#ifdef ENABLE_NATT + if (pr->udp_encap) { + natt_type = iph2->ph1->natt_options->encaps_type; + sport=extract_port(src); + dport=extract_port(dst); + } +#endif + + plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n"); + if (pfkey_send_getspi_nat( + lcconf->sock_pfkey, + satype, + mode, + dst, /* src of SA */ + src, /* dst of SA */ + natt_type, + dport, + sport, + minspi, maxspi, + pr->reqid_in, iph2->seq) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "ipseclib failed send getspi (%s)\n", + ipsec_strerror()); + racoon_free(src); + racoon_free(dst); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey GETSPI sent: %s\n", + sadbsecas2str(dst, src, satype, 0, mode)); + } + + racoon_free(src); + racoon_free(dst); + return 0; +} + +/* + * receive GETSPI from kernel. + */ +static int +pk_recvgetspi(mhp) + caddr_t *mhp; +{ + struct sadb_msg *msg; + struct sadb_sa *sa; + struct ph2handle *iph2; + struct sockaddr *src, *dst; + int proto_id; + int allspiok, notfound; + struct saprop *pp; + struct saproto *pr; + + /* validity check */ + if (mhp[SADB_EXT_SA] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb getspi message passed.\n"); + return -1; + } + msg = (struct sadb_msg *)mhp[0]; + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; + pk_fixup_sa_addresses(mhp); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); /* note SA dir */ + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + + /* the message has to be processed or not ? */ + if (msg->sadb_msg_pid != getpid()) { + plog(LLV_DEBUG, LOCATION, NULL, + "%s message is not interesting " + "because pid %d is not mine.\n", + s_pfkey_type(msg->sadb_msg_type), + msg->sadb_msg_pid); + return -1; + } + + iph2 = getph2byseq(msg->sadb_msg_seq); + if (iph2 == NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "seq %d of %s message not interesting.\n", + msg->sadb_msg_seq, + s_pfkey_type(msg->sadb_msg_type)); + return -1; + } + + if (iph2->status != PHASE2ST_GETSPISENT) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatch (db:%d msg:%d)\n", + iph2->status, PHASE2ST_GETSPISENT); + return -1; + } + + /* set SPI, and check to get all spi whether or not */ + allspiok = 1; + notfound = 1; + proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); + pp = iph2->side == INITIATOR ? iph2->proposal : iph2->approval; + + for (pr = pp->head; pr != NULL; pr = pr->next) { + if (pr->proto_id == proto_id && pr->spi == 0) { + pr->spi = sa->sadb_sa_spi; + notfound = 0; + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey GETSPI succeeded: %s\n", + sadbsecas2str(dst, src, + msg->sadb_msg_satype, + sa->sadb_sa_spi, + ipsecdoi2pfkey_mode(pr->encmode))); + } + if (pr->spi == 0) + allspiok = 0; /* not get all spi */ + } + + if (notfound) { + plog(LLV_ERROR, LOCATION, NULL, + "get spi for unknown address %s\n", + saddrwop2str(dst)); + return -1; + } + + if (allspiok) { + /* update status */ + iph2->status = PHASE2ST_GETSPIDONE; + if (isakmp_post_getspi(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to start post getspi.\n"); + remph2(iph2); + delph2(iph2); + iph2 = NULL; + return -1; + } + } + + return 0; +} + +/* + * set inbound SA + */ +int +pk_sendupdate(iph2) + struct ph2handle *iph2; +{ + struct saproto *pr; + struct pfkey_send_sa_args sa_args; + + /* sanity check */ + if (iph2->approval == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no approvaled SAs found.\n"); + return -1; + } + + /* fill in some needed for pfkey_send_update2 */ + memset (&sa_args, 0, sizeof (sa_args)); + sa_args.so = lcconf->sock_pfkey; + if (iph2->lifetime_secs) + sa_args.l_addtime = iph2->lifetime_secs; + else + sa_args.l_addtime = iph2->approval->lifetime; + sa_args.seq = iph2->seq; + sa_args.wsize = 4; + + if (iph2->sa_src && iph2->sa_dst) { + /* MIPv6: Use SA addresses, not IKE ones */ + sa_args.dst = dupsaddr(iph2->sa_src); + sa_args.src = dupsaddr(iph2->sa_dst); + } else { + /* Common case: SA addresses and IKE ones are the same */ + sa_args.dst = dupsaddr(iph2->src); + sa_args.src = dupsaddr(iph2->dst); + } + + if (sa_args.src == NULL || sa_args.dst == NULL) { + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; + } + + for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { + /* validity check */ + sa_args.satype = ipsecdoi2pfkey_proto(pr->proto_id); + if (sa_args.satype == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid proto_id %d\n", pr->proto_id); + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; + } + else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) { + /* IPCOMP has no replay window */ + sa_args.wsize = 0; + } +#ifdef ENABLE_SAMODE_UNSPECIFIED + sa_args.mode = IPSEC_MODE_ANY; +#else + sa_args.mode = ipsecdoi2pfkey_mode(pr->encmode); + if (sa_args.mode == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid encmode %d\n", pr->encmode); + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; + } +#endif + /* set algorithm type and key length */ + sa_args.e_keylen = pr->head->encklen; + if (pfkey_convertfromipsecdoi( + pr->proto_id, + pr->head->trns_id, + pr->head->authtype, + &sa_args.e_type, &sa_args.e_keylen, + &sa_args.a_type, &sa_args.a_keylen, + &sa_args.flags) < 0){ + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; + } + +#if 0 + sa_args.l_bytes = iph2->approval->lifebyte * 1024, +#else + sa_args.l_bytes = 0; +#endif + +#ifdef HAVE_SECCTX + if (*iph2->approval->sctx.ctx_str) { + sa_args.ctxdoi = iph2->approval->sctx.ctx_doi; + sa_args.ctxalg = iph2->approval->sctx.ctx_alg; + sa_args.ctxstrlen = iph2->approval->sctx.ctx_strlen; + sa_args.ctxstr = iph2->approval->sctx.ctx_str; + } +#endif /* HAVE_SECCTX */ + +#ifdef ENABLE_NATT + if (pr->udp_encap) { + sa_args.l_natt_type = iph2->ph1->natt_options->encaps_type; + sa_args.l_natt_sport = extract_port(iph2->ph1->remote); + sa_args.l_natt_dport = extract_port(iph2->ph1->local); + sa_args.l_natt_oa = iph2->natoa_src; +#ifdef SADB_X_EXT_NAT_T_FRAG + sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag; +#endif + } +#endif + + /* more info to fill in */ + sa_args.spi = pr->spi; + sa_args.reqid = pr->reqid_in; + sa_args.keymat = pr->keymat->v; + + plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_update2\n"); + if (pfkey_send_update2(&sa_args) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed send update (%s)\n", + ipsec_strerror()); + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; + } + + if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]) + continue; + + /* + * It maybe good idea to call backupsa_to_file() after + * racoon will receive the sadb_update messages. + * But it is impossible because there is not key in the + * information from the kernel. + */ + + /* change some things before backing up */ + sa_args.wsize = 4; + sa_args.l_bytes = iph2->approval->lifebyte * 1024; + + if (backupsa_to_file(&sa_args) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "backuped SA failed: %s\n", + sadbsecas2str(sa_args.src, sa_args.dst, + sa_args.satype, sa_args.spi, sa_args.mode)); + } + plog(LLV_DEBUG, LOCATION, NULL, + "backuped SA: %s\n", + sadbsecas2str(sa_args.src, sa_args.dst, + sa_args.satype, sa_args.spi, sa_args.mode)); + } + + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return 0; +} + +static int +pk_recvupdate(mhp) + caddr_t *mhp; +{ + struct sadb_msg *msg; + struct sadb_sa *sa; + struct sockaddr *src, *dst; + struct ph2handle *iph2; + u_int proto_id, encmode, sa_mode; + int incomplete = 0; + struct saproto *pr; + + /* ignore this message because of local test mode. */ + if (f_local) + return 0; + + /* sanity check */ + if (mhp[0] == NULL + || mhp[SADB_EXT_SA] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb update message passed.\n"); + return -1; + } + msg = (struct sadb_msg *)mhp[0]; + pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; + + sa_mode = mhp[SADB_X_EXT_SA2] == NULL + ? IPSEC_MODE_ANY + : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode; + + /* the message has to be processed or not ? */ + if (msg->sadb_msg_pid != getpid()) { + plog(LLV_DEBUG, LOCATION, NULL, + "%s message is not interesting " + "because pid %d is not mine.\n", + s_pfkey_type(msg->sadb_msg_type), + msg->sadb_msg_pid); + return -1; + } + + iph2 = getph2byseq(msg->sadb_msg_seq); + if (iph2 == NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "seq %d of %s message not interesting.\n", + msg->sadb_msg_seq, + s_pfkey_type(msg->sadb_msg_type)); + return -1; + } + + if (iph2->status != PHASE2ST_ADDSA) { + plog(LLV_ERROR, LOCATION, NULL, + "status mismatch (db:%d msg:%d)\n", + iph2->status, PHASE2ST_ADDSA); + return -1; + } + + /* check to complete all keys ? */ + for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { + proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); + if (proto_id == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid proto_id %d\n", msg->sadb_msg_satype); + return -1; + } + encmode = pfkey2ipsecdoi_mode(sa_mode); + if (encmode == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid encmode %d\n", sa_mode); + return -1; + } + + if (pr->proto_id == proto_id + && pr->spi == sa->sadb_sa_spi) { + pr->ok = 1; + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey UPDATE succeeded: %s\n", + sadbsecas2str(dst, src, + msg->sadb_msg_satype, + sa->sadb_sa_spi, + sa_mode)); + + plog(LLV_INFO, LOCATION, NULL, + "IPsec-SA established: %s\n", + sadbsecas2str(dst, src, + msg->sadb_msg_satype, sa->sadb_sa_spi, + sa_mode)); + } + + if (pr->ok == 0) + incomplete = 1; + } + + if (incomplete) + return 0; + + /* turn off the timer for calling pfkey_timeover() */ + sched_cancel(&iph2->sce); + + /* update status */ + iph2->status = PHASE2ST_ESTABLISHED; + evt_phase2(iph2, EVT_PHASE2_UP, NULL); + +#ifdef ENABLE_STATS + gettimeofday(&iph2->end, NULL); + syslog(LOG_NOTICE, "%s(%s): %8.6f", + "phase2", "quick", timedelta(&iph2->start, &iph2->end)); +#endif + + /* turn off schedule */ + sched_cancel(&iph2->scr); + + /* + * since we are going to reuse the phase2 handler, we need to + * remain it and refresh all the references between ph1 and ph2 to use. + */ + sched_schedule(&iph2->sce, iph2->approval->lifetime, + isakmp_ph2expire_stub); + + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); + return 0; +} + +/* + * set outbound SA + */ +int +pk_sendadd(iph2) + struct ph2handle *iph2; +{ + struct saproto *pr; + struct pfkey_send_sa_args sa_args; + + /* sanity check */ + if (iph2->approval == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no approvaled SAs found.\n"); + return -1; + } + + /* fill in some needed for pfkey_send_update2 */ + memset (&sa_args, 0, sizeof (sa_args)); + sa_args.so = lcconf->sock_pfkey; + if (iph2->lifetime_secs) + sa_args.l_addtime = iph2->lifetime_secs; + else + sa_args.l_addtime = iph2->approval->lifetime; + sa_args.seq = iph2->seq; + sa_args.wsize = 4; + + if (iph2->sa_src && iph2->sa_dst) { + /* MIPv6: Use SA addresses, not IKE ones */ + sa_args.src = dupsaddr(iph2->sa_src); + sa_args.dst = dupsaddr(iph2->sa_dst); + } else { + /* Common case: SA addresses and IKE ones are the same */ + sa_args.src = dupsaddr(iph2->src); + sa_args.dst = dupsaddr(iph2->dst); + } + + if (sa_args.src == NULL || sa_args.dst == NULL) { + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; + } + + for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { + /* validity check */ + sa_args.satype = ipsecdoi2pfkey_proto(pr->proto_id); + if (sa_args.satype == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid proto_id %d\n", pr->proto_id); + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; + } + else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) { + /* no replay window for IPCOMP */ + sa_args.wsize = 0; + } +#ifdef ENABLE_SAMODE_UNSPECIFIED + sa_args.mode = IPSEC_MODE_ANY; +#else + sa_args.mode = ipsecdoi2pfkey_mode(pr->encmode); + if (sa_args.mode == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid encmode %d\n", pr->encmode); + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; + } +#endif + + /* set algorithm type and key length */ + sa_args.e_keylen = pr->head->encklen; + if (pfkey_convertfromipsecdoi( + pr->proto_id, + pr->head->trns_id, + pr->head->authtype, + &sa_args.e_type, &sa_args.e_keylen, + &sa_args.a_type, &sa_args.a_keylen, + &sa_args.flags) < 0){ + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; + } + +#if 0 + sa_args.l_bytes = iph2->approval->lifebyte * 1024, +#else + sa_args.l_bytes = 0; +#endif + +#ifdef HAVE_SECCTX + if (*iph2->approval->sctx.ctx_str) { + sa_args.ctxdoi = iph2->approval->sctx.ctx_doi; + sa_args.ctxalg = iph2->approval->sctx.ctx_alg; + sa_args.ctxstrlen = iph2->approval->sctx.ctx_strlen; + sa_args.ctxstr = iph2->approval->sctx.ctx_str; + } +#endif /* HAVE_SECCTX */ + +#ifdef ENABLE_NATT + plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2 " + "(NAT flavor)\n"); + + if (pr->udp_encap) { + sa_args.l_natt_type = UDP_ENCAP_ESPINUDP; + sa_args.l_natt_sport = extract_port(iph2->ph1->local); + sa_args.l_natt_dport = extract_port(iph2->ph1->remote); + sa_args.l_natt_oa = iph2->natoa_dst; +#ifdef SADB_X_EXT_NAT_T_FRAG + sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag; +#endif + } +#endif + /* more info to fill in */ + sa_args.spi = pr->spi_p; + sa_args.reqid = pr->reqid_out; + sa_args.keymat = pr->keymat_p->v; + + plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2\n"); + if (pfkey_send_add2(&sa_args) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed send add (%s)\n", + ipsec_strerror()); + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; + } + + if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]) + continue; + + /* + * It maybe good idea to call backupsa_to_file() after + * racoon will receive the sadb_update messages. + * But it is impossible because there is not key in the + * information from the kernel. + */ + if (backupsa_to_file(&sa_args) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "backuped SA failed: %s\n", + sadbsecas2str(sa_args.src, sa_args.dst, + sa_args.satype, sa_args.spi, sa_args.mode)); + } + plog(LLV_DEBUG, LOCATION, NULL, + "backuped SA: %s\n", + sadbsecas2str(sa_args.src, sa_args.dst, + sa_args.satype, sa_args.spi, sa_args.mode)); + } + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return 0; +} + +static int +pk_recvadd(mhp) + caddr_t *mhp; +{ + struct sadb_msg *msg; + struct sadb_sa *sa; + struct sockaddr *src, *dst; + struct ph2handle *iph2; + u_int sa_mode; + + /* ignore this message because of local test mode. */ + if (f_local) + return 0; + + /* sanity check */ + if (mhp[0] == NULL + || mhp[SADB_EXT_SA] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb add message passed.\n"); + return -1; + } + msg = (struct sadb_msg *)mhp[0]; + pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; + + sa_mode = mhp[SADB_X_EXT_SA2] == NULL + ? IPSEC_MODE_ANY + : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode; + + /* the message has to be processed or not ? */ + if (msg->sadb_msg_pid != getpid()) { + plog(LLV_DEBUG, LOCATION, NULL, + "%s message is not interesting " + "because pid %d is not mine.\n", + s_pfkey_type(msg->sadb_msg_type), + msg->sadb_msg_pid); + return -1; + } + + iph2 = getph2byseq(msg->sadb_msg_seq); + if (iph2 == NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "seq %d of %s message not interesting.\n", + msg->sadb_msg_seq, + s_pfkey_type(msg->sadb_msg_type)); + return -1; + } + + /* + * NOTE don't update any status of phase2 handle + * because they must be updated by SADB_UPDATE message + */ + + plog(LLV_INFO, LOCATION, NULL, + "IPsec-SA established: %s\n", + sadbsecas2str(src, dst, + msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode)); + + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); + return 0; +} + +static int +pk_recvexpire(mhp) + caddr_t *mhp; +{ + struct sadb_msg *msg; + struct sadb_sa *sa; + struct sockaddr *src, *dst; + struct ph2handle *iph2; + u_int proto_id, sa_mode; + + /* sanity check */ + if (mhp[0] == NULL + || mhp[SADB_EXT_SA] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL + || (mhp[SADB_EXT_LIFETIME_HARD] != NULL + && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb expire message passed.\n"); + return -1; + } + msg = (struct sadb_msg *)mhp[0]; + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; + pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + + sa_mode = mhp[SADB_X_EXT_SA2] == NULL + ? IPSEC_MODE_ANY + : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode; + + proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); + if (proto_id == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid proto_id %d\n", msg->sadb_msg_satype); + return -1; + } + + plog(LLV_INFO, LOCATION, NULL, + "IPsec-SA expired: %s\n", + sadbsecas2str(src, dst, + msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode)); + + iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); + if (iph2 == NULL) { + /* + * Ignore it because two expire messages are come up. + * phase2 handler has been deleted already when 2nd message + * is received. + */ + plog(LLV_DEBUG, LOCATION, NULL, + "no such a SA found: %s\n", + sadbsecas2str(src, dst, + msg->sadb_msg_satype, sa->sadb_sa_spi, + sa_mode)); + return 0; + } + + /* resent expiry message? */ + if (iph2->status > PHASE2ST_ESTABLISHED) + return 0; + + /* still negotiating? */ + if (iph2->status < PHASE2ST_ESTABLISHED) { + /* not a hard timeout? */ + if (mhp[SADB_EXT_LIFETIME_HARD] == NULL) + return 0; + + /* + * We were negotiating for that SA (w/o much success + * from current status) and kernel has decided our time + * is over trying (xfrm_larval_drop controls that and + * is enabled by default on Linux >= 2.6.28 kernels). + */ + plog(LLV_WARNING, LOCATION, NULL, + "PF_KEY EXPIRE message received from kernel for SA" + " being negotiated. Stopping negotiation.\n"); + } + + /* turn off the timer for calling isakmp_ph2expire() */ + sched_cancel(&iph2->sce); + + if (iph2->status == PHASE2ST_ESTABLISHED && + iph2->side == INITIATOR) { + struct ph1handle *iph1hint; + /* + * Active phase 2 expired and we were initiator. + * Begin new phase 2 exchange, so we can keep on sending + * traffic. + */ + + /* update status for re-use */ + iph1hint = iph2->ph1; + initph2(iph2); + iph2->status = PHASE2ST_STATUS2; + + /* start quick exchange */ + if (isakmp_post_acquire(iph2, iph1hint, FALSE) < 0) { + plog(LLV_ERROR, LOCATION, iph2->dst, + "failed to begin ipsec sa " + "re-negotication.\n"); + remph2(iph2); + delph2(iph2); + return -1; + } + + return 0; + } + + /* + * We are responder or the phase 2 was not established. + * Just remove the ph2handle to reflect SADB. + */ + iph2->status = PHASE2ST_EXPIRED; + remph2(iph2); + delph2(iph2); + + return 0; +} + +static int +pk_recvacquire(mhp) + caddr_t *mhp; +{ + struct sadb_msg *msg; + struct sadb_x_policy *xpl; + struct secpolicy *sp_out = NULL, *sp_in = NULL; + struct ph2handle *iph2; + struct sockaddr *src, *dst; /* IKE addresses (for exchanges) */ + struct sockaddr *sp_src, *sp_dst; /* SP addresses (selectors). */ + struct sockaddr *sa_src = NULL, *sa_dst = NULL ; /* SA addresses */ +#ifdef HAVE_SECCTX + struct sadb_x_sec_ctx *m_sec_ctx; +#endif /* HAVE_SECCTX */ + struct policyindex spidx; + + /* ignore this message because of local test mode. */ + if (f_local) + return 0; + + /* sanity check */ + if (mhp[0] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL + || mhp[SADB_X_EXT_POLICY] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb acquire message passed.\n"); + return -1; + } + msg = (struct sadb_msg *)mhp[0]; + xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; + /* acquire does not have nat-t ports; so do not bother setting + * the default port 500; just use the port zero for wildcard + * matching the get a valid natted destination */ + sp_src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + sp_dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + +#ifdef HAVE_SECCTX + m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; + + if (m_sec_ctx != NULL) { + plog(LLV_INFO, LOCATION, NULL, "security context doi: %u\n", + m_sec_ctx->sadb_x_ctx_doi); + plog(LLV_INFO, LOCATION, NULL, + "security context algorithm: %u\n", + m_sec_ctx->sadb_x_ctx_alg); + plog(LLV_INFO, LOCATION, NULL, "security context length: %u\n", + m_sec_ctx->sadb_x_ctx_len); + plog(LLV_INFO, LOCATION, NULL, "security context: %s\n", + ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx))); + } +#endif /* HAVE_SECCTX */ + + /* ignore if type is not IPSEC_POLICY_IPSEC */ + if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) { + plog(LLV_DEBUG, LOCATION, NULL, + "ignore ACQUIRE message. type is not IPsec.\n"); + return 0; + } + + /* ignore it if src or dst are multicast addresses. */ + if ((sp_dst->sa_family == AF_INET + && IN_MULTICAST(ntohl(((struct sockaddr_in *)sp_dst)->sin_addr.s_addr))) +#ifdef INET6 + || (sp_dst->sa_family == AF_INET6 + && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sp_dst)->sin6_addr)) +#endif + ) { + plog(LLV_DEBUG, LOCATION, NULL, + "ignore due to multicast destination address: %s.\n", + saddrwop2str(sp_dst)); + return 0; + } + + if ((sp_src->sa_family == AF_INET + && IN_MULTICAST(ntohl(((struct sockaddr_in *)sp_src)->sin_addr.s_addr))) +#ifdef INET6 + || (sp_src->sa_family == AF_INET6 + && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sp_src)->sin6_addr)) +#endif + ) { + plog(LLV_DEBUG, LOCATION, NULL, + "ignore due to multicast source address: %s.\n", + saddrwop2str(sp_src)); + return 0; + } + + /* search for proper policyindex */ + sp_out = getspbyspid(xpl->sadb_x_policy_id); + if (sp_out == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "no policy found: id:%d.\n", + xpl->sadb_x_policy_id); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, + "suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx)); + + /* Before going further, let first get the source and destination + * address that would be used for IKE negotiation. The logic is: + * - if SP from SPD image contains local and remote hints, we + * use them (provided by MIGRATE). + * - otherwise, we use the ones from the ipsecrequest, which means: + * - the addresses from the request for transport mode + * - the endpoints addresses for tunnel mode + * + * Note that: + * 1) racoon does not support negotiation of bundles which + * simplifies the lookup for the addresses in the ipsecrequest + * list, as we expect only one. + * 2) We do source and destination parts all together and do not + * accept semi-defined information. This is just a decision, + * there might be needs. + * + * --arno + */ + if (sp_out->req && sp_out->req->saidx.mode == IPSEC_MODE_TUNNEL) { + /* For Tunnel mode, SA addresses are the endpoints */ + src = (struct sockaddr *) &sp_out->req->saidx.src; + dst = (struct sockaddr *) &sp_out->req->saidx.dst; + } else { + /* Otherwise use requested addresses. + * + * We need to explicitly setup sa_src and sa_dst too, + * since the SA ports are different from IKE port. And + * src/dst ports will be overwritten when the matching + * phase1 is found. */ + src = sa_src = sp_src; + dst = sa_dst = sp_dst; + } + if (sp_out->local && sp_out->remote) { + /* hints available, let's use them */ + sa_src = src; + sa_dst = dst; + src = (struct sockaddr *) sp_out->local; + dst = (struct sockaddr *) sp_out->remote; + } + + /* + * If there is a phase 2 handler against the policy identifier in + * the acquire message, and if + * 1. its state is less than PHASE2ST_ESTABLISHED, then racoon + * should ignore such a acquire message because the phase 2 + * is just negotiating. + * 2. its state is equal to PHASE2ST_ESTABLISHED, then racoon + * has to prcesss such a acquire message because racoon may + * lost the expire message. + */ + iph2 = getph2byid(src, dst, xpl->sadb_x_policy_id); + if (iph2 != NULL) { + if (iph2->status < PHASE2ST_ESTABLISHED) { + plog(LLV_DEBUG, LOCATION, NULL, + "ignore the acquire because ph2 found\n"); + return -1; + } + if (iph2->status == PHASE2ST_EXPIRED) + iph2 = NULL; + /*FALLTHROUGH*/ + } + + /* Check we are listening on source address. If not, ignore. */ + if (myaddr_getsport(src) == -1) { + plog(LLV_DEBUG, LOCATION, NULL, + "Not listening on source address %s. Ignoring ACQUIRE.\n", + saddrwop2str(src)); + return 0; + } + + /* get inbound policy */ + { + + memset(&spidx, 0, sizeof(spidx)); + spidx.dir = IPSEC_DIR_INBOUND; + memcpy(&spidx.src, &sp_out->spidx.dst, sizeof(spidx.src)); + memcpy(&spidx.dst, &sp_out->spidx.src, sizeof(spidx.dst)); + spidx.prefs = sp_out->spidx.prefd; + spidx.prefd = sp_out->spidx.prefs; + spidx.ul_proto = sp_out->spidx.ul_proto; + +#ifdef HAVE_SECCTX + if (m_sec_ctx) { + spidx.sec_ctx.ctx_doi = m_sec_ctx->sadb_x_ctx_doi; + spidx.sec_ctx.ctx_alg = m_sec_ctx->sadb_x_ctx_alg; + spidx.sec_ctx.ctx_strlen = m_sec_ctx->sadb_x_ctx_len; + memcpy(spidx.sec_ctx.ctx_str, + ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)), + spidx.sec_ctx.ctx_strlen); + } +#endif /* HAVE_SECCTX */ + + sp_in = getsp(&spidx); + if (sp_in) { + plog(LLV_DEBUG, LOCATION, NULL, + "suitable inbound SP found: %s.\n", + spidx2str(&sp_in->spidx)); + } else { + plog(LLV_NOTIFY, LOCATION, NULL, + "no in-bound policy found: %s\n", + spidx2str(&spidx)); + } + } + + /* allocate a phase 2 */ + iph2 = newph2(); + if (iph2 == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate phase2 entry.\n"); + return -1; + } + iph2->side = INITIATOR; + iph2->spid = xpl->sadb_x_policy_id; + iph2->satype = msg->sadb_msg_satype; + iph2->seq = msg->sadb_msg_seq; + iph2->status = PHASE2ST_STATUS2; + + /* set address used by IKE for the negotiation (might differ from + * SA address, i.e. might not be tunnel endpoints or addresses + * of transport mode SA) */ + iph2->dst = dupsaddr(dst); + if (iph2->dst == NULL) { + delph2(iph2); + return -1; + } + iph2->src = dupsaddr(src); + if (iph2->src == NULL) { + delph2(iph2); + return -1; + } + + /* If sa_src and sa_dst have been set, this mean we have to + * set iph2->sa_src and iph2->sa_dst to provide the addresses + * of the SA because iph2->src and iph2->dst are only the ones + * used for the IKE exchanges. Those that need these addresses + * are for instance pk_sendupdate() or pk_sendgetspi() */ + if (sa_src) { + iph2->sa_src = dupsaddr(sa_src); + iph2->sa_dst = dupsaddr(sa_dst); + } + + if (isakmp_get_sainfo(iph2, sp_out, sp_in) < 0) { + delph2(iph2); + return -1; + } + +#ifdef HAVE_SECCTX + if (m_sec_ctx) { + set_secctx_in_proposal(iph2, spidx); + } +#endif /* HAVE_SECCTX */ + + insph2(iph2); + + /* start isakmp initiation by using ident exchange */ + /* XXX should be looped if there are multiple phase 2 handler. */ + if (isakmp_post_acquire(iph2, NULL, TRUE) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to begin ipsec sa negotication.\n"); + remph2(iph2); + delph2(iph2); + return -1; + } + + return 0; +} + +static int +pk_recvdelete(mhp) + caddr_t *mhp; +{ + struct sadb_msg *msg; + struct sadb_sa *sa; + struct sockaddr *src, *dst; + struct ph2handle *iph2 = NULL; + u_int proto_id; + + /* ignore this message because of local test mode. */ + if (f_local) + return 0; + + /* sanity check */ + if (mhp[0] == NULL + || mhp[SADB_EXT_SA] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb delete message passed.\n"); + return -1; + } + msg = (struct sadb_msg *)mhp[0]; + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; + pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + + /* the message has to be processed or not ? */ + if (msg->sadb_msg_pid == getpid()) { + plog(LLV_DEBUG, LOCATION, NULL, + "%s message is not interesting " + "because the message was originated by me.\n", + s_pfkey_type(msg->sadb_msg_type)); + return -1; + } + + proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); + if (proto_id == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid proto_id %d\n", msg->sadb_msg_satype); + return -1; + } + + iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); + if (iph2 == NULL) { + /* ignore */ + plog(LLV_ERROR, LOCATION, NULL, + "no iph2 found: %s\n", + sadbsecas2str(src, dst, msg->sadb_msg_satype, + sa->sadb_sa_spi, IPSEC_MODE_ANY)); + return 0; + } + + plog(LLV_ERROR, LOCATION, NULL, + "pfkey DELETE received: %s\n", + sadbsecas2str(src, dst, + msg->sadb_msg_satype, sa->sadb_sa_spi, IPSEC_MODE_ANY)); + + /* send delete information */ + if (iph2->status == PHASE2ST_ESTABLISHED) + isakmp_info_send_d2(iph2); + + remph2(iph2); + delph2(iph2); + + return 0; +} + +static int +pk_recvflush(mhp) + caddr_t *mhp; +{ + /* ignore this message because of local test mode. */ + if (f_local) + return 0; + + /* sanity check */ + if (mhp[0] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb flush message passed.\n"); + return -1; + } + + flushph2(); + + return 0; +} + +static int +getsadbpolicy(policy0, policylen0, type, iph2) + caddr_t *policy0; + int *policylen0, type; + struct ph2handle *iph2; +{ + struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen; + struct sockaddr *src = NULL, *dst = NULL; + struct sadb_x_policy *xpl; + struct sadb_x_ipsecrequest *xisr; + struct saproto *pr; + struct saproto **pr_rlist; + int rlist_len = 0; + caddr_t policy, p; + int policylen; + int xisrlen; + u_int satype, mode; + int len = 0; +#ifdef HAVE_SECCTX + int ctxlen = 0; +#endif /* HAVE_SECCTX */ + + + /* get policy buffer size */ + policylen = sizeof(struct sadb_x_policy); + if (type != SADB_X_SPDDELETE) { + if (iph2->sa_src && iph2->sa_dst) { + src = iph2->sa_src; /* MIPv6: Use SA addresses, */ + dst = iph2->sa_dst; /* not IKE ones */ + } else { + src = iph2->src; /* Common case: SA addresses */ + dst = iph2->dst; /* and IKE ones are the same */ + } + + for (pr = iph2->approval->head; pr; pr = pr->next) { + xisrlen = sizeof(*xisr); + if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) { + xisrlen += (sysdep_sa_len(src) + + sysdep_sa_len(dst)); + } + + policylen += PFKEY_ALIGN8(xisrlen); + } + } + +#ifdef HAVE_SECCTX + if (*spidx->sec_ctx.ctx_str) { + ctxlen = sizeof(struct sadb_x_sec_ctx) + + PFKEY_ALIGN8(spidx->sec_ctx.ctx_strlen); + policylen += ctxlen; + } +#endif /* HAVE_SECCTX */ + + /* make policy structure */ + policy = racoon_malloc(policylen); + memset((void*)policy, 0xcd, policylen); + if (!policy) { + plog(LLV_ERROR, LOCATION, NULL, + "buffer allocation failed.\n"); + return -1; + } + + xpl = (struct sadb_x_policy *)policy; + xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen); + xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY; + xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC; + xpl->sadb_x_policy_dir = spidx->dir; + xpl->sadb_x_policy_id = 0; +#ifdef HAVE_PFKEY_POLICY_PRIORITY + xpl->sadb_x_policy_priority = PRIORITY_DEFAULT; +#endif + len++; + +#ifdef HAVE_SECCTX + if (*spidx->sec_ctx.ctx_str) { + struct sadb_x_sec_ctx *p; + + p = (struct sadb_x_sec_ctx *)(xpl + len); + memset(p, 0, ctxlen); + p->sadb_x_sec_len = PFKEY_UNIT64(ctxlen); + p->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX; + p->sadb_x_ctx_len = spidx->sec_ctx.ctx_strlen; + p->sadb_x_ctx_doi = spidx->sec_ctx.ctx_doi; + p->sadb_x_ctx_alg = spidx->sec_ctx.ctx_alg; + + memcpy(p + 1,spidx->sec_ctx.ctx_str,spidx->sec_ctx.ctx_strlen); + len += ctxlen; + } +#endif /* HAVE_SECCTX */ + + /* no need to append policy information any more if type is SPDDELETE */ + if (type == SADB_X_SPDDELETE) + goto end; + + xisr = (struct sadb_x_ipsecrequest *)(xpl + len); + + /* The order of things is reversed for use in add policy messages */ + for (pr = iph2->approval->head; pr; pr = pr->next) rlist_len++; + pr_rlist = racoon_malloc((rlist_len+1)*sizeof(struct saproto*)); + if (!pr_rlist) { + plog(LLV_ERROR, LOCATION, NULL, + "buffer allocation failed.\n"); + return -1; + } + pr_rlist[rlist_len--] = NULL; + for (pr = iph2->approval->head; pr; pr = pr->next) pr_rlist[rlist_len--] = pr; + rlist_len = 0; + + for (pr = pr_rlist[rlist_len++]; pr; pr = pr_rlist[rlist_len++]) { + + satype = doi2ipproto(pr->proto_id); + if (satype == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid proto_id %d\n", pr->proto_id); + goto err; + } + mode = ipsecdoi2pfkey_mode(pr->encmode); + if (mode == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid encmode %d\n", pr->encmode); + goto err; + } + + /* + * the policy level cannot be unique because the policy + * is defined later than SA, so req_id cannot be bound to SA. + */ + xisr->sadb_x_ipsecrequest_proto = satype; + xisr->sadb_x_ipsecrequest_mode = mode; + if(iph2->proposal->head->reqid_in > 0){ + xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE; + xisr->sadb_x_ipsecrequest_reqid = iph2->proposal->head->reqid_in; + }else{ + xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE; + xisr->sadb_x_ipsecrequest_reqid = 0; + } + p = (caddr_t)(xisr + 1); + + xisrlen = sizeof(*xisr); + + if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) { + int src_len, dst_len; + + src_len = sysdep_sa_len(src); + dst_len = sysdep_sa_len(dst); + xisrlen += src_len + dst_len; + + memcpy(p, src, src_len); + p += src_len; + + memcpy(p, dst, dst_len); + p += dst_len; + } + + xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen); + xisr = (struct sadb_x_ipsecrequest *)p; + + } + racoon_free(pr_rlist); + +end: + *policy0 = policy; + *policylen0 = policylen; + + return 0; + +err: + if (policy) + racoon_free(policy); + if (pr_rlist) racoon_free(pr_rlist); + + return -1; +} + +int +pk_sendspdupdate2(iph2) + struct ph2handle *iph2; +{ + struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen; + caddr_t policy = NULL; + int policylen = 0; + u_int64_t ltime, vtime; + + ltime = iph2->approval->lifetime; + vtime = 0; + + if (getsadbpolicy(&policy, &policylen, SADB_X_SPDUPDATE, iph2)) { + plog(LLV_ERROR, LOCATION, NULL, + "getting sadb policy failed.\n"); + return -1; + } + + if (pfkey_send_spdupdate2( + lcconf->sock_pfkey, + (struct sockaddr *)&spidx->src, + spidx->prefs, + (struct sockaddr *)&spidx->dst, + spidx->prefd, + spidx->ul_proto, + ltime, vtime, + policy, policylen, 0) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed send spdupdate2 (%s)\n", + ipsec_strerror()); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdupdate2\n"); + +end: + if (policy) + racoon_free(policy); + + return 0; +} + +static int +pk_recvspdupdate(mhp) + caddr_t *mhp; +{ + struct sadb_address *saddr, *daddr; + struct sadb_x_policy *xpl; + struct sadb_lifetime *lt; + struct policyindex spidx; + struct secpolicy *sp; + struct sockaddr *local=NULL, *remote=NULL; + u_int64_t created; + int ret; + + /* sanity check */ + if (mhp[0] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL + || mhp[SADB_X_EXT_POLICY] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb spdupdate message passed.\n"); + return -1; + } + saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; + daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; + xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; + lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; + if(lt != NULL) + created = lt->sadb_lifetime_addtime; + else + created = 0; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + saddr->sadb_address_proto, + xpl->sadb_x_policy_priority, + created, + &spidx); +#else + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + saddr->sadb_address_proto, + created, + &spidx); +#endif + +#ifdef HAVE_SECCTX + if (mhp[SADB_X_EXT_SEC_CTX] != NULL) { + struct sadb_x_sec_ctx *ctx; + + ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; + spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg; + spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi; + spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len; + memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len); + } +#endif /* HAVE_SECCTX */ + + sp = getsp(&spidx); + if (sp == NULL) { + plog(LLV_DEBUG, LOCATION, NULL, + "this policy did not exist for removal: \"%s\"\n", + spidx2str(&spidx)); + } else { + /* preserve hints before deleting the SP */ + local = sp->local; + remote = sp->remote; + sp->local = NULL; + sp->remote = NULL; + + remsp(sp); + delsp(sp); + } + + /* Add new SP (with old hints) */ + ret = addnewsp(mhp, local, remote); + + if (local != NULL) + racoon_free(local); + if (remote != NULL) + racoon_free(remote); + + if (ret < 0) + return -1; + + return 0; +} + +/* + * this function has to be used by responder side. + */ +int +pk_sendspdadd2(iph2) + struct ph2handle *iph2; +{ + struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen; + caddr_t policy = NULL; + int policylen = 0; + u_int64_t ltime, vtime; + + ltime = iph2->approval->lifetime; + vtime = 0; + + if (getsadbpolicy(&policy, &policylen, SADB_X_SPDADD, iph2)) { + plog(LLV_ERROR, LOCATION, NULL, + "getting sadb policy failed.\n"); + return -1; + } + + if (pfkey_send_spdadd2( + lcconf->sock_pfkey, + (struct sockaddr *)&spidx->src, + spidx->prefs, + (struct sockaddr *)&spidx->dst, + spidx->prefd, + spidx->ul_proto, + ltime, vtime, + policy, policylen, 0) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed send spdadd2 (%s)\n", + ipsec_strerror()); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdadd2\n"); + +end: + if (policy) + racoon_free(policy); + + return 0; +} + +static int +pk_recvspdadd(mhp) + caddr_t *mhp; +{ + struct sadb_address *saddr, *daddr; + struct sadb_x_policy *xpl; + struct sadb_lifetime *lt; + struct policyindex spidx; + struct secpolicy *sp; + struct sockaddr *local = NULL, *remote = NULL; + u_int64_t created; + int ret; + + /* sanity check */ + if (mhp[0] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL + || mhp[SADB_X_EXT_POLICY] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb spdadd message passed.\n"); + return -1; + } + saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; + daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; + xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; + lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; + if(lt != NULL) + created = lt->sadb_lifetime_addtime; + else + created = 0; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + saddr->sadb_address_proto, + xpl->sadb_x_policy_priority, + created, + &spidx); +#else + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + saddr->sadb_address_proto, + created, + &spidx); +#endif + +#ifdef HAVE_SECCTX + if (mhp[SADB_X_EXT_SEC_CTX] != NULL) { + struct sadb_x_sec_ctx *ctx; + + ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; + spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg; + spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi; + spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len; + memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len); + } +#endif /* HAVE_SECCTX */ + + sp = getsp(&spidx); + if (sp != NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "such policy already exists. " + "anyway replace it: %s\n", + spidx2str(&spidx)); + + /* preserve hints before deleting the SP */ + local = sp->local; + remote = sp->remote; + sp->local = NULL; + sp->remote = NULL; + + remsp(sp); + delsp(sp); + } + + /* Add new SP (with old hints) */ + ret = addnewsp(mhp, local, remote); + + if (local != NULL) + racoon_free(local); + if (remote != NULL) + racoon_free(remote); + + if (ret < 0) + return -1; + + return 0; +} + +/* + * this function has to be used by responder side. + */ +int +pk_sendspddelete(iph2) + struct ph2handle *iph2; +{ + struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen; + caddr_t policy = NULL; + int policylen; + + if (getsadbpolicy(&policy, &policylen, SADB_X_SPDDELETE, iph2)) { + plog(LLV_ERROR, LOCATION, NULL, + "getting sadb policy failed.\n"); + return -1; + } + + if (pfkey_send_spddelete( + lcconf->sock_pfkey, + (struct sockaddr *)&spidx->src, + spidx->prefs, + (struct sockaddr *)&spidx->dst, + spidx->prefd, + spidx->ul_proto, + policy, policylen, 0) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "libipsec failed send spddelete (%s)\n", + ipsec_strerror()); + goto end; + } + plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spddelete\n"); + +end: + if (policy) + racoon_free(policy); + + return 0; +} + +static int +pk_recvspddelete(mhp) + caddr_t *mhp; +{ + struct sadb_address *saddr, *daddr; + struct sadb_x_policy *xpl; + struct sadb_lifetime *lt; + struct policyindex spidx; + struct secpolicy *sp; + u_int64_t created; + + /* sanity check */ + if (mhp[0] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL + || mhp[SADB_X_EXT_POLICY] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb spddelete message passed.\n"); + return -1; + } + saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; + daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; + xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; + lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; + if(lt != NULL) + created = lt->sadb_lifetime_addtime; + else + created = 0; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + saddr->sadb_address_proto, + xpl->sadb_x_policy_priority, + created, + &spidx); +#else + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + saddr->sadb_address_proto, + created, + &spidx); +#endif + +#ifdef HAVE_SECCTX + if (mhp[SADB_X_EXT_SEC_CTX] != NULL) { + struct sadb_x_sec_ctx *ctx; + + ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; + spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg; + spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi; + spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len; + memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len); + } +#endif /* HAVE_SECCTX */ + + sp = getsp(&spidx); + if (sp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no policy found: %s\n", + spidx2str(&spidx)); + return -1; + } + + remsp(sp); + delsp(sp); + + return 0; +} + +static int +pk_recvspdexpire(mhp) + caddr_t *mhp; +{ + struct sadb_address *saddr, *daddr; + struct sadb_x_policy *xpl; + struct sadb_lifetime *lt; + struct policyindex spidx; + struct secpolicy *sp; + u_int64_t created; + + /* sanity check */ + if (mhp[0] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL + || mhp[SADB_X_EXT_POLICY] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb spdexpire message passed.\n"); + return -1; + } + saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; + daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; + xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; + lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; + if(lt != NULL) + created = lt->sadb_lifetime_addtime; + else + created = 0; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + saddr->sadb_address_proto, + xpl->sadb_x_policy_priority, + created, + &spidx); +#else + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + saddr->sadb_address_proto, + created, + &spidx); +#endif + +#ifdef HAVE_SECCTX + if (mhp[SADB_X_EXT_SEC_CTX] != NULL) { + struct sadb_x_sec_ctx *ctx; + + ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; + spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg; + spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi; + spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len; + memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len); + } +#endif /* HAVE_SECCTX */ + + sp = getsp(&spidx); + if (sp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no policy found: %s\n", + spidx2str(&spidx)); + return -1; + } + + remsp(sp); + delsp(sp); + + return 0; +} + +static int +pk_recvspdget(mhp) + caddr_t *mhp; +{ + /* sanity check */ + if (mhp[0] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb spdget message passed.\n"); + return -1; + } + + return 0; +} + +static int +pk_recvspddump(mhp) + caddr_t *mhp; +{ + struct sadb_msg *msg; + struct sadb_address *saddr, *daddr; + struct sadb_x_policy *xpl; + struct sadb_lifetime *lt; + struct policyindex spidx; + struct secpolicy *sp; + struct sockaddr *local=NULL, *remote=NULL; + u_int64_t created; + int ret; + + /* sanity check */ + if (mhp[0] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb spddump message passed.\n"); + return -1; + } + msg = (struct sadb_msg *)mhp[0]; + saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; + daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; + xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; + lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; + if(lt != NULL) + created = lt->sadb_lifetime_addtime; + else + created = 0; + + if (saddr == NULL || daddr == NULL || xpl == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb spddump message passed.\n"); + return -1; + } + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + saddr->sadb_address_proto, + xpl->sadb_x_policy_priority, + created, + &spidx); +#else + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + saddr->sadb_address_proto, + created, + &spidx); +#endif + +#ifdef HAVE_SECCTX + if (mhp[SADB_X_EXT_SEC_CTX] != NULL) { + struct sadb_x_sec_ctx *ctx; + + ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; + spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg; + spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi; + spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len; + memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len); + } +#endif /* HAVE_SECCTX */ + + sp = getsp(&spidx); + if (sp != NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "such policy already exists. " + "anyway replace it: %s\n", + spidx2str(&spidx)); + + /* preserve hints before deleting the SP */ + local = sp->local; + remote = sp->remote; + sp->local = NULL; + sp->remote = NULL; + + remsp(sp); + delsp(sp); + } + + /* Add new SP (with old hints) */ + ret = addnewsp(mhp, local, remote); + + if (local != NULL) + racoon_free(local); + if (remote != NULL) + racoon_free(remote); + + if (ret < 0) + return -1; + + return 0; +} + +static int +pk_recvspdflush(mhp) + caddr_t *mhp; +{ + /* sanity check */ + if (mhp[0] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb spdflush message passed.\n"); + return -1; + } + + flushsp(); + + return 0; +} + +#if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS) + +/* MIGRATE support (pk_recvmigrate() is the handler of MIGRATE message). + * + * pk_recvmigrate() + * 1) some preprocessing and checks + * 2) parsing of sadb_x_kmaddress extension + * 3) SP lookup using selectors and content of policy extension from MIGRATE + * 4) resolution of current local and remote IKE addresses + * 5) Use of addresses to get Phase 1 handler if any + * 6) Update of IKE addresses in Phase 1 (iph1->local and iph1->remote) + * 7) Update of IKE addresses in Phase 2 (iph2->src and iph2->dst) + * 8) Update of IKE addresses in SP (sp->local and sp->remote) + * 9) Loop on sadb_x_ipsecrequests pairs from MIGRATE + * - update of associated ipsecrequests entries in sp->req (should be + * only one as racoon does not support bundles), i.e. update of + * tunnel endpoints when required. + * - If tunnel mode endpoints have been updated, lookup of associated + * Phase 2 handle to also update sa_src and sa_dst entries + * + * XXX Note that we do not support yet the update of SA addresses for transport + * mode, but only the update of SA addresses for tunnel mode (endpoints). + * Reasons are: + * - there is no initial need for MIPv6 + * - racoon does not support bundles + * - this would imply more work to deal with sainfo update (if feasible). + */ + +/* Generic argument structure for migration callbacks */ +struct migrate_args { + struct sockaddr *local; + struct sockaddr *remote; +}; + +/* + * Update local and remote addresses of given Phase 1. Schedule removal + * if negotiation was going on and restart a one from updated address. + * + * -1 is returned on error. 0 if everything went right. + */ +static int +migrate_ph1_ike_addresses(iph1, arg) + struct ph1handle *iph1; + void *arg; +{ + struct migrate_args *ma = (struct migrate_args *) arg; + struct remoteconf *rmconf; + u_int16_t port; + + /* Already up-to-date? */ + if (cmpsaddr(iph1->local, ma->local) == CMPSADDR_MATCH && + cmpsaddr(iph1->remote, ma->remote) == CMPSADDR_MATCH) + return 0; + + if (iph1->status < PHASE1ST_ESTABLISHED) { + /* Bad luck! We received a MIGRATE *while* negotiating + * Phase 1 (i.e. it was not established yet). If we act as + * initiator we need to restart the negotiation. As + * responder, our best bet is to update our addresses + * and wait for the initiator to do something */ + plog(LLV_WARNING, LOCATION, NULL, "MIGRATE received *during* " + "Phase 1 negotiation (%s).\n", + saddr2str_fromto("%s => %s", ma->local, ma->remote)); + + /* If we are not acting as initiator, let's just leave and + * let the remote peer handle the restart */ + rmconf = getrmconf(ma->remote, 0); + if (rmconf == NULL || !rmconf->passive) { + iph1->status = PHASE1ST_EXPIRED; + isakmp_ph1delete(iph1); + + /* This is unlikely, but let's just check if a Phase 1 + * for the new addresses already exist */ + if (getph1byaddr(ma->local, ma->remote, 0)) { + plog(LLV_WARNING, LOCATION, NULL, "No need " + "to start a new Phase 1 negotiation. One " + "already exists.\n"); + return 0; + } + + plog(LLV_WARNING, LOCATION, NULL, "As initiator, " + "restarting it.\n"); + /* Note that the insertion of the new Phase 1 will not + * interfere with the fact we are called from enumph1, + * because it is inserted as first element. --arno */ + isakmp_ph1begin_i(rmconf, ma->local, ma->remote); + + return 0; + } + } + + if (iph1->local != NULL) { + plog(LLV_DEBUG, LOCATION, NULL, "Migrating Phase 1 local " + "address from %s\n", + saddr2str_fromto("%s to %s", iph1->local, ma->local)); + port = extract_port(iph1->local); + racoon_free(iph1->local); + } else + port = 0; + + iph1->local = dupsaddr(ma->local); + if (iph1->local == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "unable to allocate " + "Phase 1 local address.\n"); + return -1; + } + set_port(iph1->local, port); + + if (iph1->remote != NULL) { + plog(LLV_DEBUG, LOCATION, NULL, "Migrating Phase 1 remote " + "address from %s\n", + saddr2str_fromto("%s to %s", iph1->remote, ma->remote)); + port = extract_port(iph1->remote); + racoon_free(iph1->remote); + } else + port = 0; + + iph1->remote = dupsaddr(ma->remote); + if (iph1->remote == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "unable to allocate " + "Phase 1 remote address.\n"); + return -1; + } + set_port(iph1->remote, port); + + return 0; +} + +/* Update src and dst of all current Phase 2 handles. + * with provided local and remote addresses. + * Our intent is NOT to modify IPsec SA endpoints but IKE + * addresses so we need to take care to separate those if + * they are different. -1 is returned on error. 0 if everything + * went right. + * + * Note: we do not maintain port information as it is not + * expected to be meaningful --arno + */ +static int +migrate_ph2_ike_addresses(iph2, arg) + struct ph2handle *iph2; + void *arg; +{ + struct migrate_args *ma = (struct migrate_args *) arg; + struct ph1handle *iph1; + + /* If Phase 2 has an associated Phase 1, migrate addresses */ + if (iph2->ph1) + migrate_ph1_ike_addresses(iph2->ph1, arg); + + /* Already up-to-date? */ + if (cmpsaddr(iph2->src, ma->local) == CMPSADDR_MATCH && + cmpsaddr(iph2->dst, ma->remote) == CMPSADDR_MATCH) + return 0; + + /* save src/dst as sa_src/sa_dst before rewriting */ + if (iph2->sa_src == NULL && iph2->sa_dst == NULL) { + iph2->sa_src = iph2->src; + iph2->sa_dst = iph2->dst; + iph2->src = NULL; + iph2->dst = NULL; + } + + if (iph2->src != NULL) + racoon_free(iph2->src); + iph2->src = dupsaddr(ma->local); + if (iph2->src == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to allocate Phase 2 src address.\n"); + return -1; + } + + if (iph2->dst != NULL) + racoon_free(iph2->dst); + iph2->dst = dupsaddr(ma->remote); + if (iph2->dst == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to allocate Phase 2 dst address.\n"); + return -1; + } + + return 0; +} + +/* Consider existing Phase 2 handles with given spid and update their source + * and destination addresses for SA. As racoon does not support bundles, if + * we modify multiple occurrences, this probably imply rekeying has happened. + * + * Both addresses passed to the function are expected not to be NULL and of + * same family. -1 is returned on error. 0 if everything went right. + * + * Specific care is needed to support Phase 2 for which negotiation has + * already started but are which not yet established. + */ +static int +migrate_ph2_sa_addresses(iph2, args) + struct ph2handle *iph2; + void *args; +{ + struct migrate_args *ma = (struct migrate_args *) args; + + if (iph2->sa_src != NULL) { + racoon_free(iph2->sa_src); + iph2->sa_src = NULL; + } + + if (iph2->sa_dst != NULL) { + racoon_free(iph2->sa_dst); + iph2->sa_dst = NULL; + } + + iph2->sa_src = dupsaddr(ma->local); + if (iph2->sa_src == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to allocate Phase 2 sa_src address.\n"); + return -1; + } + + iph2->sa_dst = dupsaddr(ma->remote); + if (iph2->sa_dst == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to allocate Phase 2 sa_dst address.\n"); + return -1; + } + + if (iph2->status < PHASE2ST_ESTABLISHED) { + struct remoteconf *rmconf; + /* We were negotiating for that SA when we received the MIGRATE. + * We cannot simply update the addresses and let the exchange + * go on. We have to restart the whole negotiation if we are + * the initiator. Otherwise (acting as responder), we just need + * to delete our ph2handle and wait for the initiator to start + * a new negotiation. */ + + if (iph2->ph1 && iph2->ph1->rmconf) + rmconf = iph2->ph1->rmconf; + else + rmconf = getrmconf(iph2->dst, 0); + + if (rmconf && !rmconf->passive) { + struct ph1handle *iph1hint; + + plog(LLV_WARNING, LOCATION, iph2->dst, "MIGRATE received " + "*during* IPsec SA negotiation. As initiator, " + "restarting it.\n"); + + /* Turn off expiration timer ...*/ + sched_cancel(&iph2->sce); + iph2->status = PHASE2ST_EXPIRED; + + /* ... clean Phase 2 handle ... */ + iph1hint = iph2->ph1; + initph2(iph2); + iph2->status = PHASE2ST_STATUS2; + + /* and start a new negotiation */ + if (isakmp_post_acquire(iph2, iph1hint, FALSE) < 0) { + plog(LLV_ERROR, LOCATION, iph2->dst, "failed " + "to begin IPsec SA renegotiation after " + "MIGRATE reception.\n"); + remph2(iph2); + delph2(iph2); + return -1; + } + } else { + plog(LLV_WARNING, LOCATION, iph2->dst, "MIGRATE received " + "*during* IPsec SA negotiation. As responder, let's" + "wait for the initiator to act.\n"); + + /* Simply schedule deletion */ + isakmp_ph2expire(iph2); + } + } + + return 0; +} + +/* Update SP hints (local and remote addresses) for future IKE + * negotiations of SA associated with that SP. -1 is returned + * on error. 0 if everything went right. + * + * Note: we do not maintain port information as it is not + * expected to be meaningful --arno + */ +static int +migrate_sp_ike_addresses(sp, local, remote) + struct secpolicy *sp; + struct sockaddr *local, *remote; +{ + if (sp == NULL || local == NULL || remote == NULL) + return -1; + + if (sp->local != NULL) + racoon_free(sp->local); + + sp->local = dupsaddr(local); + if (sp->local == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "unable to allocate " + "local hint for SP.\n"); + return -1; + } + + if (sp->remote != NULL) + racoon_free(sp->remote); + + sp->remote = dupsaddr(remote); + if (sp->remote == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "unable to allocate " + "remote hint for SP.\n"); + return -1; + } + + return 0; +} + +/* Given current ipsecrequest (isr_cur) to be migrated in considered + tree, the function first checks that it matches the expected one + (xisr_old) provided in MIGRATE message and then updates the addresses + if it is tunnel mode (with content of xisr_new). Various other checks + are performed. For transport mode, structures are not modified, only + the checks are done. -1 is returned on error. */ +static int +migrate_ph2_one_isr(spid, isr_cur, xisr_old, xisr_new) + u_int32_t spid; + struct ipsecrequest *isr_cur; + struct sadb_x_ipsecrequest *xisr_old, *xisr_new; +{ + struct secasindex *saidx = &isr_cur->saidx; + struct sockaddr *osaddr, *odaddr, *nsaddr, *ndaddr; + struct ph2selector ph2sel; + struct migrate_args ma; + + /* First, check that mode and proto do match */ + if (xisr_old->sadb_x_ipsecrequest_proto != saidx->proto || + xisr_old->sadb_x_ipsecrequest_mode != saidx->mode || + xisr_new->sadb_x_ipsecrequest_proto != saidx->proto || + xisr_new->sadb_x_ipsecrequest_mode != saidx->mode) + return -1; + + /* Then, verify reqid if necessary */ + if (isr_cur->saidx.reqid && + (xisr_old->sadb_x_ipsecrequest_reqid != IPSEC_LEVEL_UNIQUE || + xisr_new->sadb_x_ipsecrequest_reqid != IPSEC_LEVEL_UNIQUE || + isr_cur->saidx.reqid != xisr_old->sadb_x_ipsecrequest_reqid || + isr_cur->saidx.reqid != xisr_new->sadb_x_ipsecrequest_reqid)) + return -1; + + /* If not tunnel mode, our work is over */ + if (saidx->mode != IPSEC_MODE_TUNNEL) { + plog(LLV_DEBUG, LOCATION, NULL, "SADB_X_MIGRATE: " + "non tunnel mode isr, skipping SA address migration.\n"); + return 0; + } + + /* Tunnel mode: let's check addresses do match and then update them. */ + osaddr = (struct sockaddr *)(xisr_old + 1); + odaddr = (struct sockaddr *)(((u_int8_t *)osaddr) + sysdep_sa_len(osaddr)); + nsaddr = (struct sockaddr *)(xisr_new + 1); + ndaddr = (struct sockaddr *)(((u_int8_t *)nsaddr) + sysdep_sa_len(nsaddr)); + + /* Check family does match */ + if (osaddr->sa_family != odaddr->sa_family || + nsaddr->sa_family != ndaddr->sa_family) + return -1; + + /* Check family does match */ + if (saidx->src.ss_family != osaddr->sa_family) + return -1; + + /* We log IPv4 to IPv6 and IPv6 to IPv4 switches */ + if (nsaddr->sa_family != osaddr->sa_family) + plog(LLV_INFO, LOCATION, NULL, "SADB_X_MIGRATE: " + "changing address families (%d to %d) for endpoints.\n", + osaddr->sa_family, nsaddr->sa_family); + + if (cmpsaddr(osaddr, (struct sockaddr *) &saidx->src) != CMPSADDR_MATCH || + cmpsaddr(odaddr, (struct sockaddr *) &saidx->dst) != CMPSADDR_MATCH) { + plog(LLV_DEBUG, LOCATION, NULL, "SADB_X_MIGRATE: " + "mismatch of addresses in saidx and xisr.\n"); + return -1; + } + + /* Excellent. Let's grab associated Phase 2 handle (if any) + * and update its sa_src and sa_dst entries. Note that we + * make the assumption that racoon does not support bundles + * and make the lookup using spid: we blindly update + * sa_src and sa_dst for _all_ found Phase 2 handles */ + memset(&ph2sel, 0, sizeof(ph2sel)); + ph2sel.spid = spid; + + memset(&ma, 0, sizeof(ma)); + ma.local = nsaddr; + ma.remote = ndaddr; + + if (enumph2(&ph2sel, migrate_ph2_sa_addresses, &ma) < 0) + return -1; + + /* Now we can do the update of endpoints in secasindex */ + memcpy(&saidx->src, nsaddr, sysdep_sa_len(nsaddr)); + memcpy(&saidx->dst, ndaddr, sysdep_sa_len(ndaddr)); + + return 0; +} + +/* Process the raw (unparsed yet) list of sadb_x_ipsecrequests of MIGRATE + * message. For each sadb_x_ipsecrequest pair (old followed by new), + * the corresponding ipsecrequest entry in the SP is updated. Associated + * existing Phase 2 handle is also updated (if any) */ +static int +migrate_sp_isr_list(sp, xisr_list, xisr_list_len) + struct secpolicy *sp; + struct sadb_x_ipsecrequest *xisr_list; + int xisr_list_len; +{ + struct sadb_x_ipsecrequest *xisr_new, *xisr_old = xisr_list; + int xisr_old_len, xisr_new_len; + struct ipsecrequest *isr_cur; + + isr_cur = sp->req; /* ipsecrequest list from from sp */ + + while (xisr_list_len > 0 && isr_cur != NULL) { + /* Get old xisr (length field is in bytes) */ + xisr_old_len = xisr_old->sadb_x_ipsecrequest_len; + if (xisr_old_len < sizeof(*xisr_old) || + xisr_old_len + sizeof(*xisr_new) > xisr_list_len) { + plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: " + "invalid ipsecrequest length. Exiting.\n"); + return -1; + } + + /* Get new xisr with updated info */ + xisr_new = (struct sadb_x_ipsecrequest *)(((u_int8_t *)xisr_old) + xisr_old_len); + xisr_new_len = xisr_new->sadb_x_ipsecrequest_len; + if (xisr_new_len < sizeof(*xisr_new) || + xisr_new_len + xisr_old_len > xisr_list_len) { + plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: " + "invalid ipsecrequest length. Exiting.\n"); + return -1; + } + + /* Start by migrating current ipsecrequest from SP */ + if (migrate_ph2_one_isr(sp->id, isr_cur, xisr_old, xisr_new) == -1) { + plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: " + "Unable to match and migrate isr. Exiting.\n"); + return -1; + } + + /* Update pointers for next round */ + xisr_list_len -= xisr_old_len + xisr_new_len; + xisr_old = (struct sadb_x_ipsecrequest *)(((u_int8_t *)xisr_new) + + xisr_new_len); + + isr_cur = isr_cur->next; /* Get next ipsecrequest from SP */ + } + + /* Check we had the same amount of pairs in the MIGRATE + as the number of ipsecrequests in the SP */ + if ((xisr_list_len != 0) || isr_cur != NULL) { + plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: " + "number of ipsecrequest does not match the one in SP.\n"); + return -1; + } + + return 0; +} + +/* Parse sadb_x_kmaddress extension and make local and remote + * parameters point to the new addresses (zero copy). -1 is + * returned on error, meaning that addresses are not usable */ +static int +parse_kmaddress(kmaddr, local, remote) + struct sadb_x_kmaddress *kmaddr; + struct sockaddr **local, **remote; +{ + int addrslen, local_len=0; + struct ph1handle *iph1; + + if (kmaddr == NULL) + return -1; + + /* Grab addresses in sadb_x_kmaddress extension */ + addrslen = PFKEY_EXTLEN(kmaddr) - sizeof(*kmaddr); + if (addrslen < sizeof(struct sockaddr)) + return -1; + + *local = (struct sockaddr *)(kmaddr + 1); + + switch ((*local)->sa_family) { + case AF_INET: + local_len = sizeof(struct sockaddr_in); + break; +#ifdef INET6 + case AF_INET6: + local_len = sizeof(struct sockaddr_in6); + break; +#endif + default: + return -1; + } + + if (addrslen != PFKEY_ALIGN8(2*local_len)) + return -1; + + *remote = (struct sockaddr *)(((u_int8_t *)(*local)) + local_len); + + if ((*local)->sa_family != (*remote)->sa_family) + return -1; + + return 0; +} + +/* Handler of PF_KEY MIGRATE message. Helpers are above */ +static int +pk_recvmigrate(mhp) + caddr_t *mhp; +{ + struct sadb_address *saddr, *daddr; + struct sockaddr *old_saddr, *new_saddr; + struct sockaddr *old_daddr, *new_daddr; + struct sockaddr *old_local, *old_remote; + struct sockaddr *local, *remote; + struct sadb_x_kmaddress *kmaddr; + struct sadb_x_policy *xpl; + struct sadb_x_ipsecrequest *xisr_list; + struct sadb_lifetime *lt; + struct policyindex spidx; + struct secpolicy *sp; + struct ipsecrequest *isr_cur; + struct secasindex *oldsaidx; + struct ph2handle *iph2; + struct ph1handle *iph1; + struct ph2selector ph2sel; + struct ph1selector ph1sel; + u_int32_t spid; + u_int64_t created; + int xisr_list_len; + int ulproto; + struct migrate_args ma; + + /* Some sanity checks */ + + if (mhp[0] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL + || mhp[SADB_X_EXT_KMADDRESS] == NULL + || mhp[SADB_X_EXT_POLICY] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "SADB_X_MIGRATE: invalid MIGRATE message received.\n"); + return -1; + } + kmaddr = (struct sadb_x_kmaddress *)mhp[SADB_X_EXT_KMADDRESS]; + saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; + daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; + xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; + lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; + if (lt != NULL) + created = lt->sadb_lifetime_addtime; + else + created = 0; + + if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) { + plog(LLV_WARNING, LOCATION, NULL,"SADB_X_MIGRATE: " + "found non IPsec policy in MIGRATE message. Exiting.\n"); + return -1; + } + + if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) { + plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: " + "invalid size for sadb_x_policy. Exiting.\n"); + return -1; + } + + /* Some logging to help debbugging */ + if (xpl->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND) + plog(LLV_DEBUG, LOCATION, NULL, + "SADB_X_MIGRATE: Outbound SA being migrated.\n"); + else + plog(LLV_DEBUG, LOCATION, NULL, + "SADB_X_MIGRATE: Inbound SA being migrated.\n"); + + /* validity check */ + xisr_list = (struct sadb_x_ipsecrequest *)(xpl + 1); + xisr_list_len = PFKEY_EXTLEN(xpl) - sizeof(*xpl); + if (xisr_list_len < sizeof(*xisr_list)) { + plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: " + "invalid sadb_x_policy message length. Exiting.\n"); + return -1; + } + + if (parse_kmaddress(kmaddr, &local, &remote) == -1) { + plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: " + "invalid sadb_x_kmaddress extension. Exiting.\n"); + return -1; + } + + /* 0 means ANY */ + if (saddr->sadb_address_proto == 0) + ulproto = IPSEC_ULPROTO_ANY; + else + ulproto = saddr->sadb_address_proto; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + ulproto, + xpl->sadb_x_policy_priority, + created, + &spidx); +#else + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + ulproto, + created, + &spidx); +#endif + + /* Everything seems ok, let's get the SP. + * + * XXX We could also do the lookup using the spid from xpl. + * I don't know which one is better. --arno */ + sp = getsp(&spidx); + if (sp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "SADB_X_MIGRATE: Passed policy does not exist: %s\n", + spidx2str(&spidx)); + return -1; + } + + /* Get the best source and destination addresses used for IKE + * negotiation, to find and migrate existing Phase 1 */ + if (sp->local && sp->remote) { + /* hints available, let's use them */ + old_local = (struct sockaddr *)sp->local; + old_remote = (struct sockaddr *)sp->remote; + } else if (sp->req && sp->req->saidx.mode == IPSEC_MODE_TUNNEL) { + /* Tunnel mode and no hint, use endpoints */ + old_local = (struct sockaddr *)&sp->req->saidx.src; + old_remote = (struct sockaddr *)&sp->req->saidx.dst; + } else { + /* default, use selectors as fallback */ + old_local = (struct sockaddr *)&sp->spidx.src; + old_remote = (struct sockaddr *)&sp->spidx.dst; + } + + /* We migrate all Phase 1 that match our old local and remote + * addresses (no matter their state). + * + * XXX In fact, we should probably havea special treatment for + * Phase 1 that are being established when we receive a MIGRATE. + * This can happen if a movement occurs during the initial IKE + * negotiation. In that case, I wonder if should restart the + * negotiation from the new address or just update things like + * we do it now. + * + * XXX while looking at getph1byaddr(), the comment at the + * beginning of the function expects comparison to happen + * without ports considerations but it uses CMPSADDR() which + * relies either on cmpsaddrstrict() or cmpsaddrwop() based + * on NAT-T support being activated. That make me wonder if I + * should force ports to 0 (ANY) in local and remote values + * used below. + * + * -- arno */ + + /* Apply callback data ...*/ + memset(&ma, 0, sizeof(ma)); + ma.local = local; + ma.remote = remote; + + /* Fill phase1 match criteria ... */ + memset(&ph1sel, 0, sizeof(ph1sel)); + ph1sel.local = old_local; + ph1sel.remote = old_remote; + + + /* Have matching Phase 1 found and addresses updated. As this is a + * time consuming task on a busy responder, and MIGRATE messages + * are always sent for *both* inbound and outbound (and possibly + * forward), we only do that for outbound SP. */ + if (xpl->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND && + enumph1(&ph1sel, migrate_ph1_ike_addresses, &ma) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: Unable " + "to migrate Phase 1 addresses.\n"); + return -1; + } + + /* We can now update IKE addresses in Phase 2 handle. */ + memset(&ph2sel, 0, sizeof(ph2sel)); + ph2sel.spid = sp->id; + if (enumph2(&ph2sel, migrate_ph2_ike_addresses, &ma) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: Unable " + "to migrate Phase 2 IKE addresses.\n"); + return -1; + } + + /* and _then_ in SP. */ + if (migrate_sp_ike_addresses(sp, local, remote) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "SADB_X_MIGRATE: Unable to migrate SP IKE addresses.\n"); + return -1; + } + + /* Loop on sadb_x_ipsecrequest list to possibly update sp->req + * entries and associated live Phase 2 handles (their sa_src + * and sa_dst) */ + if (migrate_sp_isr_list(sp, xisr_list, xisr_list_len) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "SADB_X_MIGRATE: Unable to migrate isr list.\n"); + return -1; + } + + return 0; +} +#endif + +/* + * send error against acquire message to kernel. + */ +int +pk_sendeacquire(iph2) + struct ph2handle *iph2; +{ + struct sadb_msg *newmsg; + int len; + + len = sizeof(struct sadb_msg); + newmsg = racoon_calloc(1, len); + if (newmsg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer to send acquire.\n"); + return -1; + } + + memset(newmsg, 0, len); + newmsg->sadb_msg_version = PF_KEY_V2; + newmsg->sadb_msg_type = SADB_ACQUIRE; + newmsg->sadb_msg_errno = ENOENT; /* XXX */ + newmsg->sadb_msg_satype = iph2->satype; + newmsg->sadb_msg_len = PFKEY_UNIT64(len); + newmsg->sadb_msg_reserved = 0; + newmsg->sadb_msg_seq = iph2->seq; + newmsg->sadb_msg_pid = (u_int32_t)getpid(); + + /* send message */ + len = pfkey_send(lcconf->sock_pfkey, newmsg, len); + + racoon_free(newmsg); + + return 0; +} + +/* + * check if the algorithm is supported or not. + * OUT 0: ok + * -1: ng + */ +int +pk_checkalg(class, calg, keylen) + int class, calg, keylen; +{ + int sup, error; + u_int alg; + struct sadb_alg alg0; + + switch (algclass2doi(class)) { + case IPSECDOI_PROTO_IPSEC_ESP: + sup = SADB_EXT_SUPPORTED_ENCRYPT; + break; + case IPSECDOI_ATTR_AUTH: + sup = SADB_EXT_SUPPORTED_AUTH; + break; + case IPSECDOI_PROTO_IPCOMP: + plog(LLV_DEBUG, LOCATION, NULL, + "no check of compression algorithm; " + "not supported in sadb message.\n"); + return 0; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid algorithm class.\n"); + return -1; + } + alg = ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg)); + if (alg == ~0) + return -1; + + if (keylen == 0) { + if (ipsec_get_keylen(sup, alg, &alg0)) { + plog(LLV_ERROR, LOCATION, NULL, + "%s.\n", ipsec_strerror()); + return -1; + } + keylen = alg0.sadb_alg_minbits; + } + + error = ipsec_check_keylen(sup, alg, keylen); + if (error) + plog(LLV_ERROR, LOCATION, NULL, + "%s.\n", ipsec_strerror()); + + return error; +} + +/* + * differences with pfkey_recv() in libipsec/pfkey.c: + * - never performs busy wait loop. + * - returns NULL and set *lenp to negative on fatal failures + * - returns NULL and set *lenp to non-negative on non-fatal failures + * - returns non-NULL on success + */ +static struct sadb_msg * +pk_recv(so, lenp) + int so; + int *lenp; +{ + struct sadb_msg buf, *newmsg; + int reallen; + int retry = 0; + + *lenp = -1; + do + { + plog(LLV_DEBUG, LOCATION, NULL, "pk_recv: retry[%d] recv() \n", retry ); + *lenp = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT); + retry++; + } + while (*lenp < 0 && errno == EAGAIN && retry < 3); + + if (*lenp < 0) + return NULL; /*fatal*/ + + else if (*lenp < sizeof(buf)) + return NULL; + + reallen = PFKEY_UNUNIT64(buf.sadb_msg_len); + if (reallen < sizeof(buf)) { + *lenp = -1; + errno = EIO; + return NULL; /*fatal*/ + } + if ((newmsg = racoon_calloc(1, reallen)) == NULL) + return NULL; + + *lenp = recv(so, (caddr_t)newmsg, reallen, MSG_PEEK); + if (*lenp < 0) { + racoon_free(newmsg); + return NULL; /*fatal*/ + } else if (*lenp != reallen) { + racoon_free(newmsg); + return NULL; + } + + *lenp = recv(so, (caddr_t)newmsg, reallen, 0); + if (*lenp < 0) { + racoon_free(newmsg); + return NULL; /*fatal*/ + } else if (*lenp != reallen) { + racoon_free(newmsg); + return NULL; + } + + return newmsg; +} + +/* see handler.h */ +u_int32_t +pk_getseq() +{ + return eay_random(); +} + +static int +addnewsp(mhp, local, remote) + caddr_t *mhp; + struct sockaddr *local, *remote; +{ + struct secpolicy *new = NULL; + struct sadb_address *saddr, *daddr; + struct sadb_x_policy *xpl; + struct sadb_lifetime *lt; + u_int64_t created; + + /* sanity check */ + if (mhp[SADB_EXT_ADDRESS_SRC] == NULL + || mhp[SADB_EXT_ADDRESS_DST] == NULL + || mhp[SADB_X_EXT_POLICY] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb spd management message passed.\n"); + goto bad; + } + + saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; + daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; + xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; + lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; + if(lt != NULL) + created = lt->sadb_lifetime_addtime; + else + created = 0; + lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; + if(lt != NULL) + created = lt->sadb_lifetime_addtime; + else + created = 0; + +#ifdef __linux__ + /* bsd skips over per-socket policies because there will be no + * src and dst extensions in spddump messages. On Linux the only + * way to achieve the same is check for policy id. + */ + if (xpl->sadb_x_policy_id % 8 >= 3) return 0; +#endif + + new = newsp(); + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer\n"); + goto bad; + } + + new->spidx.dir = xpl->sadb_x_policy_dir; + new->id = xpl->sadb_x_policy_id; + new->policy = xpl->sadb_x_policy_type; + new->req = NULL; + + /* check policy */ + switch (xpl->sadb_x_policy_type) { + case IPSEC_POLICY_DISCARD: + case IPSEC_POLICY_NONE: + case IPSEC_POLICY_ENTRUST: + case IPSEC_POLICY_BYPASS: + break; + + case IPSEC_POLICY_IPSEC: + { + int tlen; + struct sadb_x_ipsecrequest *xisr; + struct ipsecrequest **p_isr = &new->req; + + /* validity check */ + if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid msg length.\n"); + goto bad; + } + + tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl); + xisr = (struct sadb_x_ipsecrequest *)(xpl + 1); + + while (tlen > 0) { + + /* length check */ + if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid msg length.\n"); + goto bad; + } + + /* allocate request buffer */ + *p_isr = newipsecreq(); + if (*p_isr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get new ipsecreq.\n"); + goto bad; + } + + /* set values */ + (*p_isr)->next = NULL; + + switch (xisr->sadb_x_ipsecrequest_proto) { + case IPPROTO_ESP: + case IPPROTO_AH: + case IPPROTO_IPCOMP: + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid proto type: %u\n", + xisr->sadb_x_ipsecrequest_proto); + goto bad; + } + (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto; + + switch (xisr->sadb_x_ipsecrequest_mode) { + case IPSEC_MODE_TRANSPORT: + case IPSEC_MODE_TUNNEL: + break; + case IPSEC_MODE_ANY: + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid mode: %u\n", + xisr->sadb_x_ipsecrequest_mode); + goto bad; + } + (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode; + + switch (xisr->sadb_x_ipsecrequest_level) { + case IPSEC_LEVEL_DEFAULT: + case IPSEC_LEVEL_USE: + case IPSEC_LEVEL_REQUIRE: + break; + case IPSEC_LEVEL_UNIQUE: + (*p_isr)->saidx.reqid = + xisr->sadb_x_ipsecrequest_reqid; + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid level: %u\n", + xisr->sadb_x_ipsecrequest_level); + goto bad; + } + (*p_isr)->level = xisr->sadb_x_ipsecrequest_level; + + /* set IP addresses if there */ + if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) { + struct sockaddr *paddr; + + paddr = (struct sockaddr *)(xisr + 1); + bcopy(paddr, &(*p_isr)->saidx.src, + sysdep_sa_len(paddr)); + + paddr = (struct sockaddr *)((caddr_t)paddr + + sysdep_sa_len(paddr)); + bcopy(paddr, &(*p_isr)->saidx.dst, + sysdep_sa_len(paddr)); + } + + (*p_isr)->sp = new; + + /* initialization for the next. */ + p_isr = &(*p_isr)->next; + tlen -= xisr->sadb_x_ipsecrequest_len; + + /* validity check */ + if (tlen < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "becoming tlen < 0\n"); + } + + xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr + + xisr->sadb_x_ipsecrequest_len); + } + } + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid policy type.\n"); + goto bad; + } + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + saddr->sadb_address_proto, + xpl->sadb_x_policy_priority, + created, + &new->spidx); +#else + KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, + saddr + 1, + daddr + 1, + saddr->sadb_address_prefixlen, + daddr->sadb_address_prefixlen, + saddr->sadb_address_proto, + created, + &new->spidx); +#endif + +#ifdef HAVE_SECCTX + if (mhp[SADB_X_EXT_SEC_CTX] != NULL) { + struct sadb_x_sec_ctx *ctx; + + ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; + new->spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg; + new->spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi; + new->spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len; + memcpy(new->spidx.sec_ctx.ctx_str,ctx + 1,ctx->sadb_x_ctx_len); + } +#endif /* HAVE_SECCTX */ + + /* Set local and remote hints for that SP, if available */ + if (local && remote) { + new->local = dupsaddr(local); + new->remote = dupsaddr(remote); + } + + inssp(new); + + return 0; +bad: + if (new != NULL) { + if (new->req != NULL) + racoon_free(new->req); + racoon_free(new); + } + return -1; +} + +/* proto/mode/src->dst spi */ +const char * +sadbsecas2str(src, dst, proto, spi, mode) + struct sockaddr *src, *dst; + int proto; + u_int32_t spi; + int mode; +{ + static char buf[256]; + u_int doi_proto, doi_mode = 0; + char *p; + int blen, i; + + doi_proto = pfkey2ipsecdoi_proto(proto); + if (doi_proto == ~0) + return NULL; + if (mode) { + doi_mode = pfkey2ipsecdoi_mode(mode); + if (doi_mode == ~0) + return NULL; + } + + blen = sizeof(buf) - 1; + p = buf; + + i = snprintf(p, blen, "%s%s%s ", + s_ipsecdoi_proto(doi_proto), + mode ? "/" : "", + mode ? s_ipsecdoi_encmode(doi_mode) : ""); + if (i < 0 || i >= blen) + return NULL; + p += i; + blen -= i; + + i = snprintf(p, blen, "%s->", saddr2str(src)); + if (i < 0 || i >= blen) + return NULL; + p += i; + blen -= i; + + i = snprintf(p, blen, "%s ", saddr2str(dst)); + if (i < 0 || i >= blen) + return NULL; + p += i; + blen -= i; + + if (spi) { + snprintf(p, blen, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi), + (unsigned long)ntohl(spi)); + } + + return buf; +} diff --git a/ipsec-tools/src/racoon/pfkey.h b/ipsec-tools/src/racoon/pfkey.h new file mode 100644 index 00000000..cfe111dc --- /dev/null +++ b/ipsec-tools/src/racoon/pfkey.h @@ -0,0 +1,75 @@ +/* $NetBSD: pfkey.h,v 1.8 2009/07/03 06:40:10 tteras Exp $ */ + +/* Id: pfkey.h,v 1.3 2004/06/11 16:00:17 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _PFKEY_H +#define _PFKEY_H + +struct pfkey_satype { + u_int8_t ps_satype; + const char *ps_name; +}; + +extern const struct pfkey_satype pfkey_satypes[]; +extern const int pfkey_nsatypes; + +extern vchar_t *pfkey_dump_sadb __P((int)); +extern void pfkey_flush_sadb __P((u_int)); +extern int pfkey_init __P((void)); +extern int pfkey_reload __P((void)); + +extern struct pfkey_st *pfkey_getpst __P((caddr_t *, int, int)); + +extern int pk_checkalg __P((int, int, int)); + +struct ph2handle; +extern void pk_fixup_sa_addresses __P((caddr_t *mhp)); +extern int pk_sendgetspi __P((struct ph2handle *)); +extern int pk_sendupdate __P((struct ph2handle *)); +extern int pk_sendadd __P((struct ph2handle *)); +extern int pk_sendeacquire __P((struct ph2handle *)); +extern int pk_sendspdupdate2 __P((struct ph2handle *)); +extern int pk_sendspdadd2 __P((struct ph2handle *)); +extern int pk_sendspddelete __P((struct ph2handle *)); + +extern u_int pfkey2ipsecdoi_proto __P((u_int)); +extern u_int ipsecdoi2pfkey_proto __P((u_int)); +extern u_int pfkey2ipsecdoi_mode __P((u_int)); +extern u_int ipsecdoi2pfkey_mode __P((u_int)); + +extern int pfkey_convertfromipsecdoi __P(( u_int, u_int, u_int, + u_int *, u_int *, u_int *, u_int *, u_int *)); +extern u_int32_t pk_getseq __P((void)); +extern const char *sadbsecas2str + __P((struct sockaddr *, struct sockaddr *, int, u_int32_t, int)); + +#endif /* _PFKEY_H */ diff --git a/ipsec-tools/src/racoon/plainrsa-gen.8 b/ipsec-tools/src/racoon/plainrsa-gen.8 new file mode 100644 index 00000000..377de2dc --- /dev/null +++ b/ipsec-tools/src/racoon/plainrsa-gen.8 @@ -0,0 +1,138 @@ +.\" $NetBSD: plainrsa-gen.8,v 1.13 2006/09/19 18:54:39 wiz Exp $ +.\" +.\" Id: plainrsa-gen.8,v 1.4 2005/04/18 11:07:55 manubsd Exp +.\" +.\" Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. +.\" Contributed by: Michal Ludvig , SUSE Labs +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the project nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd June 14, 2004 +.Dt PLAINRSA-GEN 8 +.Os +.\" +.Sh NAME +.Nm plainrsa-gen +.Nd generator for Plain RSA keys +.\" +.Sh SYNOPSIS +.Nm plainrsa-gen +.Bk -words +.Op Fl b Ar bits +.Op Fl e Ar pubexp +.Op Fl f Ar outfile +.Op Fl h +.Ek +.\" +.Sh DESCRIPTION +.Nm +can be used to generate +.Li Plain RSA keys +for authentication purposes. +Using +.Li Plain RSA keys +is optional. +Other possibilities are +.Li Pre-shared keys +or +.Li X.509 certificates . +.\" +.Bl -tag -width Ds +.It Fl b Ar bits +bit length of the key. +Default is +.Li 1024 , +recommended length is +.Li 2048 +or even +.Li 4096 +bits. +Note that generating longer keys takes longer time. +.It Fl e Ar pubexp +value of RSA public exponent. +Default is +.Li 0x3 . +Don't change this unless you really know what you are doing! +.It Fl f Ar outfile +.Ar outfile +instead of +.Li stdout . +If the file already exists it won't be overwritten. +You wouldn't like to lose your private key by accident, would you? +.El +.\" +.Sh OUTPUT FILE FORMAT +This is the secret +.Li private key +that should +.Ic never +leave your computer: +.Bd -literal +: RSA { + # RSA 1024 bits + # pubkey=0sAQOrWlcwbAIdNSMhDt... + Modulus: 0xab5a57306c021d3523... + PublicExponent: 0x03 + PrivateExponent: 0x723c3a2048... + Prime1: 0xd309b30e6adf9d85c01... + Prime2: 0xcfdc2a8aa5b2b3c90e3... + Exponent1: 0x8cb122099c9513ae... + Exponent2: 0x8a92c7071921cd30... + Coefficient: 0x722751305eafe9... + } +.Ed +.Pp +The line +.Li pubkey=0sAQOrW... +of the +.Li private key +contains a +.Li public key +that should be stored in the other peer's configuration in this format: +.Bd -literal +: PUB 0sAQOrWlcwbAIdNSMhDt... +.Ed +.\" +.Pp +You can also specify +.Li from +and +.Li to +addresses for which the key is valid: +.Bd -literal +0.0.0.0/0 10.20.30.0/24 : PUB 0sAQOrWlcwbAIdNSMhDt... +.Ed +.\" +.Sh SEE ALSO +.Xr racoon.conf 5 , +.Xr racoon 8 +.\" +.Sh HISTORY +.Nm +was written by +.An Michal Ludvig Aq michal@logix.cz +and first appeared in +.Ic ipsec-tools 0.4 . diff --git a/ipsec-tools/src/racoon/plainrsa-gen.c b/ipsec-tools/src/racoon/plainrsa-gen.c new file mode 100644 index 00000000..cad1861b --- /dev/null +++ b/ipsec-tools/src/racoon/plainrsa-gen.c @@ -0,0 +1,307 @@ +/* $NetBSD: plainrsa-gen.c,v 1.6 2011/02/11 10:07:19 tteras Exp $ */ + +/* Id: plainrsa-gen.c,v 1.6 2005/04/21 09:08:40 monas Exp */ +/* + * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. + * Contributed by: Michal Ludvig , SUSE Labs + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* This file contains a generator for FreeS/WAN-style ipsec.secrets RSA keys. */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_OPENSSL_ENGINE_H +#include +#endif + +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "crypto_openssl.h" + +#include "package_version.h" + +void +usage (char *argv0) +{ + fprintf(stderr, "Plain RSA key generator, part of %s\n", TOP_PACKAGE_STRING); + fprintf(stderr, "By Michal Ludvig (http://www.logix.cz/michal)\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: %s [options]\n", argv0); + fprintf(stderr, "\n"); + fprintf(stderr, " -b bits Generate long RSA key (default=1024)\n"); + fprintf(stderr, " -e pubexp Public exponent to use (default=0x3)\n"); + fprintf(stderr, " -f filename Filename to store the key to (default=stdout)\n"); + fprintf(stderr, " -i filename Input source for format conversion\n"); + fprintf(stderr, " -h Help\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Report bugs to \n"); + exit(1); +} + +/* + * See RFC 2065, section 3.5 for details about the output format. + */ +vchar_t * +mix_b64_pubkey(const RSA *key) +{ + char *binbuf; + long binlen, ret; + vchar_t *res; + + binlen = 1 + BN_num_bytes(key->e) + BN_num_bytes(key->n); + binbuf = malloc(binlen); + memset(binbuf, 0, binlen); + binbuf[0] = BN_bn2bin(key->e, (unsigned char *) &binbuf[1]); + ret = BN_bn2bin(key->n, (unsigned char *) (&binbuf[binbuf[0] + 1])); + if (1 + binbuf[0] + ret != binlen) { + plog(LLV_ERROR, LOCATION, NULL, + "Pubkey generation failed. This is really strange...\n"); + return NULL; + } + + return base64_encode(binbuf, binlen); +} + +char * +lowercase(char *input) +{ + char *ptr = input; + while (*ptr) { + if (*ptr >= 'A' && *ptr <= 'F') + *ptr -= 'A' - 'a'; + *ptr++; + } + + return input; +} + +int +print_rsa_key(FILE *fp, const RSA *key) +{ + vchar_t *pubkey64 = NULL; + + pubkey64 = mix_b64_pubkey(key); + if (!pubkey64) { + fprintf(stderr, "mix_b64_pubkey(): %s\n", eay_strerror()); + return -1; + } + + fprintf(fp, "# : PUB 0s%s\n", pubkey64->v); + fprintf(fp, ": RSA\t{\n"); + fprintf(fp, "\t# RSA %d bits\n", BN_num_bits(key->n)); + fprintf(fp, "\t# pubkey=0s%s\n", pubkey64->v); + fprintf(fp, "\tModulus: 0x%s\n", lowercase(BN_bn2hex(key->n))); + fprintf(fp, "\tPublicExponent: 0x%s\n", lowercase(BN_bn2hex(key->e))); + fprintf(fp, "\tPrivateExponent: 0x%s\n", lowercase(BN_bn2hex(key->d))); + fprintf(fp, "\tPrime1: 0x%s\n", lowercase(BN_bn2hex(key->p))); + fprintf(fp, "\tPrime2: 0x%s\n", lowercase(BN_bn2hex(key->q))); + fprintf(fp, "\tExponent1: 0x%s\n", lowercase(BN_bn2hex(key->dmp1))); + fprintf(fp, "\tExponent2: 0x%s\n", lowercase(BN_bn2hex(key->dmq1))); + fprintf(fp, "\tCoefficient: 0x%s\n", lowercase(BN_bn2hex(key->iqmp))); + fprintf(fp, " }\n"); + + vfree(pubkey64); + return 0; +} + +int +print_public_rsa_key(FILE *fp, const RSA *key) +{ + vchar_t *pubkey64 = NULL; + + pubkey64 = mix_b64_pubkey(key); + if (!pubkey64) { + fprintf(stderr, "mix_b64_pubkey(): %s\n", eay_strerror()); + return -1; + } + + fprintf(fp, ": PUB 0s%s\n", pubkey64->v); + + vfree(pubkey64); + return 0; +} + +int +convert_rsa_key(FILE *fpout, FILE *fpin) +{ + int ret; + RSA *key = NULL; + + key = PEM_read_RSAPrivateKey(fpin, NULL, NULL, NULL); + if (key) { + ret = print_rsa_key(fpout, key); + RSA_free(key); + + return ret; + } + + rewind(fpin); + + key = PEM_read_RSA_PUBKEY(fpin, NULL, NULL, NULL); + if (key) { + ret = print_public_rsa_key(fpout, key); + RSA_free(key); + + return ret; + } + + /* Implement parsing of input stream containing + * private or public "plainrsa" formatted text. + * Convert the result to PEM formatted output. + * + * This seemingly needs manual use of prsaparse(). + * An expert ought to do this. */ + + fprintf(stderr, "convert_rsa_key: %s\n", "Only conversion from PEM at this time"); + return -1; +} + +int +gen_rsa_key(FILE *fp, size_t bits, unsigned long exp) +{ + int ret; + RSA *key; + + key = RSA_generate_key(bits, exp, NULL, NULL); + if (!key) { + fprintf(stderr, "RSA_generate_key(): %s\n", eay_strerror()); + return -1; + } + + ret = print_rsa_key(fp, key); + RSA_free(key); + + return ret; +} + +int +main (int argc, char *argv[]) +{ + FILE *fp = stdout, *fpin = NULL; + size_t bits = 1024; + unsigned int pubexp = 0x3; + struct stat st; + extern char *optarg; + extern int optind; + int c, fd = -1, fdin = -1; + char *fname = NULL, *finput = NULL; + + while ((c = getopt(argc, argv, "e:b:f:i:h")) != -1) + switch (c) { + case 'e': + if (strncmp(optarg, "0x", 2) == 0) + sscanf(optarg, "0x%x", &pubexp); + else + pubexp = atoi(optarg); + break; + case 'b': + bits = atoi(optarg); + break; + case 'f': + fname = optarg; + break; + case 'i': + finput = optarg; + break; + case 'h': + default: + usage(argv[0]); + } + + if (fname) { + umask(0077); + /* Restrictive access due to private key material. */ + fd = open(fname, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, S_IRUSR | S_IWUSR); + if (fd < 0) { + if (errno == EEXIST) + fprintf(stderr, "%s: file exists! Please use a different name.\n", fname); + else + fprintf(stderr, "%s: %s\n", fname, strerror(errno)); + exit(1); + } + fp = fdopen(fd, "w"); + if (fp == NULL) { + fprintf(stderr, "%s: %s\n", fname, strerror(errno)); + close(fd); + exit(1); + } + } + + if (finput) { + /* Restrictive access once more. Do not be fooled by a link. */ + fdin = open(finput, O_RDONLY | O_NOFOLLOW); + if (fdin < 0) { + if (errno == ELOOP) + fprintf(stderr, "%s: file is a link. Discarded for security.\n", fname); + if (fp) + fclose(fp); + exit(1); + } + fpin = fdopen(fdin, "r"); + if (fpin == NULL) { + fprintf(stderr, "%s: %s\n", fname, strerror(errno)); + close(fdin); + if (fp) + fclose(fp); + exit(1); + } + + } + + ploginit(); + eay_init(); + + if (fpin) + convert_rsa_key(fp, fpin); + else + gen_rsa_key(fp, bits, pubexp); + + fclose(fp); + if (fpin) + fclose(fpin); + + return 0; +} diff --git a/ipsec-tools/src/racoon/plog.c b/ipsec-tools/src/racoon/plog.c new file mode 100644 index 00000000..aebfed27 --- /dev/null +++ b/ipsec-tools/src/racoon/plog.c @@ -0,0 +1,295 @@ +/* $NetBSD: plog.c,v 1.7 2011/01/28 12:51:40 tteras Exp $ */ + +/* Id: plog.c,v 1.11 2006/06/20 09:57:31 vanhu Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#include +#ifdef HAVE_STDARG_H +#include +#else +#include +#endif +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#include +#include + +#include "var.h" +#include "misc.h" +#include "plog.h" +#include "logger.h" +#include "debug.h" +#include "gcmalloc.h" + +#ifndef VA_COPY +# define VA_COPY(dst,src) memcpy(&(dst), &(src), sizeof(va_list)) +#endif + +char *pname = NULL; +u_int32_t loglevel = LLV_BASE; +int f_foreground = 0; + +int print_location = 0; + +static struct log *logp = NULL; +static char *logfile = NULL; + +static char *plog_common __P((int, const char *, const char *, struct sockaddr *)); + +static struct plogtags { + char *name; + int priority; +} ptab[] = { + { "(not defined)", 0, }, + { "ERROR", LOG_INFO, }, + { "WARNING", LOG_INFO, }, + { "NOTIFY", LOG_INFO, }, + { "INFO", LOG_INFO, }, + { "DEBUG", LOG_DEBUG, }, + { "DEBUG2", LOG_DEBUG, }, +}; + +static char * +plog_common(pri, fmt, func, sa) + int pri; + const char *fmt, *func; + struct sockaddr *sa; +{ + static char buf[800]; /* XXX shoule be allocated every time ? */ + void *addr; + char *p; + int reslen, len; + + p = buf; + reslen = sizeof(buf); + + if (logfile || f_foreground) { + time_t t; + struct tm *tm; + + t = time(0); + tm = localtime(&t); + len = strftime(p, reslen, "%Y-%m-%d %T: ", tm); + p += len; + reslen -= len; + } + + if (sa && reslen > 3) { + addr = NULL; + switch (sa->sa_family) { + case AF_INET: + addr = &((struct sockaddr_in*)sa)->sin_addr; + break; + case AF_INET6: + addr = &((struct sockaddr_in6*)sa)->sin6_addr; + break; + } + if (inet_ntop(sa->sa_family, addr, p + 1, reslen - 3) != NULL) { + *p++ = '['; + len = strlen(p); + p += len; + *p++ = ']'; + *p++ = ' '; + reslen -= len + 3; + } + } + + if (pri < ARRAYLEN(ptab)) { + len = snprintf(p, reslen, "%s: ", ptab[pri].name); + p += len; + reslen -= len; + } + + if (print_location) + len = snprintf(p, reslen, "%s: %s", func, fmt); + else + len = snprintf(p, reslen, "%s", fmt); + p += len; + reslen -= len; + + /* Force nul termination */ + if (reslen == 0) + p[-1] = 0; + +#ifdef BROKEN_PRINTF + while ((p = strstr(buf,"%z")) != NULL) + p[1] = 'l'; +#endif + + return buf; +} + +void +_plog(int pri, const char *func, struct sockaddr *sa, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + plogv(pri, func, sa, fmt, ap); + va_end(ap); +} + +void +plogv(int pri, const char *func, struct sockaddr *sa, + const char *fmt, va_list ap) +{ + char *newfmt; + va_list ap_bak; + + if (pri > loglevel) + return; + + newfmt = plog_common(pri, fmt, func, sa); + + VA_COPY(ap_bak, ap); + + if (f_foreground) + vprintf(newfmt, ap); + + if (logfile) + log_vaprint(logp, newfmt, ap_bak); + else { + if (pri < ARRAYLEN(ptab)) + vsyslog(ptab[pri].priority, newfmt, ap_bak); + else + vsyslog(LOG_ALERT, newfmt, ap_bak); + } +} + +void +plogdump(pri, data, len) + int pri; + void *data; + size_t len; +{ + caddr_t buf; + size_t buflen; + int i, j; + + if (pri > loglevel) + return; + + /* + * 2 words a bytes + 1 space 4 bytes + 1 newline 32 bytes + * + 2 newline + '\0' + */ + buflen = (len * 2) + (len / 4) + (len / 32) + 3; + buf = racoon_malloc(buflen); + + i = 0; + j = 0; + while (j < len) { + if (j % 32 == 0) + buf[i++] = '\n'; + else + if (j % 4 == 0) + buf[i++] = ' '; + snprintf(&buf[i], buflen - i, "%02x", + ((unsigned char *)data)[j] & 0xff); + i += 2; + j++; + } + if (buflen - i >= 2) { + buf[i++] = '\n'; + buf[i] = '\0'; + } + plog(pri, LOCATION, NULL, "%s", buf); + + racoon_free(buf); +} + +void +ploginit() +{ + if (logfile) { + logp = log_open(250, logfile); + if (logp == NULL) + errx(1, "ERROR: failed to open log file %s.", logfile); + return; + } + + openlog(pname, LOG_NDELAY, LOG_DAEMON); +} + +void +plogset(file) + char *file; +{ + if (logfile != NULL) + racoon_free(logfile); + logfile = racoon_strdup(file); + STRDUP_FATAL(logfile); +} + +/* + Returns a printable string from (possibly) binary data ; + concatenates all unprintable chars to one space. + XXX Maybe the printable chars range is too large... + */ +char* +binsanitize(binstr, n) + char *binstr; + size_t n; +{ + int p,q; + char* d; + + d = racoon_malloc(n + 1); + for (p = 0, q = 0; p < n; p++) { + if (isgraph((int)binstr[p])) { + d[q++] = binstr[p]; + } else { + if (q && d[q - 1] != ' ') + d[q++] = ' '; + } + } + d[q++] = '\0'; + + return d; +} + diff --git a/ipsec-tools/src/racoon/plog.h b/ipsec-tools/src/racoon/plog.h new file mode 100644 index 00000000..ed43c8bf --- /dev/null +++ b/ipsec-tools/src/racoon/plog.h @@ -0,0 +1,82 @@ +/* $NetBSD: plog.h,v 1.5 2007/10/02 09:47:40 vanhu Exp $ */ + +/* Id: plog.h,v 1.7 2006/06/20 09:57:31 vanhu Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _PLOG_H +#define _PLOG_H + +#ifdef HAVE_STDARG_H +#include +#else +#include +#endif +#include + +/* + * INFO: begin negotiation, SA establishment/deletion/expiration. + * NOTIFY: just notifiable. + * WARNING: not error strictly. + * ERROR: system call error. also invalid parameter/format. + * DEBUG1: debugging informatioin. + * DEBUG2: too more verbose. e.g. parsing config. + */ +#define LLV_ERROR 1 +#define LLV_WARNING 2 +#define LLV_NOTIFY 3 +#define LLV_INFO 4 +#define LLV_DEBUG 5 +#define LLV_DEBUG2 6 + +#define LLV_BASE LLV_INFO /* by default log less than this value. */ + +extern char *pname; +extern u_int32_t loglevel; +extern int f_foreground; +extern int print_location; + +struct sockaddr; +#define plog(pri, ...) \ + do { \ + if ((pri) <= loglevel) \ + _plog((pri), __VA_ARGS__); \ + } while (0) +extern void _plog __P((int, const char *, struct sockaddr *, const char *, ...)) + __attribute__ ((__format__ (__printf__, 4, 5))); +extern void plogv __P((int, const char *, struct sockaddr *, + const char *, va_list)); +extern void plogdump __P((int, void *, size_t)); +extern void ploginit __P((void)); +extern void plogset __P((char *)); + +extern char* binsanitize __P((char*, size_t)); + +#endif /* _PLOG_H */ diff --git a/ipsec-tools/src/racoon/policy.c b/ipsec-tools/src/racoon/policy.c new file mode 100644 index 00000000..4c00677e --- /dev/null +++ b/ipsec-tools/src/racoon/policy.c @@ -0,0 +1,498 @@ +/* $NetBSD: policy.c,v 1.12 2011/03/14 17:18:13 tteras Exp $ */ + +/* $KAME: policy.c,v 1.46 2001/11/16 04:08:10 sakane Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "debug.h" + +#include "policy.h" +#include "localconf.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "oakley.h" +#include "handler.h" +#include "strnames.h" +#include "gcmalloc.h" + +static TAILQ_HEAD(_sptree, secpolicy) sptree; + +/* perform exact match against security policy table. */ +struct secpolicy * +getsp(spidx) + struct policyindex *spidx; +{ + struct secpolicy *p; + + for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) { + if (!cmpspidxstrict(spidx, &p->spidx)) + return p; + } + + return NULL; +} + +/* + * perform non-exact match against security policy table, only if this is + * transport mode SA negotiation. for example, 0.0.0.0/0 -> 0.0.0.0/0 + * entry in policy.txt can be returned when we're negotiating transport + * mode SA. this is how the kernel works. + */ +#if 1 +struct secpolicy * +getsp_r(spidx) + struct policyindex *spidx; +{ + struct secpolicy *p; + struct secpolicy *found = NULL; + + for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) { + if (!cmpspidxstrict(spidx, &p->spidx)) + return p; + + if (!found && !cmpspidxwild(spidx, &p->spidx)) + found = p; + } + + return found; +} +#else +struct secpolicy * +getsp_r(spidx, iph2) + struct policyindex *spidx; + struct ph2handle *iph2; +{ + struct secpolicy *p; + u_int8_t prefixlen; + + plog(LLV_DEBUG, LOCATION, NULL, "checking for transport mode\n"); + + if (spidx->src.ss_family != spidx->dst.ss_family) { + plog(LLV_ERROR, LOCATION, NULL, + "address family mismatch, src:%d dst:%d\n", + spidx->src.ss_family, + spidx->dst.ss_family); + return NULL; + } + switch (spidx->src.ss_family) { + case AF_INET: + prefixlen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + prefixlen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid family: %d\n", spidx->src.ss_family); + return NULL; + } + + /* is it transport mode SA negotiation? */ + plog(LLV_DEBUG, LOCATION, NULL, "src1: %s\n", + saddr2str(iph2->src)); + plog(LLV_DEBUG, LOCATION, NULL, "src2: %s\n", + saddr2str((struct sockaddr *)&spidx->src)); + + if (cmpsaddr(iph2->src, (struct sockaddr *) &spidx->src) != CMPSADDR_MATCH || + spidx->prefs != prefixlen) + return NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "dst1: %s\n", + saddr2str(iph2->dst)); + plog(LLV_DEBUG, LOCATION, NULL, "dst2: %s\n", + saddr2str((struct sockaddr *)&spidx->dst)); + + if (cmpsaddr(iph2->dst, (struct sockaddr *) &spidx->dst) != CMPSADDR_MATCH || + spidx->prefd != prefixlen) + return NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "looks to be transport mode\n"); + + for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) { + if (!cmpspidx_wild(spidx, &p->spidx)) + return p; + } + + return NULL; +} +#endif + +struct secpolicy * +getspbyspid(spid) + u_int32_t spid; +{ + struct secpolicy *p; + + for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) { + if (p->id == spid) + return p; + } + + return NULL; +} + +/* + * compare policyindex. + * a: subject b: db + * OUT: 0: equal + * 1: not equal + */ +int +cmpspidxstrict(a, b) + struct policyindex *a, *b; +{ + plog(LLV_DEBUG, LOCATION, NULL, "sub:%p: %s\n", a, spidx2str(a)); + plog(LLV_DEBUG, LOCATION, NULL, "db :%p: %s\n", b, spidx2str(b)); + + /* XXX don't check direction now, but it's to be checked carefully. */ + if (a->dir != b->dir + || a->prefs != b->prefs + || a->prefd != b->prefd + || a->ul_proto != b->ul_proto) + return 1; + + if (cmpsaddr((struct sockaddr *) &a->src, + (struct sockaddr *) &b->src) != CMPSADDR_MATCH) + return 1; + if (cmpsaddr((struct sockaddr *) &a->dst, + (struct sockaddr *) &b->dst) != CMPSADDR_MATCH) + return 1; + +#ifdef HAVE_SECCTX + if (a->sec_ctx.ctx_alg != b->sec_ctx.ctx_alg + || a->sec_ctx.ctx_doi != b->sec_ctx.ctx_doi + || !within_range(a->sec_ctx.ctx_str, b->sec_ctx.ctx_str)) + return 1; +#endif + return 0; +} + +/* + * compare policyindex, with wildcard address/protocol match. + * a: subject b: db, can contain wildcard things. + * OUT: 0: equal + * 1: not equal + */ +int +cmpspidxwild(a, b) + struct policyindex *a, *b; +{ + struct sockaddr_storage sa1, sa2; + + plog(LLV_DEBUG, LOCATION, NULL, "sub:%p: %s\n", a, spidx2str(a)); + plog(LLV_DEBUG, LOCATION, NULL, "db: %p: %s\n", b, spidx2str(b)); + + if (!(b->dir == IPSEC_DIR_ANY || a->dir == b->dir)) + return 1; + + if (!(b->ul_proto == IPSEC_ULPROTO_ANY || + a->ul_proto == b->ul_proto)) + return 1; + + if (a->src.ss_family != b->src.ss_family) + return 1; + if (a->dst.ss_family != b->dst.ss_family) + return 1; + +#ifndef __linux__ + /* compare src address */ + if (sizeof(sa1) < a->src.ss_len || sizeof(sa2) < b->src.ss_len) { + plog(LLV_ERROR, LOCATION, NULL, + "unexpected error: " + "src.ss_len:%d dst.ss_len:%d\n", + a->src.ss_len, b->src.ss_len); + return 1; + } +#endif + mask_sockaddr((struct sockaddr *)&sa1, (struct sockaddr *)&a->src, + b->prefs); + mask_sockaddr((struct sockaddr *)&sa2, (struct sockaddr *)&b->src, + b->prefs); + plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n", + a, b->prefs, saddr2str((struct sockaddr *)&sa1)); + plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n", + b, b->prefs, saddr2str((struct sockaddr *)&sa2)); + if (cmpsaddr((struct sockaddr *)&sa1, (struct sockaddr *)&sa2) > CMPSADDR_WILDPORT_MATCH) + return 1; + +#ifndef __linux__ + /* compare dst address */ + if (sizeof(sa1) < a->dst.ss_len || sizeof(sa2) < b->dst.ss_len) { + plog(LLV_ERROR, LOCATION, NULL, "unexpected error\n"); + exit(1); + } +#endif + mask_sockaddr((struct sockaddr *)&sa1, (struct sockaddr *)&a->dst, + b->prefd); + mask_sockaddr((struct sockaddr *)&sa2, (struct sockaddr *)&b->dst, + b->prefd); + plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n", + a, b->prefd, saddr2str((struct sockaddr *)&sa1)); + plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n", + b, b->prefd, saddr2str((struct sockaddr *)&sa2)); + if (cmpsaddr((struct sockaddr *)&sa1, (struct sockaddr *)&sa2) > CMPSADDR_WILDPORT_MATCH) + return 1; + +#ifdef HAVE_SECCTX + if (a->sec_ctx.ctx_alg != b->sec_ctx.ctx_alg + || a->sec_ctx.ctx_doi != b->sec_ctx.ctx_doi + || !within_range(a->sec_ctx.ctx_str, b->sec_ctx.ctx_str)) + return 1; +#endif + return 0; +} + +struct secpolicy * +newsp() +{ + struct secpolicy *new; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) + return NULL; + + return new; +} + +void +delsp(sp) + struct secpolicy *sp; +{ + struct ipsecrequest *req = NULL, *next; + + for (req = sp->req; req; req = next) { + next = req->next; + racoon_free(req); + } + + if (sp->local) + racoon_free(sp->local); + if (sp->remote) + racoon_free(sp->remote); + + racoon_free(sp); +} + +void +delsp_bothdir(spidx0) + struct policyindex *spidx0; +{ + struct policyindex spidx; + struct secpolicy *sp; + struct sockaddr_storage src, dst; + u_int8_t prefs, prefd; + + memcpy(&spidx, spidx0, sizeof(spidx)); + switch (spidx.dir) { + case IPSEC_DIR_INBOUND: +#ifdef HAVE_POLICY_FWD + case IPSEC_DIR_FWD: +#endif + src = spidx.src; + dst = spidx.dst; + prefs = spidx.prefs; + prefd = spidx.prefd; + break; + case IPSEC_DIR_OUTBOUND: + src = spidx.dst; + dst = spidx.src; + prefs = spidx.prefd; + prefd = spidx.prefs; + break; + default: + return; + } + + spidx.src = src; + spidx.dst = dst; + spidx.prefs = prefs; + spidx.prefd = prefd; + spidx.dir = IPSEC_DIR_INBOUND; + + sp = getsp(&spidx); + if (sp) { + remsp(sp); + delsp(sp); + } + +#ifdef HAVE_POLICY_FWD + spidx.dir = IPSEC_DIR_FWD; + + sp = getsp(&spidx); + if (sp) { + remsp(sp); + delsp(sp); + } +#endif + + spidx.src = dst; + spidx.dst = src; + spidx.prefs = prefd; + spidx.prefd = prefs; + spidx.dir = IPSEC_DIR_OUTBOUND; + + sp = getsp(&spidx); + if (sp) { + remsp(sp); + delsp(sp); + } +} + +void +inssp(new) + struct secpolicy *new; +{ +#ifdef HAVE_PFKEY_POLICY_PRIORITY + struct secpolicy *p; + + TAILQ_FOREACH(p, &sptree, chain) { + if (new->spidx.priority < p->spidx.priority) { + TAILQ_INSERT_BEFORE(p, new, chain); + return; + } + } + if (p == NULL) +#endif + TAILQ_INSERT_TAIL(&sptree, new, chain); + + return; +} + +void +remsp(sp) + struct secpolicy *sp; +{ + TAILQ_REMOVE(&sptree, sp, chain); +} + +void +flushsp() +{ + struct secpolicy *p, *next; + + for (p = TAILQ_FIRST(&sptree); p; p = next) { + next = TAILQ_NEXT(p, chain); + remsp(p); + delsp(p); + } +} + +void +initsp() +{ + TAILQ_INIT(&sptree); +} + +struct ipsecrequest * +newipsecreq() +{ + struct ipsecrequest *new; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) + return NULL; + + return new; +} + +const char * +spidx2str(spidx) + const struct policyindex *spidx; +{ + /* addr/pref[port] addr/pref[port] ul dir act */ + static char buf[256]; + char *p, *a, *b; + int blen, i; + + blen = sizeof(buf) - 1; + p = buf; + + a = saddr2str((const struct sockaddr *)&spidx->src); + for (b = a; *b != '\0'; b++) + if (*b == '[') { + *b = '\0'; + b++; + break; + } + i = snprintf(p, blen, "%s/%d[%s ", a, spidx->prefs, b); + if (i < 0 || i >= blen) + return NULL; + p += i; + blen -= i; + + a = saddr2str((const struct sockaddr *)&spidx->dst); + for (b = a; *b != '\0'; b++) + if (*b == '[') { + *b = '\0'; + b++; + break; + } + i = snprintf(p, blen, "%s/%d[%s ", a, spidx->prefd, b); + if (i < 0 || i >= blen) + return NULL; + p += i; + blen -= i; + + i = snprintf(p, blen, "proto=%s dir=%s", + s_proto(spidx->ul_proto), s_direction(spidx->dir)); + +#ifdef HAVE_SECCTX + if (spidx->sec_ctx.ctx_strlen) { + p += i; + blen -= i; + snprintf(p, blen, " sec_ctx:doi=%d,alg=%d,len=%d,str=%s", + spidx->sec_ctx.ctx_doi, spidx->sec_ctx.ctx_alg, + spidx->sec_ctx.ctx_strlen, spidx->sec_ctx.ctx_str); + } +#endif + return buf; +} diff --git a/ipsec-tools/src/racoon/policy.h b/ipsec-tools/src/racoon/policy.h new file mode 100644 index 00000000..ef7f9236 --- /dev/null +++ b/ipsec-tools/src/racoon/policy.h @@ -0,0 +1,169 @@ +/* $NetBSD: policy.h,v 1.8 2008/12/05 06:02:20 tteras Exp $ */ + +/* Id: policy.h,v 1.5 2004/06/11 16:00:17 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _POLICY_H +#define _POLICY_H + +#include + + +#ifdef HAVE_SECCTX +#define MAX_CTXSTR_SIZE 50 +struct security_ctx { + u_int8_t ctx_doi; /* Security Context DOI */ + u_int8_t ctx_alg; /* Security Context Algorithm */ + u_int16_t ctx_strlen; /* Security Context stringlength + * (includes terminating NULL) + */ + char ctx_str[MAX_CTXSTR_SIZE]; /* Security Context string */ +}; +#endif + +/* refs. ipsec.h */ +/* + * Security Policy Index + * NOTE: Ensure to be same address family and upper layer protocol. + * NOTE: ul_proto, port number, uid, gid: + * ANY: reserved for waldcard. + * 0 to (~0 - 1): is one of the number of each value. + */ +struct policyindex { + u_int8_t dir; /* direction of packet flow, see blow */ + struct sockaddr_storage src; /* IP src address for SP */ + struct sockaddr_storage dst; /* IP dst address for SP */ + u_int8_t prefs; /* prefix length in bits for src */ + u_int8_t prefd; /* prefix length in bits for dst */ + u_int16_t ul_proto; /* upper layer Protocol */ + u_int32_t priority; /* priority for the policy */ + u_int64_t created; /* Used for generated SPD entries deletion */ +#ifdef HAVE_SECCTX + struct security_ctx sec_ctx; /* Security Context */ +#endif +}; + +/* Security Policy Data Base */ +struct secpolicy { + TAILQ_ENTRY(secpolicy) chain; + + struct policyindex spidx; /* selector */ + u_int32_t id; /* It's unique number on the system. */ + + u_int policy; /* DISCARD, NONE or IPSEC, see keyv2.h */ + struct ipsecrequest *req; + /* pointer to the ipsec request tree, */ + /* if policy == IPSEC else this value == NULL.*/ + + /* MIPv6 needs to perform negotiation of SA using different addresses + * than the endpoints of the SA (CoA for the source). In that case, + * MIGRATE msg provides that info (before movement occurs on the MN) */ + struct sockaddr *local; + struct sockaddr *remote; +}; + +/* Security Assocciation Index */ +/* NOTE: Ensure to be same address family */ +struct secasindex { + struct sockaddr_storage src; /* srouce address for SA */ + struct sockaddr_storage dst; /* destination address for SA */ + u_int16_t proto; /* IPPROTO_ESP or IPPROTO_AH */ + u_int8_t mode; /* mode of protocol, see ipsec.h */ + u_int32_t reqid; /* reqid id who owned this SA */ + /* see IPSEC_MANUAL_REQID_MAX. */ +}; + +/* Request for IPsec */ +struct ipsecrequest { + struct ipsecrequest *next; + /* pointer to next structure */ + /* If NULL, it means the end of chain. */ + + struct secasindex saidx;/* hint for search proper SA */ + /* if __ss_len == 0 then no address specified.*/ + u_int level; /* IPsec level defined below. */ + + struct secpolicy *sp; /* back pointer to SP */ +}; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY +#define KEY_SETSECSPIDX(_dir, s, d, ps, pd, ulp, _priority, _created, idx) \ +do { \ + bzero((idx), sizeof(struct policyindex)); \ + (idx)->dir = (_dir); \ + (idx)->prefs = (ps); \ + (idx)->prefd = (pd); \ + (idx)->ul_proto = (ulp); \ + (idx)->priority = (_priority); \ + (idx)->created = (_created); \ + memcpy(&(idx)->src, (s), sysdep_sa_len((struct sockaddr *)(s))); \ + memcpy(&(idx)->dst, (d), sysdep_sa_len((struct sockaddr *)(d))); \ +} while (0) +#else +#define KEY_SETSECSPIDX(_dir, s, d, ps, pd, ulp, _created, idx) \ +do { \ + bzero((idx), sizeof(struct policyindex)); \ + (idx)->dir = (_dir); \ + (idx)->prefs = (ps); \ + (idx)->prefd = (pd); \ + (idx)->ul_proto = (ulp); \ + (idx)->created = (_created); \ + memcpy(&(idx)->src, (s), sysdep_sa_len((struct sockaddr *)(s))); \ + memcpy(&(idx)->dst, (d), sysdep_sa_len((struct sockaddr *)(d))); \ +} while (0) +#endif + +struct ph2handle; +struct policyindex; +extern struct secpolicy *getsp __P((struct policyindex *)); +extern struct secpolicy *getsp_r __P((struct policyindex *)); +struct secpolicy *getspbyspid __P((u_int32_t)); +extern int cmpspidxstrict __P((struct policyindex *, struct policyindex *)); +extern int cmpspidxwild __P((struct policyindex *, struct policyindex *)); +extern struct secpolicy *newsp __P((void)); +extern void delsp __P((struct secpolicy *)); +extern void delsp_bothdir __P((struct policyindex *)); +extern void inssp __P((struct secpolicy *)); +extern void remsp __P((struct secpolicy *)); +extern void flushsp __P((void)); +extern void initsp __P((void)); +extern struct ipsecrequest *newipsecreq __P((void)); + +extern const char *spidx2str __P((const struct policyindex *)); +#ifdef HAVE_SECCTX +#include +extern int get_security_context __P((vchar_t *, struct policyindex *)); +extern void init_avc __P((void)); +extern int within_range __P((security_context_t, security_context_t)); +extern void set_secctx_in_proposal __P((struct ph2handle *, struct policyindex)); +#endif + +#endif /* _POLICY_H */ diff --git a/ipsec-tools/src/racoon/privsep.c b/ipsec-tools/src/racoon/privsep.c new file mode 100644 index 00000000..f222c406 --- /dev/null +++ b/ipsec-tools/src/racoon/privsep.c @@ -0,0 +1,1807 @@ +/* $NetBSD: privsep.c,v 1.21.2.1 2011/08/12 05:46:06 tteras Exp $ */ + +/* Id: privsep.c,v 1.15 2005/08/08 11:23:44 vanhu Exp */ + +/* + * Copyright (C) 2004 Emmanuel Dreyfus + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#ifdef __NetBSD__ +#include /* for setproctitle */ +#endif +#include +#include +#include + +#include +#include +#include + +#include + +#include "gcmalloc.h" +#include "vmbuf.h" +#include "misc.h" +#include "plog.h" +#include "var.h" + +#include "crypto_openssl.h" +#include "isakmp_var.h" +#include "isakmp.h" +#ifdef ENABLE_HYBRID +#include "resolv.h" +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif +#include "localconf.h" +#include "remoteconf.h" +#include "admin.h" +#include "sockmisc.h" +#include "privsep.h" +#include "session.h" + +static int privsep_sock[2] = { -1, -1 }; + +static int privsep_recv(int, struct privsep_com_msg **, size_t *); +static int privsep_send(int, struct privsep_com_msg *, size_t); +static int safety_check(struct privsep_com_msg *, int i); +static int port_check(int); +static int unsafe_env(char *const *); +static int unknown_name(int); +static int unsafe_path(char *, int); +static int rec_fd(int); +static int send_fd(int, int); + +struct socket_args { + int domain; + int type; + int protocol; +}; + +struct sockopt_args { + int s; + int level; + int optname; + const void *optval; + socklen_t optlen; +}; + +struct bind_args { + int s; + const struct sockaddr *addr; + socklen_t addrlen; +}; + +static int +privsep_send(sock, buf, len) + int sock; + struct privsep_com_msg *buf; + size_t len; +{ + if (buf == NULL) + return 0; + + if (sendto(sock, (char *)buf, len, 0, NULL, 0) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_send failed: %s\n", + strerror(errno)); + return -1; + } + + racoon_free((char *)buf); + + return 0; +} + + +static int +privsep_recv(sock, bufp, lenp) + int sock; + struct privsep_com_msg **bufp; + size_t *lenp; +{ + struct admin_com com; + struct admin_com *combuf; + size_t len; + + *bufp = NULL; + *lenp = 0; + + /* Get the header */ + while ((len = recvfrom(sock, (char *)&com, + sizeof(com), MSG_PEEK, NULL, NULL)) == -1) { + if (errno == EINTR) + continue; + if (errno == ECONNRESET) + return -1; + + plog(LLV_ERROR, LOCATION, NULL, + "privsep_recv failed: %s\n", + strerror(errno)); + return -1; + } + + /* EOF, other side has closed. */ + if (len == 0) + return -1; + + /* Check for short packets */ + if (len < sizeof(com)) { + plog(LLV_ERROR, LOCATION, NULL, + "corrupted privsep message (short header)\n"); + return -1; + } + + /* Allocate buffer for the whole message */ + if ((combuf = (struct admin_com *)racoon_malloc(com.ac_len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate memory: %s\n", strerror(errno)); + return -1; + } + + /* Get the whole buffer */ + while ((len = recvfrom(sock, (char *)combuf, + com.ac_len, 0, NULL, NULL)) == -1) { + if (errno == EINTR) + continue; + if (errno == ECONNRESET) + return -1; + plog(LLV_ERROR, LOCATION, NULL, + "failed to recv privsep command: %s\n", + strerror(errno)); + return -1; + } + + /* We expect len to match */ + if (len != com.ac_len) { + plog(LLV_ERROR, LOCATION, NULL, + "corrupted privsep message (short packet)\n"); + return -1; + } + + *bufp = (struct privsep_com_msg *)combuf; + *lenp = len; + + return 0; +} + +static int +privsep_do_exit(void *ctx, int fd) +{ + kill(getpid(), SIGTERM); + return 0; +} + +int +privsep_init(void) +{ + int i; + pid_t child_pid; + + /* If running as root, we don't use the privsep code path */ + if (lcconf->uid == 0) + return 0; + + /* + * When running privsep, certificate and script paths + * are mandatory, as they enable us to check path safety + * in the privileged instance + */ + if ((lcconf->pathinfo[LC_PATHTYPE_CERT] == NULL) || + (lcconf->pathinfo[LC_PATHTYPE_SCRIPT] == NULL)) { + plog(LLV_ERROR, LOCATION, NULL, "privilege separation " + "require path cert and path script in the config file\n"); + return -1; + } + + if (socketpair(PF_LOCAL, SOCK_STREAM, 0, privsep_sock) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate privsep_sock: %s\n", strerror(errno)); + return -1; + } + + switch (child_pid = fork()) { + case -1: + plog(LLV_ERROR, LOCATION, NULL, "Cannot fork privsep: %s\n", + strerror(errno)); + return -1; + break; + + case 0: /* Child: drop privileges */ + (void)close(privsep_sock[0]); + + if (lcconf->chroot != NULL) { + if (chdir(lcconf->chroot) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot chdir(%s): %s\n", lcconf->chroot, + strerror(errno)); + return -1; + } + if (chroot(lcconf->chroot) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot chroot(%s): %s\n", lcconf->chroot, + strerror(errno)); + return -1; + } + } + + if (setgid(lcconf->gid) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot setgid(%d): %s\n", lcconf->gid, + strerror(errno)); + return -1; + } + + if (setegid(lcconf->gid) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot setegid(%d): %s\n", lcconf->gid, + strerror(errno)); + return -1; + } + + if (setuid(lcconf->uid) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot setuid(%d): %s\n", lcconf->uid, + strerror(errno)); + return -1; + } + + if (seteuid(lcconf->uid) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot seteuid(%d): %s\n", lcconf->uid, + strerror(errno)); + return -1; + } + monitor_fd(privsep_sock[1], privsep_do_exit, NULL, 0); + + return 0; + break; + + default: /* Parent: privileged process */ + break; + } + + /* + * Close everything except the socketpair, + * and stdout if running in the forground. + */ + for (i = sysconf(_SC_OPEN_MAX); i > 0; i--) { + if (i == privsep_sock[0]) + continue; + if ((f_foreground) && (i == 1)) + continue; + (void)close(i); + } + + /* Above trickery closed the log file, reopen it */ + ploginit(); + + plog(LLV_INFO, LOCATION, NULL, + "racoon privileged process running with PID %d\n", getpid()); + + plog(LLV_INFO, LOCATION, NULL, + "racoon unprivileged process running with PID %d\n", child_pid); + +#if defined(__NetBSD__) || defined(__FreeBSD__) + setproctitle("[priv]"); +#endif + + /* + * Don't catch any signal + * This duplicate session:signals[], which is static... + */ + signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, SIG_DFL); + signal(SIGINT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGUSR1, SIG_DFL); + signal(SIGUSR2, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + + while (1) { + size_t len; + struct privsep_com_msg *combuf; + struct privsep_com_msg *reply; + char *data; + size_t *buflen; + size_t totallen; + char *bufs[PRIVSEP_NBUF_MAX]; + int i; + + if (privsep_recv(privsep_sock[0], &combuf, &len) != 0) + goto out; + + /* Safety checks and gather the data */ + if (len < sizeof(*combuf)) { + plog(LLV_ERROR, LOCATION, NULL, + "corrupted privsep message (short buflen)\n"); + goto out; + } + + data = (char *)(combuf + 1); + totallen = sizeof(*combuf); + for (i = 0; i < PRIVSEP_NBUF_MAX; i++) { + bufs[i] = (char *)data; + data += combuf->bufs.buflen[i]; + totallen += combuf->bufs.buflen[i]; + } + + if (totallen > len) { + plog(LLV_ERROR, LOCATION, NULL, + "corrupted privsep message (bufs too big)\n"); + goto out; + } + + /* Prepare the reply buffer */ + if ((reply = racoon_malloc(sizeof(*reply))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate reply buffer: %s\n", + strerror(errno)); + goto out; + } + bzero(reply, sizeof(*reply)); + reply->hdr.ac_cmd = combuf->hdr.ac_cmd; + reply->hdr.ac_len = sizeof(*reply); + + switch(combuf->hdr.ac_cmd) { + /* + * XXX Improvement: instead of returning the key, + * stuff eay_get_pkcs1privkey and eay_get_x509sign + * together and sign the hash in the privileged + * instance? + * pro: the key remains inaccessible to unpriv + * con: a compromised unpriv racoon can still sign anything + */ + case PRIVSEP_EAY_GET_PKCS1PRIVKEY: { + vchar_t *privkey; + + /* Make sure the string is NULL terminated */ + if (safety_check(combuf, 0) != 0) + break; + bufs[0][combuf->bufs.buflen[0] - 1] = '\0'; + + if (unsafe_path(bufs[0], LC_PATHTYPE_CERT) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_eay_get_pkcs1privkey: " + "unsafe cert \"%s\"\n", bufs[0]); + } + + plog(LLV_DEBUG, LOCATION, NULL, + "eay_get_pkcs1privkey(\"%s\")\n", bufs[0]); + + if ((privkey = eay_get_pkcs1privkey(bufs[0])) == NULL){ + reply->hdr.ac_errno = errno; + break; + } + + reply->bufs.buflen[0] = privkey->l; + reply->hdr.ac_len = sizeof(*reply) + privkey->l; + reply = racoon_realloc(reply, reply->hdr.ac_len); + if (reply == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate reply buffer: %s\n", + strerror(errno)); + goto out; + } + + memcpy(reply + 1, privkey->v, privkey->l); + vfree(privkey); + break; + } + + case PRIVSEP_SCRIPT_EXEC: { + char *script; + int name; + char **envp = NULL; + int envc = 0; + int count = 0; + int i; + + /* + * First count the bufs, and make sure strings + * are NULL terminated. + * + * We expect: script, name, envp[], void + */ + if (safety_check(combuf, 0) != 0) + break; + bufs[0][combuf->bufs.buflen[0] - 1] = '\0'; + count++; /* script */ + + count++; /* name */ + + for (; count < PRIVSEP_NBUF_MAX; count++) { + if (combuf->bufs.buflen[count] == 0) + break; + bufs[count] + [combuf->bufs.buflen[count] - 1] = '\0'; + envc++; + } + + /* count a void buf and perform safety check */ + count++; + if (count >= PRIVSEP_NBUF_MAX) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_script_exec: too many args\n"); + goto out; + } + + + /* + * Allocate the arrays for envp + */ + envp = racoon_malloc((envc + 1) * sizeof(char *)); + if (envp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot allocate memory: %s\n", + strerror(errno)); + goto out; + } + bzero(envp, (envc + 1) * sizeof(char *)); + + + /* + * Populate script, name and envp + */ + count = 0; + script = bufs[count++]; + + if (combuf->bufs.buflen[count] != sizeof(name)) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_script_exec: corrupted message\n"); + goto out; + } + memcpy((char *)&name, bufs[count++], sizeof(name)); + + for (i = 0; combuf->bufs.buflen[count]; count++) + envp[i++] = bufs[count]; + + count++; /* void */ + + plog(LLV_DEBUG, LOCATION, NULL, + "script_exec(\"%s\", %d, %p)\n", + script, name, envp); + + /* + * Check env for dangerous variables + * Check script path and name + * Perform fork and execve + */ + if ((unsafe_env(envp) == 0) && + (unknown_name(name) == 0) && + (unsafe_path(script, LC_PATHTYPE_SCRIPT) == 0)) + (void)script_exec(script, name, envp); + else + plog(LLV_ERROR, LOCATION, NULL, + "privsep_script_exec: " + "unsafe script \"%s\"\n", script); + + racoon_free(envp); + break; + } + + case PRIVSEP_GETPSK: { + vchar_t *psk; + int keylen; + + /* Make sure the string is NULL terminated */ + if (safety_check(combuf, 0) != 0) + break; + bufs[0][combuf->bufs.buflen[0] - 1] = '\0'; + + if (combuf->bufs.buflen[1] != sizeof(keylen)) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_getpsk: corrupted message\n"); + goto out; + } + memcpy(&keylen, bufs[1], sizeof(keylen)); + + plog(LLV_DEBUG, LOCATION, NULL, + "getpsk(\"%s\", %d)\n", bufs[0], keylen); + + if ((psk = getpsk(bufs[0], keylen)) == NULL) { + reply->hdr.ac_errno = errno; + break; + } + + reply->bufs.buflen[0] = psk->l; + reply->hdr.ac_len = sizeof(*reply) + psk->l; + reply = racoon_realloc(reply, reply->hdr.ac_len); + if (reply == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate reply buffer: %s\n", + strerror(errno)); + goto out; + } + + memcpy(reply + 1, psk->v, psk->l); + vfree(psk); + break; + } + + case PRIVSEP_SOCKET: { + struct socket_args socket_args; + int s; + + /* Make sure the string is NULL terminated */ + if (safety_check(combuf, 0) != 0) + break; + + if (combuf->bufs.buflen[0] != + sizeof(struct socket_args)) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_socket: corrupted message\n"); + goto out; + } + memcpy(&socket_args, bufs[0], + sizeof(struct socket_args)); + + if (socket_args.domain != PF_INET && + socket_args.domain != PF_INET6) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_socket: " + "unauthorized domain (%d)\n", + socket_args.domain); + goto out; + } + + if ((s = socket(socket_args.domain, socket_args.type, + socket_args.protocol)) == -1) { + reply->hdr.ac_errno = errno; + break; + } + + if (send_fd(privsep_sock[0], s) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_socket: send_fd failed\n"); + close(s); + goto out; + } + + close(s); + break; + } + + case PRIVSEP_BIND: { + struct bind_args bind_args; + int err, port = 0; + + /* Make sure the string is NULL terminated */ + if (safety_check(combuf, 0) != 0) + break; + + if (combuf->bufs.buflen[0] != + sizeof(struct bind_args)) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_bind: corrupted message\n"); + goto out; + } + memcpy(&bind_args, bufs[0], sizeof(struct bind_args)); + + if (combuf->bufs.buflen[1] != bind_args.addrlen) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_bind: corrupted message\n"); + goto out; + } + bind_args.addr = (const struct sockaddr *)bufs[1]; + + if ((bind_args.s = rec_fd(privsep_sock[0])) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_bind: rec_fd failed\n"); + goto out; + } + + port = extract_port(bind_args.addr); + if (port != PORT_ISAKMP && port != PORT_ISAKMP_NATT && + port != lcconf->port_isakmp && + port != lcconf->port_isakmp_natt) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_bind: " + "unauthorized port (%d)\n", + port); + close(bind_args.s); + goto out; + } + + err = bind(bind_args.s, bind_args.addr, + bind_args.addrlen); + + if (err) + reply->hdr.ac_errno = errno; + + close(bind_args.s); + break; + } + + case PRIVSEP_SETSOCKOPTS: { + struct sockopt_args sockopt_args; + int err; + + /* Make sure the string is NULL terminated */ + if (safety_check(combuf, 0) != 0) + break; + + if (combuf->bufs.buflen[0] != + sizeof(struct sockopt_args)) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_setsockopt: " + "corrupted message\n"); + goto out; + } + memcpy(&sockopt_args, bufs[0], + sizeof(struct sockopt_args)); + + if (combuf->bufs.buflen[1] != sockopt_args.optlen) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_setsockopt: corrupted message\n"); + goto out; + } + sockopt_args.optval = bufs[1]; + + if (sockopt_args.optname != + (sockopt_args.level == + IPPROTO_IP ? IP_IPSEC_POLICY : + IPV6_IPSEC_POLICY)) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_setsockopt: " + "unauthorized option (%d)\n", + sockopt_args.optname); + goto out; + } + + if ((sockopt_args.s = rec_fd(privsep_sock[0])) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_setsockopt: rec_fd failed\n"); + goto out; + } + + err = setsockopt(sockopt_args.s, + sockopt_args.level, + sockopt_args.optname, + sockopt_args.optval, + sockopt_args.optlen); + if (err) + reply->hdr.ac_errno = errno; + + close(sockopt_args.s); + break; + } + +#ifdef ENABLE_HYBRID + case PRIVSEP_ACCOUNTING_SYSTEM: { + int pool_size; + int port; + int inout; + struct sockaddr *raddr; + + if (safety_check(combuf, 0) != 0) + break; + if (safety_check(combuf, 1) != 0) + break; + if (safety_check(combuf, 2) != 0) + break; + if (safety_check(combuf, 3) != 0) + break; + + memcpy(&port, bufs[0], sizeof(port)); + raddr = (struct sockaddr *)bufs[1]; + + bufs[2][combuf->bufs.buflen[2] - 1] = '\0'; + memcpy(&inout, bufs[3], sizeof(port)); + + if (port_check(port) != 0) + break; + + plog(LLV_DEBUG, LOCATION, NULL, + "accounting_system(%d, %s, %s)\n", + port, saddr2str(raddr), bufs[2]); + + errno = 0; + if (isakmp_cfg_accounting_system(port, + raddr, bufs[2], inout) != 0) { + if (errno == 0) + reply->hdr.ac_errno = EINVAL; + else + reply->hdr.ac_errno = errno; + } + break; + } + case PRIVSEP_XAUTH_LOGIN_SYSTEM: { + if (safety_check(combuf, 0) != 0) + break; + bufs[0][combuf->bufs.buflen[0] - 1] = '\0'; + + if (safety_check(combuf, 1) != 0) + break; + bufs[1][combuf->bufs.buflen[1] - 1] = '\0'; + + plog(LLV_DEBUG, LOCATION, NULL, + "xauth_login_system(\"%s\", )\n", + bufs[0]); + + errno = 0; + if (xauth_login_system(bufs[0], bufs[1]) != 0) { + if (errno == 0) + reply->hdr.ac_errno = EINVAL; + else + reply->hdr.ac_errno = errno; + } + break; + } +#ifdef HAVE_LIBPAM + case PRIVSEP_ACCOUNTING_PAM: { + int port; + int inout; + int pool_size; + + if (safety_check(combuf, 0) != 0) + break; + if (safety_check(combuf, 1) != 0) + break; + if (safety_check(combuf, 2) != 0) + break; + + memcpy(&port, bufs[0], sizeof(port)); + memcpy(&inout, bufs[1], sizeof(inout)); + memcpy(&pool_size, bufs[2], sizeof(pool_size)); + + if (pool_size != isakmp_cfg_config.pool_size) + if (isakmp_cfg_resize_pool(pool_size) != 0) + break; + + if (port_check(port) != 0) + break; + + plog(LLV_DEBUG, LOCATION, NULL, + "isakmp_cfg_accounting_pam(%d, %d)\n", + port, inout); + + errno = 0; + if (isakmp_cfg_accounting_pam(port, inout) != 0) { + if (errno == 0) + reply->hdr.ac_errno = EINVAL; + else + reply->hdr.ac_errno = errno; + } + break; + } + + case PRIVSEP_XAUTH_LOGIN_PAM: { + int port; + int pool_size; + struct sockaddr *raddr; + + if (safety_check(combuf, 0) != 0) + break; + if (safety_check(combuf, 1) != 0) + break; + if (safety_check(combuf, 2) != 0) + break; + if (safety_check(combuf, 3) != 0) + break; + if (safety_check(combuf, 4) != 0) + break; + + memcpy(&port, bufs[0], sizeof(port)); + memcpy(&pool_size, bufs[1], sizeof(pool_size)); + raddr = (struct sockaddr *)bufs[2]; + + bufs[3][combuf->bufs.buflen[3] - 1] = '\0'; + bufs[4][combuf->bufs.buflen[4] - 1] = '\0'; + + if (pool_size != isakmp_cfg_config.pool_size) + if (isakmp_cfg_resize_pool(pool_size) != 0) + break; + + if (port_check(port) != 0) + break; + + plog(LLV_DEBUG, LOCATION, NULL, + "xauth_login_pam(%d, %s, \"%s\", )\n", + port, saddr2str(raddr), bufs[3]); + + errno = 0; + if (xauth_login_pam(port, + raddr, bufs[3], bufs[4]) != 0) { + if (errno == 0) + reply->hdr.ac_errno = EINVAL; + else + reply->hdr.ac_errno = errno; + } + break; + } + + case PRIVSEP_CLEANUP_PAM: { + int port; + int pool_size; + + if (safety_check(combuf, 0) != 0) + break; + if (safety_check(combuf, 1) != 0) + break; + + memcpy(&port, bufs[0], sizeof(port)); + memcpy(&pool_size, bufs[1], sizeof(pool_size)); + + if (pool_size != isakmp_cfg_config.pool_size) + if (isakmp_cfg_resize_pool(pool_size) != 0) + break; + + if (port_check(port) != 0) + break; + + plog(LLV_DEBUG, LOCATION, NULL, + "cleanup_pam(%d)\n", port); + + cleanup_pam(port); + reply->hdr.ac_errno = 0; + + break; + } +#endif /* HAVE_LIBPAM */ +#endif /* ENABLE_HYBRID */ + + default: + plog(LLV_ERROR, LOCATION, NULL, + "unexpected privsep command %d\n", + combuf->hdr.ac_cmd); + goto out; + break; + } + + /* This frees reply */ + if (privsep_send(privsep_sock[0], + reply, reply->hdr.ac_len) != 0) { + racoon_free(reply); + goto out; + } + + racoon_free(combuf); + } + +out: + plog(LLV_INFO, LOCATION, NULL, + "racoon privileged process %d terminated\n", getpid()); + _exit(0); +} + + +vchar_t * +privsep_eay_get_pkcs1privkey(path) + char *path; +{ + vchar_t *privkey; + struct privsep_com_msg *msg; + size_t len; + + if (geteuid() == 0) + return eay_get_pkcs1privkey(path); + + len = sizeof(*msg) + strlen(path) + 1; + if ((msg = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return NULL; + } + bzero(msg, len); + msg->hdr.ac_cmd = PRIVSEP_EAY_GET_PKCS1PRIVKEY; + msg->hdr.ac_len = len; + msg->bufs.buflen[0] = len - sizeof(*msg); + memcpy(msg + 1, path, msg->bufs.buflen[0]); + + if (privsep_send(privsep_sock[1], msg, len) != 0) + return NULL; + + if (privsep_recv(privsep_sock[1], &msg, &len) != 0) + return NULL; + + if (msg->hdr.ac_errno != 0) { + errno = msg->hdr.ac_errno; + goto out; + } + + if ((privkey = vmalloc(len - sizeof(*msg))) == NULL) + goto out; + + memcpy(privkey->v, msg + 1, privkey->l); + racoon_free(msg); + return privkey; + +out: + racoon_free(msg); + return NULL; +} + +int +privsep_script_exec(script, name, envp) + char *script; + int name; + char *const envp[]; +{ + int count = 0; + char *const *c; + char *data; + size_t len; + struct privsep_com_msg *msg; + + if (geteuid() == 0) + return script_exec(script, name, envp); + + if ((msg = racoon_malloc(sizeof(*msg))) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return -1; + } + + bzero(msg, sizeof(*msg)); + msg->hdr.ac_cmd = PRIVSEP_SCRIPT_EXEC; + msg->hdr.ac_len = sizeof(*msg); + + /* + * We send: + * script, name, envp[0], ... envp[N], void + */ + + /* + * Safety check on the counts: PRIVSEP_NBUF_MAX max + */ + count = 0; + count++; /* script */ + count++; /* name */ + for (c = envp; *c; c++) /* envp */ + count++; + count++; /* void */ + + if (count > PRIVSEP_NBUF_MAX) { + plog(LLV_ERROR, LOCATION, NULL, "Unexpected error: " + "privsep_script_exec count > PRIVSEP_NBUF_MAX\n"); + racoon_free(msg); + return -1; + } + + + /* + * Compute the length + */ + count = 0; + msg->bufs.buflen[count] = strlen(script) + 1; /* script */ + msg->hdr.ac_len += msg->bufs.buflen[count++]; + + msg->bufs.buflen[count] = sizeof(name); /* name */ + msg->hdr.ac_len += msg->bufs.buflen[count++]; + + for (c = envp; *c; c++) { /* envp */ + msg->bufs.buflen[count] = strlen(*c) + 1; + msg->hdr.ac_len += msg->bufs.buflen[count++]; + } + + msg->bufs.buflen[count] = 0; /* void */ + msg->hdr.ac_len += msg->bufs.buflen[count++]; + + if ((msg = racoon_realloc(msg, msg->hdr.ac_len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return -1; + } + + /* + * Now copy the data + */ + data = (char *)(msg + 1); + count = 0; + + memcpy(data, (char *)script, msg->bufs.buflen[count]); /* script */ + data += msg->bufs.buflen[count++]; + + memcpy(data, (char *)&name, msg->bufs.buflen[count]); /* name */ + data += msg->bufs.buflen[count++]; + + for (c = envp; *c; c++) { /* envp */ + memcpy(data, *c, msg->bufs.buflen[count]); + data += msg->bufs.buflen[count++]; + } + + count++; /* void */ + + /* + * And send it! + */ + if (privsep_send(privsep_sock[1], msg, msg->hdr.ac_len) != 0) + return -1; + + if (privsep_recv(privsep_sock[1], &msg, &len) != 0) + return -1; + + if (msg->hdr.ac_errno != 0) { + errno = msg->hdr.ac_errno; + racoon_free(msg); + return -1; + } + + racoon_free(msg); + return 0; +} + +vchar_t * +privsep_getpsk(str, keylen) + const char *str; + int keylen; +{ + vchar_t *psk; + struct privsep_com_msg *msg; + size_t len; + int *keylenp; + char *data; + + if (geteuid() == 0) + return getpsk(str, keylen); + + len = sizeof(*msg) + strlen(str) + 1 + sizeof(keylen); + if ((msg = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return NULL; + } + bzero(msg, len); + msg->hdr.ac_cmd = PRIVSEP_GETPSK; + msg->hdr.ac_len = len; + + data = (char *)(msg + 1); + msg->bufs.buflen[0] = strlen(str) + 1; + memcpy(data, str, msg->bufs.buflen[0]); + + data += msg->bufs.buflen[0]; + msg->bufs.buflen[1] = sizeof(keylen); + memcpy(data, &keylen, sizeof(keylen)); + + if (privsep_send(privsep_sock[1], msg, len) != 0) + return NULL; + + if (privsep_recv(privsep_sock[1], &msg, &len) != 0) + return NULL; + + if (msg->hdr.ac_errno != 0) { + errno = msg->hdr.ac_errno; + goto out; + } + + if ((psk = vmalloc(len - sizeof(*msg))) == NULL) + goto out; + + memcpy(psk->v, msg + 1, psk->l); + racoon_free(msg); + return psk; + +out: + racoon_free(msg); + return NULL; +} + +/* + * Create a privileged socket. On BSD systems a socket obtains special + * capabilities if it is created by root; setsockopt(IP_IPSEC_POLICY) will + * succeed but will be ineffective if performed on an unprivileged socket. + */ +int +privsep_socket(domain, type, protocol) + int domain; + int type; + int protocol; +{ + struct privsep_com_msg *msg; + size_t len; + char *data; + struct socket_args socket_args; + int s, saved_errno = 0; + + if (geteuid() == 0) + return socket(domain, type, protocol); + + len = sizeof(*msg) + sizeof(socket_args); + + if ((msg = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return -1; + } + bzero(msg, len); + msg->hdr.ac_cmd = PRIVSEP_SOCKET; + msg->hdr.ac_len = len; + + socket_args.domain = domain; + socket_args.type = type; + socket_args.protocol = protocol; + + data = (char *)(msg + 1); + msg->bufs.buflen[0] = sizeof(socket_args); + memcpy(data, &socket_args, msg->bufs.buflen[0]); + + /* frees msg */ + if (privsep_send(privsep_sock[1], msg, len) != 0) + goto out; + + /* Get the privileged socket descriptor from the privileged process. */ + if ((s = rec_fd(privsep_sock[1])) == -1) + return -1; + + if (privsep_recv(privsep_sock[1], &msg, &len) != 0) + goto out; + + if (msg->hdr.ac_errno != 0) { + errno = msg->hdr.ac_errno; + goto out; + } + + racoon_free(msg); + return s; + +out: + racoon_free(msg); + return -1; +} + +/* + * Bind() a socket to a port. This works just like regular bind(), except that + * if you want to bind to the designated isakmp ports and you don't have the + * privilege to do so, it will ask a privileged process to do it. + */ +int +privsep_bind(s, addr, addrlen) + int s; + const struct sockaddr *addr; + socklen_t addrlen; +{ + struct privsep_com_msg *msg; + size_t len; + char *data; + struct bind_args bind_args; + int err, saved_errno = 0; + + err = bind(s, addr, addrlen); + if ((err == 0) || (saved_errno = errno) != EACCES || geteuid() == 0) { + if (saved_errno) + plog(LLV_ERROR, LOCATION, NULL, + "privsep_bind (%s) = %d\n", strerror(saved_errno), err); + errno = saved_errno; + return err; + } + + len = sizeof(*msg) + sizeof(bind_args) + addrlen; + + if ((msg = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return -1; + } + bzero(msg, len); + msg->hdr.ac_cmd = PRIVSEP_BIND; + msg->hdr.ac_len = len; + + bind_args.s = -1; + bind_args.addr = NULL; + bind_args.addrlen = addrlen; + + data = (char *)(msg + 1); + msg->bufs.buflen[0] = sizeof(bind_args); + memcpy(data, &bind_args, msg->bufs.buflen[0]); + + data += msg->bufs.buflen[0]; + msg->bufs.buflen[1] = addrlen; + memcpy(data, addr, addrlen); + + /* frees msg */ + if (privsep_send(privsep_sock[1], msg, len) != 0) + goto out; + + /* Send the socket descriptor to the privileged process. */ + if (send_fd(privsep_sock[1], s) < 0) + return -1; + + if (privsep_recv(privsep_sock[1], &msg, &len) != 0) + goto out; + + if (msg->hdr.ac_errno != 0) { + errno = msg->hdr.ac_errno; + goto out; + } + + racoon_free(msg); + return 0; + +out: + racoon_free(msg); + return -1; +} + +/* + * Set socket options. This works just like regular setsockopt(), except that + * if you want to change IP_IPSEC_POLICY or IPV6_IPSEC_POLICY and you don't + * have the privilege to do so, it will ask a privileged process to do it. + */ +int +privsep_setsockopt(s, level, optname, optval, optlen) + int s; + int level; + int optname; + const void *optval; + socklen_t optlen; +{ + struct privsep_com_msg *msg; + size_t len; + char *data; + struct sockopt_args sockopt_args; + int err, saved_errno = 0; + + if ((err = setsockopt(s, level, optname, optval, optlen) == 0) || + (saved_errno = errno) != EACCES || + geteuid() == 0) { + if (saved_errno) + plog(LLV_ERROR, LOCATION, NULL, + "privsep_setsockopt (%s)\n", + strerror(saved_errno)); + + errno = saved_errno; + return err; + } + + len = sizeof(*msg) + sizeof(sockopt_args) + optlen; + + if ((msg = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return -1; + } + bzero(msg, len); + msg->hdr.ac_cmd = PRIVSEP_SETSOCKOPTS; + msg->hdr.ac_len = len; + + sockopt_args.s = -1; + sockopt_args.level = level; + sockopt_args.optname = optname; + sockopt_args.optval = NULL; + sockopt_args.optlen = optlen; + + data = (char *)(msg + 1); + msg->bufs.buflen[0] = sizeof(sockopt_args); + memcpy(data, &sockopt_args, msg->bufs.buflen[0]); + + data += msg->bufs.buflen[0]; + msg->bufs.buflen[1] = optlen; + memcpy(data, optval, optlen); + + /* frees msg */ + if (privsep_send(privsep_sock[1], msg, len) != 0) + goto out; + + if (send_fd(privsep_sock[1], s) < 0) + return -1; + + if (privsep_recv(privsep_sock[1], &msg, &len) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_recv failed\n"); + goto out; + } + + if (msg->hdr.ac_errno != 0) { + errno = msg->hdr.ac_errno; + goto out; + } + + racoon_free(msg); + return 0; + +out: + racoon_free(msg); + return -1; +} + +#ifdef ENABLE_HYBRID +int +privsep_xauth_login_system(usr, pwd) + char *usr; + char *pwd; +{ + struct privsep_com_msg *msg; + size_t len; + char *data; + + if (geteuid() == 0) + return xauth_login_system(usr, pwd); + + len = sizeof(*msg) + strlen(usr) + 1 + strlen(pwd) + 1; + if ((msg = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return -1; + } + bzero(msg, len); + msg->hdr.ac_cmd = PRIVSEP_XAUTH_LOGIN_SYSTEM; + msg->hdr.ac_len = len; + + data = (char *)(msg + 1); + msg->bufs.buflen[0] = strlen(usr) + 1; + memcpy(data, usr, msg->bufs.buflen[0]); + data += msg->bufs.buflen[0]; + + msg->bufs.buflen[1] = strlen(pwd) + 1; + memcpy(data, pwd, msg->bufs.buflen[1]); + + /* frees msg */ + if (privsep_send(privsep_sock[1], msg, len) != 0) + return -1; + + if (privsep_recv(privsep_sock[1], &msg, &len) != 0) + return -1; + + if (msg->hdr.ac_errno != 0) { + racoon_free(msg); + return -1; + } + + racoon_free(msg); + return 0; +} + +int +privsep_accounting_system(port, raddr, usr, inout) + int port; + struct sockaddr *raddr; + char *usr; + int inout; +{ + struct privsep_com_msg *msg; + size_t len; + char *data; + int result; + + if (geteuid() == 0) + return isakmp_cfg_accounting_system(port, raddr, + usr, inout); + + len = sizeof(*msg) + + sizeof(port) + + sysdep_sa_len(raddr) + + strlen(usr) + 1 + + sizeof(inout); + + if ((msg = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return -1; + } + bzero(msg, len); + msg->hdr.ac_cmd = PRIVSEP_ACCOUNTING_SYSTEM; + msg->hdr.ac_len = len; + msg->bufs.buflen[0] = sizeof(port); + msg->bufs.buflen[1] = sysdep_sa_len(raddr); + msg->bufs.buflen[2] = strlen(usr) + 1; + msg->bufs.buflen[3] = sizeof(inout); + + data = (char *)(msg + 1); + memcpy(data, &port, msg->bufs.buflen[0]); + + data += msg->bufs.buflen[0]; + memcpy(data, raddr, msg->bufs.buflen[1]); + + data += msg->bufs.buflen[1]; + memcpy(data, usr, msg->bufs.buflen[2]); + + data += msg->bufs.buflen[2]; + memcpy(data, &inout, msg->bufs.buflen[3]); + + /* frees msg */ + if (privsep_send(privsep_sock[1], msg, len) != 0) + return -1; + + if (privsep_recv(privsep_sock[1], &msg, &len) != 0) + return -1; + + if (msg->hdr.ac_errno != 0) { + errno = msg->hdr.ac_errno; + goto out; + } + + racoon_free(msg); + return 0; + +out: + racoon_free(msg); + return -1; +} + +static int +port_check(port) + int port; +{ + if ((port < 0) || (port >= isakmp_cfg_config.pool_size)) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep: port %d outside of allowed range [0,%zu]\n", + port, isakmp_cfg_config.pool_size - 1); + return -1; + } + + return 0; +} +#endif + +static int +safety_check(msg, index) + struct privsep_com_msg *msg; + int index; +{ + if (index >= PRIVSEP_NBUF_MAX) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep: Corrupted message, too many buffers\n"); + return -1; + } + + if (msg->bufs.buflen[index] == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep: Corrupted message, unexpected void buffer\n"); + return -1; + } + + return 0; +} + +/* + * Filter unsafe environment variables + */ +static int +unsafe_env(envp) + char *const *envp; +{ + char *const *e; + char *const *be; + char *const bad_env[] = { "PATH=", "LD_LIBRARY_PATH=", "IFS=", NULL }; + + for (e = envp; *e; e++) { + for (be = bad_env; *be; be++) { + if (strncmp(*e, *be, strlen(*be)) == 0) { + goto found; + } + } + } + + return 0; +found: + plog(LLV_ERROR, LOCATION, NULL, + "privsep_script_exec: unsafe environment variable\n"); + return -1; +} + +/* + * Check path safety + */ +static int +unsafe_path(script, pathtype) + char *script; + int pathtype; +{ + char *path; + char rpath[MAXPATHLEN + 1]; + size_t len; + + if (script == NULL) + return -1; + + path = lcconf->pathinfo[pathtype]; + + /* No path was given for scripts: skip the check */ + if (path == NULL) + return 0; + + if (realpath(script, rpath) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "script path \"%s\" is invalid\n", script); + return -1; + } + + len = strlen(path); + if (strncmp(path, rpath, len) != 0) + return -1; + + return 0; +} + +static int +unknown_name(name) + int name; +{ + if ((name < 0) || (name > SCRIPT_MAX)) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_script_exec: unsafe name index\n"); + return -1; + } + + return 0; +} + +/* Receive a file descriptor through the argument socket */ +static int +rec_fd(s) + int s; +{ + struct msghdr msg; + struct cmsghdr *cmsg; + int *fdptr; + int fd; + char cmsbuf[1024]; + struct iovec iov; + char iobuf[1]; + + iov.iov_base = iobuf; + iov.iov_len = 1; + + if (sizeof(cmsbuf) < CMSG_SPACE(sizeof(fd))) { + plog(LLV_ERROR, LOCATION, NULL, + "send_fd: buffer size too small\n"); + return -1; + } + bzero(&msg, sizeof(msg)); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsbuf; + msg.msg_controllen = CMSG_SPACE(sizeof(fd)); + + if (recvmsg(s, &msg, MSG_WAITALL) == -1) + return -1; + + cmsg = CMSG_FIRSTHDR(&msg); + fdptr = (int *) CMSG_DATA(cmsg); + return fdptr[0]; +} + +/* Send the file descriptor fd through the argument socket s */ +static int +send_fd(s, fd) + int s; + int fd; +{ + struct msghdr msg; + struct cmsghdr *cmsg; + char cmsbuf[1024]; + struct iovec iov; + int *fdptr; + + iov.iov_base = " "; + iov.iov_len = 1; + + if (sizeof(cmsbuf) < CMSG_SPACE(sizeof(fd))) { + plog(LLV_ERROR, LOCATION, NULL, + "send_fd: buffer size too small\n"); + return -1; + } + bzero(&msg, sizeof(msg)); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsbuf; + msg.msg_controllen = CMSG_SPACE(sizeof(fd)); + msg.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); + fdptr = (int *)CMSG_DATA(cmsg); + fdptr[0] = fd; + msg.msg_controllen = cmsg->cmsg_len; + + if (sendmsg(s, &msg, 0) == -1) + return -1; + + return 0; +} + +#ifdef HAVE_LIBPAM +int +privsep_accounting_pam(port, inout) + int port; + int inout; +{ + struct privsep_com_msg *msg; + size_t len; + int *port_data; + int *inout_data; + int *pool_size_data; + int result; + + if (geteuid() == 0) + return isakmp_cfg_accounting_pam(port, inout); + + len = sizeof(*msg) + + sizeof(port) + + sizeof(inout) + + sizeof(isakmp_cfg_config.pool_size); + + if ((msg = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return -1; + } + bzero(msg, len); + msg->hdr.ac_cmd = PRIVSEP_ACCOUNTING_PAM; + msg->hdr.ac_len = len; + msg->bufs.buflen[0] = sizeof(port); + msg->bufs.buflen[1] = sizeof(inout); + msg->bufs.buflen[2] = sizeof(isakmp_cfg_config.pool_size); + + port_data = (int *)(msg + 1); + inout_data = (int *)(port_data + 1); + pool_size_data = (int *)(inout_data + 1); + + *port_data = port; + *inout_data = inout; + *pool_size_data = isakmp_cfg_config.pool_size; + + /* frees msg */ + if (privsep_send(privsep_sock[1], msg, len) != 0) + return -1; + + if (privsep_recv(privsep_sock[1], &msg, &len) != 0) + return -1; + + if (msg->hdr.ac_errno != 0) { + errno = msg->hdr.ac_errno; + goto out; + } + + racoon_free(msg); + return 0; + +out: + racoon_free(msg); + return -1; +} + +int +privsep_xauth_login_pam(port, raddr, usr, pwd) + int port; + struct sockaddr *raddr; + char *usr; + char *pwd; +{ + struct privsep_com_msg *msg; + size_t len; + char *data; + int result; + + if (geteuid() == 0) + return xauth_login_pam(port, raddr, usr, pwd); + + len = sizeof(*msg) + + sizeof(port) + + sizeof(isakmp_cfg_config.pool_size) + + sysdep_sa_len(raddr) + + strlen(usr) + 1 + + strlen(pwd) + 1; + + if ((msg = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return -1; + } + bzero(msg, len); + msg->hdr.ac_cmd = PRIVSEP_XAUTH_LOGIN_PAM; + msg->hdr.ac_len = len; + msg->bufs.buflen[0] = sizeof(port); + msg->bufs.buflen[1] = sizeof(isakmp_cfg_config.pool_size); + msg->bufs.buflen[2] = sysdep_sa_len(raddr); + msg->bufs.buflen[3] = strlen(usr) + 1; + msg->bufs.buflen[4] = strlen(pwd) + 1; + + data = (char *)(msg + 1); + memcpy(data, &port, msg->bufs.buflen[0]); + + data += msg->bufs.buflen[0]; + memcpy(data, &isakmp_cfg_config.pool_size, msg->bufs.buflen[1]); + + data += msg->bufs.buflen[1]; + memcpy(data, raddr, msg->bufs.buflen[2]); + + data += msg->bufs.buflen[2]; + memcpy(data, usr, msg->bufs.buflen[3]); + + data += msg->bufs.buflen[3]; + memcpy(data, pwd, msg->bufs.buflen[4]); + + /* frees msg */ + if (privsep_send(privsep_sock[1], msg, len) != 0) + return -1; + + if (privsep_recv(privsep_sock[1], &msg, &len) != 0) + return -1; + + if (msg->hdr.ac_errno != 0) { + errno = msg->hdr.ac_errno; + goto out; + } + + racoon_free(msg); + return 0; + +out: + racoon_free(msg); + return -1; +} + +void +privsep_cleanup_pam(port) + int port; +{ + struct privsep_com_msg *msg; + size_t len; + char *data; + int result; + + if (geteuid() == 0) + return cleanup_pam(port); + + len = sizeof(*msg) + + sizeof(port) + + sizeof(isakmp_cfg_config.pool_size); + + if ((msg = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return; + } + bzero(msg, len); + msg->hdr.ac_cmd = PRIVSEP_CLEANUP_PAM; + msg->hdr.ac_len = len; + msg->bufs.buflen[0] = sizeof(port); + msg->bufs.buflen[1] = sizeof(isakmp_cfg_config.pool_size); + + data = (char *)(msg + 1); + memcpy(data, &port, msg->bufs.buflen[0]); + + data += msg->bufs.buflen[0]; + memcpy(data, &isakmp_cfg_config.pool_size, msg->bufs.buflen[1]); + + /* frees msg */ + if (privsep_send(privsep_sock[1], msg, len) != 0) + return; + + if (privsep_recv(privsep_sock[1], &msg, &len) != 0) + return; + + if (msg->hdr.ac_errno != 0) + errno = msg->hdr.ac_errno; + + racoon_free(msg); + return; +} +#endif diff --git a/ipsec-tools/src/racoon/privsep.h b/ipsec-tools/src/racoon/privsep.h new file mode 100644 index 00000000..732743cf --- /dev/null +++ b/ipsec-tools/src/racoon/privsep.h @@ -0,0 +1,76 @@ +/* $NetBSD: privsep.h,v 1.6 2008/12/08 06:00:54 tteras Exp $ */ + +/* Id: privsep.h,v 1.5 2005/06/07 12:22:11 fredsen Exp */ + +/* + * Copyright (C) 2004 Emmanuel Dreyfus + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _PRIVSEP_H +#define _PRIVSEP_H + +#define PRIVSEP_EAY_GET_PKCS1PRIVKEY 0x0801 /* admin_com_bufs follows */ +#define PRIVSEP_SCRIPT_EXEC 0x0803 /* admin_com_bufs follows */ +#define PRIVSEP_GETPSK 0x0804 /* admin_com_bufs follows */ +#define PRIVSEP_XAUTH_LOGIN_SYSTEM 0x0805 /* admin_com_bufs follows */ +#define PRIVSEP_ACCOUNTING_PAM 0x0806 /* admin_com_bufs follows */ +#define PRIVSEP_XAUTH_LOGIN_PAM 0x0807 /* admin_com_bufs follows */ +#define PRIVSEP_CLEANUP_PAM 0x0808 /* admin_com_bufs follows */ +#define PRIVSEP_ACCOUNTING_SYSTEM 0x0809 /* admin_com_bufs follows */ +#define PRIVSEP_SETSOCKOPTS 0x080A /* admin_com_bufs follows */ +#define PRIVSEP_BIND 0x080B /* admin_com_bufs follows */ +#define PRIVSEP_SOCKET 0x080C /* admin_com_bufs follows */ + +#define PRIVSEP_NBUF_MAX 24 +#define PRIVSEP_BUFLEN_MAX 4096 +struct admin_com_bufs { + size_t buflen[PRIVSEP_NBUF_MAX]; + /* Followed by the buffers */ +}; + +struct privsep_com_msg { + struct admin_com hdr; + struct admin_com_bufs bufs; +}; + +int privsep_init __P((void)); + +vchar_t *privsep_eay_get_pkcs1privkey __P((char *)); +int privsep_script_exec __P((char *, int, char * const *)); +int privsep_setsockopt __P((int, int, int, const void *, socklen_t)); +int privsep_socket __P((int, int, int)); +int privsep_bind __P((int, const struct sockaddr *, socklen_t)); +vchar_t *privsep_getpsk __P((const char *, const int)); +int privsep_xauth_login_system __P((char *, char *)); +#ifdef HAVE_LIBPAM +int privsep_accounting_pam __P((int, int)); +int privsep_xauth_login_pam __P((int, struct sockaddr *, char *, char *)); +void privsep_cleanup_pam __P((int)); +#endif +int privsep_accounting_system __P((int, struct sockaddr *, char *, int)); +#endif /* _PRIVSEP_H */ diff --git a/ipsec-tools/src/racoon/proposal.c b/ipsec-tools/src/racoon/proposal.c new file mode 100644 index 00000000..33dd3114 --- /dev/null +++ b/ipsec-tools/src/racoon/proposal.c @@ -0,0 +1,1290 @@ +/* $NetBSD: proposal.c,v 1.17 2008/09/19 11:14:49 tteras Exp $ */ + +/* $Id: proposal.c,v 1.17 2008/09/19 11:14:49 tteras Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "debug.h" + +#include "policy.h" +#include "pfkey.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "ipsec_doi.h" +#include "algorithm.h" +#include "proposal.h" +#include "sainfo.h" +#include "localconf.h" +#include "remoteconf.h" +#include "oakley.h" +#include "handler.h" +#include "strnames.h" +#include "gcmalloc.h" +#ifdef ENABLE_NATT +#include "nattraversal.h" +#endif + +static uint g_nextreqid = 1; + +/* %%% + * modules for ipsec sa spec + */ +struct saprop * +newsaprop() +{ + struct saprop *new; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) + return NULL; + + return new; +} + +struct saproto * +newsaproto() +{ + struct saproto *new; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) + return NULL; + + return new; +} + +/* set saprop to last part of the prop tree */ +void +inssaprop(head, new) + struct saprop **head; + struct saprop *new; +{ + struct saprop *p; + + if (*head == NULL) { + *head = new; + return; + } + + for (p = *head; p->next; p = p->next) + ; + p->next = new; + + return; +} + +/* set saproto to the end of the proto tree in saprop */ +void +inssaproto(pp, new) + struct saprop *pp; + struct saproto *new; +{ + struct saproto *p; + + for (p = pp->head; p && p->next; p = p->next) + ; + if (p == NULL) + pp->head = new; + else + p->next = new; + + return; +} + +/* set saproto to the top of the proto tree in saprop */ +void +inssaprotorev(pp, new) + struct saprop *pp; + struct saproto *new; +{ + new->next = pp->head; + pp->head = new; + + return; +} + +struct satrns * +newsatrns() +{ + struct satrns *new; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) + return NULL; + + return new; +} + +/* set saproto to last part of the proto tree in saprop */ +void +inssatrns(pr, new) + struct saproto *pr; + struct satrns *new; +{ + struct satrns *tr; + + for (tr = pr->head; tr && tr->next; tr = tr->next) + ; + if (tr == NULL) + pr->head = new; + else + tr->next = new; + + return; +} + +/* + * take a single match between saprop. allocate a new proposal and return it + * for future use (like picking single proposal from a bundle). + * pp1: peer's proposal. + * pp2: my proposal. + * NOTE: In the case of initiator, must be ensured that there is no + * modification of the proposal by calling cmp_aproppair_i() before + * this function. + * XXX cannot understand the comment! + */ +struct saprop * +cmpsaprop_alloc(ph1, pp1, pp2, side) + struct ph1handle *ph1; + const struct saprop *pp1, *pp2; + int side; +{ + struct saprop *newpp = NULL; + struct saproto *pr1, *pr2, *newpr = NULL; + struct satrns *tr1, *tr2, *newtr; + const int ordermatters = 0; + int npr1, npr2; + int spisizematch; + + newpp = newsaprop(); + if (newpp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate saprop.\n"); + return NULL; + } + newpp->prop_no = pp1->prop_no; + + /* see proposal.h about lifetime/key length and PFS selection. */ + + /* check time/bytes lifetime and PFS */ + switch (ph1->rmconf->pcheck_level) { + case PROP_CHECK_OBEY: + newpp->lifetime = pp1->lifetime; + newpp->lifebyte = pp1->lifebyte; + newpp->pfs_group = pp1->pfs_group; + break; + + case PROP_CHECK_STRICT: + if (pp1->lifetime > pp2->lifetime) { + plog(LLV_ERROR, LOCATION, NULL, + "long lifetime proposed: " + "my:%d peer:%d\n", + (int)pp2->lifetime, (int)pp1->lifetime); + goto err; + } + if (pp1->lifebyte > pp2->lifebyte) { + plog(LLV_ERROR, LOCATION, NULL, + "long lifebyte proposed: " + "my:%d peer:%d\n", + pp2->lifebyte, pp1->lifebyte); + goto err; + } + newpp->lifetime = pp1->lifetime; + newpp->lifebyte = pp1->lifebyte; + + prop_pfs_check: + if (pp2->pfs_group != 0 && pp1->pfs_group != pp2->pfs_group) { + plog(LLV_ERROR, LOCATION, NULL, + "pfs group mismatched: " + "my:%d peer:%d\n", + pp2->pfs_group, pp1->pfs_group); + goto err; + } + newpp->pfs_group = pp1->pfs_group; + break; + + case PROP_CHECK_CLAIM: + /* lifetime */ + if (pp1->lifetime <= pp2->lifetime) { + newpp->lifetime = pp1->lifetime; + } else { + newpp->lifetime = pp2->lifetime; + newpp->claim |= IPSECDOI_ATTR_SA_LD_TYPE_SEC; + plog(LLV_NOTIFY, LOCATION, NULL, + "use own lifetime: " + "my:%d peer:%d\n", + (int)pp2->lifetime, (int)pp1->lifetime); + } + + /* lifebyte */ + if (pp1->lifebyte > pp2->lifebyte) { + newpp->lifebyte = pp2->lifebyte; + newpp->claim |= IPSECDOI_ATTR_SA_LD_TYPE_SEC; + plog(LLV_NOTIFY, LOCATION, NULL, + "use own lifebyte: " + "my:%d peer:%d\n", + pp2->lifebyte, pp1->lifebyte); + } + newpp->lifebyte = pp1->lifebyte; + + goto prop_pfs_check; + break; + + case PROP_CHECK_EXACT: + if (pp1->lifetime != pp2->lifetime) { + plog(LLV_ERROR, LOCATION, NULL, + "lifetime mismatched: " + "my:%d peer:%d\n", + (int)pp2->lifetime, (int)pp1->lifetime); + goto err; + } + + if (pp1->lifebyte != pp2->lifebyte) { + plog(LLV_ERROR, LOCATION, NULL, + "lifebyte mismatched: " + "my:%d peer:%d\n", + pp2->lifebyte, pp1->lifebyte); + goto err; + } + if (pp1->pfs_group != pp2->pfs_group) { + plog(LLV_ERROR, LOCATION, NULL, + "pfs group mismatched: " + "my:%d peer:%d\n", + pp2->pfs_group, pp1->pfs_group); + goto err; + } + newpp->lifetime = pp1->lifetime; + newpp->lifebyte = pp1->lifebyte; + newpp->pfs_group = pp1->pfs_group; + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid pcheck_level why?.\n"); + goto err; + } + +#ifdef HAVE_SECCTX + /* check the security_context properties. + * It is possible for one side to have a security context + * and the other side doesn't. If so, this is an error. + */ + + if (*pp1->sctx.ctx_str && !(*pp2->sctx.ctx_str)) { + plog(LLV_ERROR, LOCATION, NULL, + "My proposal missing security context\n"); + goto err; + } + if (!(*pp1->sctx.ctx_str) && *pp2->sctx.ctx_str) { + plog(LLV_ERROR, LOCATION, NULL, + "Peer is missing security context\n"); + goto err; + } + + if (*pp1->sctx.ctx_str && *pp2->sctx.ctx_str) { + if (pp1->sctx.ctx_doi == pp2->sctx.ctx_doi) + newpp->sctx.ctx_doi = pp1->sctx.ctx_doi; + else { + plog(LLV_ERROR, LOCATION, NULL, + "sec doi mismatched: my:%d peer:%d\n", + pp2->sctx.ctx_doi, pp1->sctx.ctx_doi); + goto err; + } + + if (pp1->sctx.ctx_alg == pp2->sctx.ctx_alg) + newpp->sctx.ctx_alg = pp1->sctx.ctx_alg; + else { + plog(LLV_ERROR, LOCATION, NULL, + "sec alg mismatched: my:%d peer:%d\n", + pp2->sctx.ctx_alg, pp1->sctx.ctx_alg); + goto err; + } + + if ((pp1->sctx.ctx_strlen != pp2->sctx.ctx_strlen) || + memcmp(pp1->sctx.ctx_str, pp2->sctx.ctx_str, + pp1->sctx.ctx_strlen) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "sec ctx string mismatched: my:%s peer:%s\n", + pp2->sctx.ctx_str, pp1->sctx.ctx_str); + goto err; + } else { + newpp->sctx.ctx_strlen = pp1->sctx.ctx_strlen; + memcpy(newpp->sctx.ctx_str, pp1->sctx.ctx_str, + pp1->sctx.ctx_strlen); + } + } +#endif /* HAVE_SECCTX */ + + npr1 = npr2 = 0; + for (pr1 = pp1->head; pr1; pr1 = pr1->next) + npr1++; + for (pr2 = pp2->head; pr2; pr2 = pr2->next) + npr2++; + if (npr1 != npr2) + goto err; + + /* check protocol order */ + pr1 = pp1->head; + pr2 = pp2->head; + + while (1) { + if (!ordermatters) { + /* + * XXX does not work if we have multiple proposals + * with the same proto_id + */ + switch (side) { + case RESPONDER: + if (!pr2) + break; + for (pr1 = pp1->head; pr1; pr1 = pr1->next) { + if (pr1->proto_id == pr2->proto_id) + break; + } + break; + case INITIATOR: + if (!pr1) + break; + for (pr2 = pp2->head; pr2; pr2 = pr2->next) { + if (pr2->proto_id == pr1->proto_id) + break; + } + break; + } + } + if (!pr1 || !pr2) + break; + + if (pr1->proto_id != pr2->proto_id) { + plog(LLV_ERROR, LOCATION, NULL, + "proto_id mismatched: " + "my:%s peer:%s\n", + s_ipsecdoi_proto(pr2->proto_id), + s_ipsecdoi_proto(pr1->proto_id)); + goto err; + } + spisizematch = 0; + if (pr1->spisize == pr2->spisize) + spisizematch = 1; + else if (pr1->proto_id == IPSECDOI_PROTO_IPCOMP) { + /* + * draft-shacham-ippcp-rfc2393bis-05.txt: + * need to accept 16bit and 32bit SPI (CPI) for IPComp. + */ + if (pr1->spisize == sizeof(u_int16_t) && + pr2->spisize == sizeof(u_int32_t)) { + spisizematch = 1; + } else if (pr2->spisize == sizeof(u_int16_t) && + pr1->spisize == sizeof(u_int32_t)) { + spisizematch = 1; + } + if (spisizematch) { + plog(LLV_ERROR, LOCATION, NULL, + "IPComp SPI size promoted " + "from 16bit to 32bit\n"); + } + } + if (!spisizematch) { + plog(LLV_ERROR, LOCATION, NULL, + "spisize mismatched: " + "my:%d peer:%d\n", + (int)pr2->spisize, (int)pr1->spisize); + goto err; + } + +#ifdef ENABLE_NATT + if ((ph1->natt_flags & NAT_DETECTED) && + natt_udp_encap (pr2->encmode)) + { + plog(LLV_INFO, LOCATION, NULL, "Adjusting my encmode %s->%s\n", + s_ipsecdoi_encmode(pr2->encmode), + s_ipsecdoi_encmode(pr2->encmode - ph1->natt_options->mode_udp_diff)); + pr2->encmode -= ph1->natt_options->mode_udp_diff; + pr2->udp_encap = 1; + } + + if ((ph1->natt_flags & NAT_DETECTED) && + natt_udp_encap (pr1->encmode)) + { + plog(LLV_INFO, LOCATION, NULL, "Adjusting peer's encmode %s(%d)->%s(%d)\n", + s_ipsecdoi_encmode(pr1->encmode), + pr1->encmode, + s_ipsecdoi_encmode(pr1->encmode - ph1->natt_options->mode_udp_diff), + pr1->encmode - ph1->natt_options->mode_udp_diff); + pr1->encmode -= ph1->natt_options->mode_udp_diff; + pr1->udp_encap = 1; + } +#endif + + if (pr1->encmode != pr2->encmode) { + plog(LLV_ERROR, LOCATION, NULL, + "encmode mismatched: " + "my:%s peer:%s\n", + s_ipsecdoi_encmode(pr2->encmode), + s_ipsecdoi_encmode(pr1->encmode)); + goto err; + } + + for (tr1 = pr1->head; tr1; tr1 = tr1->next) { + for (tr2 = pr2->head; tr2; tr2 = tr2->next) { + if (cmpsatrns(pr1->proto_id, tr1, tr2, ph1->rmconf->pcheck_level) == 0) + goto found; + } + } + + goto err; + + found: + newpr = newsaproto(); + if (newpr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate saproto.\n"); + goto err; + } + newpr->proto_id = pr1->proto_id; + newpr->spisize = pr1->spisize; + newpr->encmode = pr1->encmode; + newpr->spi = pr2->spi; /* copy my SPI */ + newpr->spi_p = pr1->spi; /* copy peer's SPI */ + newpr->reqid_in = pr2->reqid_in; + newpr->reqid_out = pr2->reqid_out; +#ifdef ENABLE_NATT + newpr->udp_encap = pr1->udp_encap | pr2->udp_encap; +#endif + + newtr = newsatrns(); + if (newtr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate satrns.\n"); + racoon_free(newpr); + goto err; + } + newtr->trns_no = tr1->trns_no; + newtr->trns_id = tr1->trns_id; + newtr->encklen = tr1->encklen; + newtr->authtype = tr1->authtype; + + inssatrns(newpr, newtr); + inssaproto(newpp, newpr); + + pr1 = pr1->next; + pr2 = pr2->next; + } + + /* XXX should check if we have visited all items or not */ + if (!ordermatters) { + switch (side) { + case RESPONDER: + if (!pr2) + pr1 = NULL; + break; + case INITIATOR: + if (!pr1) + pr2 = NULL; + break; + } + } + + /* should be matched all protocols in a proposal */ + if (pr1 != NULL || pr2 != NULL) + goto err; + + return newpp; + +err: + flushsaprop(newpp); + return NULL; +} + +/* take a single match between saprop. returns 0 if pp1 equals to pp2. */ +int +cmpsaprop(pp1, pp2) + const struct saprop *pp1, *pp2; +{ + if (pp1->pfs_group != pp2->pfs_group) { + plog(LLV_WARNING, LOCATION, NULL, + "pfs_group mismatch. mine:%d peer:%d\n", + pp1->pfs_group, pp2->pfs_group); + /* FALLTHRU */ + } + + if (pp1->lifetime > pp2->lifetime) { + plog(LLV_WARNING, LOCATION, NULL, + "less lifetime proposed. mine:%d peer:%d\n", + (int)pp1->lifetime, (int)pp2->lifetime); + /* FALLTHRU */ + } + if (pp1->lifebyte > pp2->lifebyte) { + plog(LLV_WARNING, LOCATION, NULL, + "less lifebyte proposed. mine:%d peer:%d\n", + pp1->lifebyte, pp2->lifebyte); + /* FALLTHRU */ + } + + return 0; +} + +/* + * take a single match between satrns. returns 0 if tr1 equals to tr2. + * tr1: peer's satrns + * tr2: my satrns + */ +int +cmpsatrns(proto_id, tr1, tr2, check_level) + int proto_id; + const struct satrns *tr1, *tr2; + int check_level; +{ + if (tr1->trns_id != tr2->trns_id) { + plog(LLV_WARNING, LOCATION, NULL, + "trns_id mismatched: " + "my:%s peer:%s\n", + s_ipsecdoi_trns(proto_id, tr2->trns_id), + s_ipsecdoi_trns(proto_id, tr1->trns_id)); + return 1; + } + + if (tr1->authtype != tr2->authtype) { + plog(LLV_WARNING, LOCATION, NULL, + "authtype mismatched: " + "my:%s peer:%s\n", + s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr2->authtype), + s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr1->authtype)); + return 1; + } + + /* Check key length regarding checkmode + * XXX Shall we send some kind of notify message when key length rejected ? + */ + switch(check_level){ + case PROP_CHECK_OBEY: + return 0; + break; + + case PROP_CHECK_STRICT: + /* FALLTHROUGH */ + case PROP_CHECK_CLAIM: + if (tr1->encklen < tr2->encklen) { + plog(LLV_WARNING, LOCATION, NULL, + "low key length proposed, " + "mine:%d peer:%d.\n", + tr2->encklen, tr1->encklen); + return 1; + } + break; + case PROP_CHECK_EXACT: + if (tr1->encklen != tr2->encklen) { + plog(LLV_WARNING, LOCATION, NULL, + "key length mismatched, " + "mine:%d peer:%d.\n", + tr2->encklen, tr1->encklen); + return 1; + } + break; + } + + return 0; +} + +int +set_satrnsbysainfo(pr, sainfo) + struct saproto *pr; + struct sainfo *sainfo; +{ + struct sainfoalg *a, *b; + struct satrns *newtr; + int t; + + switch (pr->proto_id) { + case IPSECDOI_PROTO_IPSEC_AH: + if (sainfo->algs[algclass_ipsec_auth] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no auth algorithm found\n"); + goto err; + } + t = 1; + for (a = sainfo->algs[algclass_ipsec_auth]; a; a = a->next) { + + if (a->alg == IPSECDOI_ATTR_AUTH_NONE) + continue; + + /* allocate satrns */ + newtr = newsatrns(); + if (newtr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate satrns.\n"); + goto err; + } + + newtr->trns_no = t++; + newtr->trns_id = ipsecdoi_authalg2trnsid(a->alg); + newtr->authtype = a->alg; + + inssatrns(pr, newtr); + } + break; + case IPSECDOI_PROTO_IPSEC_ESP: + if (sainfo->algs[algclass_ipsec_enc] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no encryption algorithm found\n"); + goto err; + } + t = 1; + for (a = sainfo->algs[algclass_ipsec_enc]; a; a = a->next) { + for (b = sainfo->algs[algclass_ipsec_auth]; b; b = b->next) { + /* allocate satrns */ + newtr = newsatrns(); + if (newtr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate satrns.\n"); + goto err; + } + + newtr->trns_no = t++; + newtr->trns_id = a->alg; + newtr->encklen = a->encklen; + newtr->authtype = b->alg; + + inssatrns(pr, newtr); + } + } + break; + case IPSECDOI_PROTO_IPCOMP: + if (sainfo->algs[algclass_ipsec_comp] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no ipcomp algorithm found\n"); + goto err; + } + t = 1; + for (a = sainfo->algs[algclass_ipsec_comp]; a; a = a->next) { + + /* allocate satrns */ + newtr = newsatrns(); + if (newtr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate satrns.\n"); + goto err; + } + + newtr->trns_no = t++; + newtr->trns_id = a->alg; + newtr->authtype = IPSECDOI_ATTR_AUTH_NONE; /*no auth*/ + + inssatrns(pr, newtr); + } + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "unknown proto_id (%d).\n", pr->proto_id); + goto err; + } + + /* no proposal found */ + if (pr->head == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "no algorithms found.\n"); + return -1; + } + + return 0; + +err: + flushsatrns(pr->head); + return -1; +} + +struct saprop * +aproppair2saprop(p0) + struct prop_pair *p0; +{ + struct prop_pair *p, *t; + struct saprop *newpp; + struct saproto *newpr; + struct satrns *newtr; + u_int8_t *spi; + + if (p0 == NULL) + return NULL; + + /* allocate ipsec a sa proposal */ + newpp = newsaprop(); + if (newpp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate saprop.\n"); + return NULL; + } + newpp->prop_no = p0->prop->p_no; + /* lifetime & lifebyte must be updated later */ + + for (p = p0; p; p = p->next) { + + /* allocate ipsec sa protocol */ + newpr = newsaproto(); + if (newpr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate saproto.\n"); + goto err; + } + + /* check spi size */ + /* XXX should be handled isakmp cookie */ + if (sizeof(newpr->spi) < p->prop->spi_size) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid spi size %d.\n", p->prop->spi_size); + racoon_free(newpr); + goto err; + } + + /* + * XXX SPI bits are left-filled, for use with IPComp. + * we should be switching to variable-length spi field... + */ + newpr->proto_id = p->prop->proto_id; + newpr->spisize = p->prop->spi_size; + memset(&newpr->spi, 0, sizeof(newpr->spi)); + spi = (u_int8_t *)&newpr->spi; + spi += sizeof(newpr->spi); + spi -= p->prop->spi_size; + memcpy(spi, p->prop + 1, p->prop->spi_size); + newpr->reqid_in = 0; + newpr->reqid_out = 0; + + for (t = p; t; t = t->tnext) { + + plog(LLV_DEBUG, LOCATION, NULL, + "prop#=%d prot-id=%s spi-size=%d " + "#trns=%d trns#=%d trns-id=%s\n", + t->prop->p_no, + s_ipsecdoi_proto(t->prop->proto_id), + t->prop->spi_size, t->prop->num_t, + t->trns->t_no, + s_ipsecdoi_trns(t->prop->proto_id, + t->trns->t_id)); + + /* allocate ipsec sa transform */ + newtr = newsatrns(); + if (newtr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate satrns.\n"); + racoon_free(newpr); + goto err; + } + + if (ipsecdoi_t2satrns(t->trns, + newpp, newpr, newtr) < 0) { + flushsaprop(newpp); + racoon_free(newtr); + racoon_free(newpr); + return NULL; + } + + inssatrns(newpr, newtr); + } + + /* + * If the peer does not specify encryption mode, use + * transport mode by default. This is to conform to + * draft-shacham-ippcp-rfc2393bis-08.txt (explicitly specifies + * that unspecified == transport), as well as RFC2407 + * (unspecified == implementation dependent default). + */ + if (newpr->encmode == 0) + newpr->encmode = IPSECDOI_ATTR_ENC_MODE_TRNS; + + inssaproto(newpp, newpr); + } + + return newpp; + +err: + flushsaprop(newpp); + return NULL; +} + +void +flushsaprop(head) + struct saprop *head; +{ + struct saprop *p, *save; + + for (p = head; p != NULL; p = save) { + save = p->next; + flushsaproto(p->head); + racoon_free(p); + } + + return; +} + +void +flushsaproto(head) + struct saproto *head; +{ + struct saproto *p, *save; + + for (p = head; p != NULL; p = save) { + save = p->next; + flushsatrns(p->head); + vfree(p->keymat); + vfree(p->keymat_p); + racoon_free(p); + } + + return; +} + +void +flushsatrns(head) + struct satrns *head; +{ + struct satrns *p, *save; + + for (p = head; p != NULL; p = save) { + save = p->next; + racoon_free(p); + } + + return; +} + +/* + * print multiple proposals + */ +void +printsaprop(pri, pp) + const int pri; + const struct saprop *pp; +{ + const struct saprop *p; + + if (pp == NULL) { + plog(pri, LOCATION, NULL, "(null)"); + return; + } + + for (p = pp; p; p = p->next) { + printsaprop0(pri, p); + } + + return; +} + +/* + * print one proposal. + */ +void +printsaprop0(pri, pp) + int pri; + const struct saprop *pp; +{ + const struct saproto *p; + + if (pp == NULL) + return; + + for (p = pp->head; p; p = p->next) { + printsaproto(pri, p); + } + + return; +} + +void +printsaproto(pri, pr) + const int pri; + const struct saproto *pr; +{ + struct satrns *tr; + + if (pr == NULL) + return; + + plog(pri, LOCATION, NULL, + " (proto_id=%s spisize=%d spi=%08lx spi_p=%08lx " + "encmode=%s reqid=%d:%d)\n", + s_ipsecdoi_proto(pr->proto_id), + (int)pr->spisize, + (unsigned long)ntohl(pr->spi), + (unsigned long)ntohl(pr->spi_p), + s_ipsecdoi_attr_v(IPSECDOI_ATTR_ENC_MODE, pr->encmode), + (int)pr->reqid_in, (int)pr->reqid_out); + + for (tr = pr->head; tr; tr = tr->next) { + printsatrns(pri, pr->proto_id, tr); + } + + return; +} + +void +printsatrns(pri, proto_id, tr) + const int pri; + const int proto_id; + const struct satrns *tr; +{ + if (tr == NULL) + return; + + switch (proto_id) { + case IPSECDOI_PROTO_IPSEC_AH: + plog(pri, LOCATION, NULL, + " (trns_id=%s authtype=%s)\n", + s_ipsecdoi_trns(proto_id, tr->trns_id), + s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr->authtype)); + break; + case IPSECDOI_PROTO_IPSEC_ESP: + plog(pri, LOCATION, NULL, + " (trns_id=%s encklen=%d authtype=%s)\n", + s_ipsecdoi_trns(proto_id, tr->trns_id), + tr->encklen, + s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr->authtype)); + break; + case IPSECDOI_PROTO_IPCOMP: + plog(pri, LOCATION, NULL, + " (trns_id=%s)\n", + s_ipsecdoi_trns(proto_id, tr->trns_id)); + break; + default: + plog(pri, LOCATION, NULL, + "(unknown proto_id %d)\n", proto_id); + } + + return; +} + +void +print_proppair0(pri, p, level) + int pri; + struct prop_pair *p; + int level; +{ + char spc[21]; + + memset(spc, ' ', sizeof(spc)); + spc[sizeof(spc) - 1] = '\0'; + if (level < 20) { + spc[level] = '\0'; + } + + plog(pri, LOCATION, NULL, + "%s%p: next=%p tnext=%p\n", spc, p, p->next, p->tnext); + if (p->next) + print_proppair0(pri, p->next, level + 1); + if (p->tnext) + print_proppair0(pri, p->tnext, level + 1); +} + +void +print_proppair(pri, p) + int pri; + struct prop_pair *p; +{ + print_proppair0(pri, p, 1); +} + +int +set_proposal_from_policy(iph2, sp_main, sp_sub) + struct ph2handle *iph2; + struct secpolicy *sp_main, *sp_sub; +{ + struct saprop *newpp; + struct ipsecrequest *req; + int encmodesv = IPSECDOI_ATTR_ENC_MODE_TRNS; /* use only when complex_bundle */ + + newpp = newsaprop(); + if (newpp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate saprop.\n"); + goto err; + } + newpp->prop_no = 1; + newpp->lifetime = iph2->sainfo->lifetime; + newpp->lifebyte = iph2->sainfo->lifebyte; + newpp->pfs_group = iph2->sainfo->pfs_group; + + if (lcconf->complex_bundle) + goto skip1; + + /* + * decide the encryption mode of this SA bundle. + * the mode becomes tunnel mode when there is even one policy + * of tunnel mode in the SPD. otherwise the mode becomes + * transport mode. + */ + for (req = sp_main->req; req; req = req->next) { + if (req->saidx.mode == IPSEC_MODE_TUNNEL) { + encmodesv = pfkey2ipsecdoi_mode(req->saidx.mode); +#ifdef ENABLE_NATT + if (iph2->ph1 && (iph2->ph1->natt_flags & NAT_DETECTED)) + encmodesv += iph2->ph1->natt_options->mode_udp_diff; +#endif + break; + } + } + + skip1: + for (req = sp_main->req; req; req = req->next) { + struct saproto *newpr; + caddr_t paddr = NULL; + + /* + * check if SA bundle ? + * nested SAs negotiation is NOT supported. + * me +--- SA1 ---+ peer1 + * me +--- SA2 --------------+ peer2 + */ +#ifdef __linux__ + if (req->saidx.src.ss_family && req->saidx.dst.ss_family) { +#else + if (req->saidx.src.ss_len && req->saidx.dst.ss_len) { +#endif + /* check the end of ip addresses of SA */ + if (iph2->side == INITIATOR) + paddr = (caddr_t)&req->saidx.dst; + else + paddr = (caddr_t)&req->saidx.src; + } + + /* allocate ipsec sa protocol */ + newpr = newsaproto(); + if (newpr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate saproto.\n"); + goto err; + } + + newpr->proto_id = ipproto2doi(req->saidx.proto); + if (newpr->proto_id == IPSECDOI_PROTO_IPCOMP) + newpr->spisize = 2; + else + newpr->spisize = 4; + if (lcconf->complex_bundle) { + newpr->encmode = pfkey2ipsecdoi_mode(req->saidx.mode); +#ifdef ENABLE_NATT + if (iph2->ph1 && (iph2->ph1->natt_flags & NAT_DETECTED)) + newpr->encmode += + iph2->ph1->natt_options->mode_udp_diff; +#endif + } + else + newpr->encmode = encmodesv; + + if (iph2->side == INITIATOR) + newpr->reqid_out = req->saidx.reqid; + else + newpr->reqid_in = req->saidx.reqid; + + if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get algorithms.\n"); + racoon_free(newpr); + goto err; + } + + /* set new saproto */ + inssaprotorev(newpp, newpr); + } + + /* get reqid_in from inbound policy */ + if (sp_sub) { + struct saproto *pr; + + req = sp_sub->req; + pr = newpp->head; + while (req && pr) { + if (iph2->side == INITIATOR) + pr->reqid_in = req->saidx.reqid; + else + pr->reqid_out = req->saidx.reqid; + pr = pr->next; + req = req->next; + } + if (pr || req) { + plog(LLV_NOTIFY, LOCATION, NULL, + "There is a difference " + "between the in/out bound policies in SPD.\n"); + } + } + + iph2->proposal = newpp; + + printsaprop0(LLV_DEBUG, newpp); + + return 0; +err: + flushsaprop(newpp); + return -1; +} + +/* + * generate a policy from peer's proposal. + * this function unconditionally choices first proposal in SA payload + * passed by peer. + */ +int +set_proposal_from_proposal(iph2) + struct ph2handle *iph2; +{ + struct saprop *newpp = NULL, *pp0, *pp_peer = NULL; + struct saproto *newpr = NULL, *pr; + struct prop_pair **pair; + int error = -1; + int i; + + /* get proposal pair */ + pair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2); + if (pair == NULL) + goto end; + + /* + * make my proposal according as the client proposal. + * XXX assumed there is only one proposal even if it's the SA bundle. + */ + for (i = 0; i < MAXPROPPAIRLEN; i++) { + if (pair[i] == NULL) + continue; + + if (pp_peer != NULL) + flushsaprop(pp_peer); + + pp_peer = aproppair2saprop(pair[i]); + if (pp_peer == NULL) + goto end; + + pp0 = newsaprop(); + if (pp0 == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate saprop.\n"); + goto end; + } + pp0->prop_no = 1; + pp0->lifetime = iph2->sainfo->lifetime; + pp0->lifebyte = iph2->sainfo->lifebyte; + pp0->pfs_group = iph2->sainfo->pfs_group; + +#ifdef HAVE_SECCTX + if (*pp_peer->sctx.ctx_str) { + pp0->sctx.ctx_doi = pp_peer->sctx.ctx_doi; + pp0->sctx.ctx_alg = pp_peer->sctx.ctx_alg; + pp0->sctx.ctx_strlen = pp_peer->sctx.ctx_strlen; + memcpy(pp0->sctx.ctx_str, pp_peer->sctx.ctx_str, + pp_peer->sctx.ctx_strlen); + } +#endif /* HAVE_SECCTX */ + + if (pp_peer->next != NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "pp_peer is inconsistency, ignore it.\n"); + /*FALLTHROUGH*/ + } + + for (pr = pp_peer->head; pr; pr = pr->next) + { + newpr = newsaproto(); + if (newpr == NULL) + { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate saproto.\n"); + racoon_free(pp0); + goto end; + } + newpr->proto_id = pr->proto_id; + newpr->spisize = pr->spisize; + newpr->encmode = pr->encmode; + newpr->spi = 0; + newpr->spi_p = pr->spi; /* copy peer's SPI */ + newpr->reqid_in = 0; + newpr->reqid_out = 0; + + if (iph2->ph1->rmconf->gen_policy == GENERATE_POLICY_UNIQUE){ + newpr->reqid_in = g_nextreqid ; + newpr->reqid_out = g_nextreqid ++; + /* + * XXX there is a (very limited) + * risk of reusing the same reqid + * as another SP entry for the same peer + */ + if(g_nextreqid >= IPSEC_MANUAL_REQID_MAX) + g_nextreqid = 1; + }else{ + newpr->reqid_in = 0; + newpr->reqid_out = 0; + } + + if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) + { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get algorithms.\n"); + racoon_free(newpr); + racoon_free(pp0); + goto end; + } + inssaproto(pp0, newpr); + } + + inssaprop(&newpp, pp0); + } + + plog(LLV_DEBUG, LOCATION, NULL, "make a proposal from peer's:\n"); + printsaprop0(LLV_DEBUG, newpp); + + iph2->proposal = newpp; + + error = 0; + +end: + if (error && newpp) + flushsaprop(newpp); + + if (pp_peer) + flushsaprop(pp_peer); + if (pair) + free_proppair(pair); + return error; +} diff --git a/ipsec-tools/src/racoon/proposal.h b/ipsec-tools/src/racoon/proposal.h new file mode 100644 index 00000000..11fbab8b --- /dev/null +++ b/ipsec-tools/src/racoon/proposal.h @@ -0,0 +1,214 @@ +/* $NetBSD: proposal.h,v 1.7 2010/02/09 23:05:16 wiz Exp $ */ + +/* Id: proposal.h,v 1.5 2004/06/11 16:00:17 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _PROPOSAL_H +#define _PROPOSAL_H + +#include + +/* + * A. chained list of transform, only for single proto_id + * (this is same as set of transforms in single proposal payload) + * B. proposal. this will point to multiple (A) items (order is important + * here so pointer to (A) must be ordered array, or chained list). + * this covers multiple proposal on a packet if proposal # is the same. + * C. finally, (B) needs to be connected as chained list. + * + * head ---> prop[.......] ---> prop[...] ---> prop[...] ---> ... + * | | | | + * | | | +- proto4 <== must preserve order here + * | | +--- proto3 + * | +----- proto2 + * +------- proto1[trans1, trans2, trans3, ...] + * + * incoming packets needs to be parsed to construct the same structure + * (check "prop_pair" too). + */ +/* SA proposal specification */ +struct saprop { + int prop_no; + time_t lifetime; + int lifebyte; + int pfs_group; /* pfs group */ + int claim; /* flag to send RESPONDER-LIFETIME. */ + /* XXX assumed DOI values are 1 or 2. */ +#ifdef HAVE_SECCTX + struct security_ctx sctx; /* security context structure */ +#endif + struct saproto *head; + struct saprop *next; +}; + +/* SA protocol specification */ +struct saproto { + int proto_id; + size_t spisize; /* spi size */ + int encmode; /* encryption mode */ + + int udp_encap; /* UDP encapsulation */ + + /* XXX should be vchar_t * */ + /* these are network byte order */ + u_int32_t spi; /* inbound. i.e. --SA-> me */ + u_int32_t spi_p; /* outbound. i.e. me -SA-> */ + + vchar_t *keymat; /* KEYMAT */ + vchar_t *keymat_p; /* peer's KEYMAT */ + + int reqid_out; /* request id (outbound) */ + int reqid_in; /* request id (inbound) */ + + int ok; /* if 1, success to set SA in kernel */ + + struct satrns *head; /* header of transform */ + struct saproto *next; /* next protocol */ +}; + +/* SA algorithm specification */ +struct satrns { + int trns_no; + int trns_id; /* transform id */ + int encklen; /* key length of encryption algorithm */ + int authtype; /* authentication algorithm if ESP */ + + struct satrns *next; /* next transform */ +}; + +/* + * prop_pair: (proposal number, transform number) + * + * (SA (P1 (T1 T2)) (P1' (T1' T2')) (P2 (T1" T2"))) + * + * p[1] p[2] + * top (P1,T1) (P2",T1") + * | |tnext |tnext + * | v v + * | (P1, T2) (P2", T2") + * v next + * (P1', T1') + * |tnext + * v + * (P1', T2') + * + * when we convert it to saprop in prop2saprop(), it should become like: + * + * (next) + * saprop --------------------> saprop + * | (head) | (head) + * +-> saproto +-> saproto + * | | (head) | (head) + * | +-> satrns(P1 T1) +-> satrns(P2" T1") + * | | (next) | (next) + * | v v + * | satrns(P1, T2) satrns(P2", T2") + * v (next) + * saproto + * | (head) + * +-> satrns(P1' T1') + * | (next) + * v + * satrns(P1', T2') + */ +struct prop_pair { + struct isakmp_pl_p *prop; + struct isakmp_pl_t *trns; + struct prop_pair *next; /* next prop_pair with same proposal # */ + /* (bundle case) */ + struct prop_pair *tnext; /* next prop_pair in same proposal payload */ + /* (multiple tranform case) */ +}; +#define MAXPROPPAIRLEN 256 /* It's enough because field size is 1 octet. */ + +/* + * Lifetime length selection refered to the section 4.5.4 of RFC2407. It does + * not completely conform to the description of RFC. There are four types of + * the behavior. If the value of "proposal_check" in "remote" directive is; + * "obey" + * the responder obey the initiator anytime. + * "strict" + * If the responder's length is longer than the initiator's one, the + * responder uses the intitiator's one. Otherwise rejects the proposal. + * If PFS is not required by the responder, the responder obeys the + * proposal. If PFS is required by both sides and if the responder's + * group is not equal to the initiator's one, then the responder reject + * the proposal. + * "claim" + * If the responder's length is longer than the initiator's one, the + * responder use the intitiator's one. If the responder's length is + * shorter than the initiator's one, the responder uses own length + * AND send RESPONDER-LIFETIME notify message to a initiator in the + * case of lifetime. + * About PFS, this directive is same as "strict". + * "exact" + * If the initiator's length is not equal to the responder's one, the + * responder rejects the proposal. + * If PFS is required and if the responder's group is not equal to + * the initiator's one, then the responder reject the proposal. + * XXX should be defined the behavior of key length. + */ +#define PROP_CHECK_OBEY 1 +#define PROP_CHECK_STRICT 2 +#define PROP_CHECK_CLAIM 3 +#define PROP_CHECK_EXACT 4 + +struct sainfo; +struct ph1handle; +struct secpolicy; +extern struct saprop *newsaprop __P((void)); +extern struct saproto *newsaproto __P((void)); +extern void inssaprop __P((struct saprop **, struct saprop *)); +extern void inssaproto __P((struct saprop *, struct saproto *)); +extern void inssaprotorev __P((struct saprop *, struct saproto *)); +extern struct satrns *newsatrns __P((void)); +extern void inssatrns __P((struct saproto *, struct satrns *)); +extern struct saprop *cmpsaprop_alloc __P((struct ph1handle *, + const struct saprop *, const struct saprop *, int)); +extern int cmpsaprop __P((const struct saprop *, const struct saprop *)); +extern int cmpsatrns __P((int, const struct satrns *, const struct satrns *, int)); +extern int set_satrnsbysainfo __P((struct saproto *, struct sainfo *)); +extern struct saprop *aproppair2saprop __P((struct prop_pair *)); +extern void free_proppair __P((struct prop_pair **)); +extern void flushsaprop __P((struct saprop *)); +extern void flushsaproto __P((struct saproto *)); +extern void flushsatrns __P((struct satrns *)); +extern void printsaprop __P((const int, const struct saprop *)); +extern void printsaprop0 __P((const int, const struct saprop *)); +extern void printsaproto __P((const int, const struct saproto *)); +extern void printsatrns __P((const int, const int, const struct satrns *)); +extern void print_proppair0 __P((int, struct prop_pair *, int)); +extern void print_proppair __P((int, struct prop_pair *)); +extern int set_proposal_from_policy __P((struct ph2handle *, + struct secpolicy *, struct secpolicy *)); +extern int set_proposal_from_proposal __P((struct ph2handle *)); + +#endif /* _PROPOSAL_H */ diff --git a/ipsec-tools/src/racoon/prsa_par.c b/ipsec-tools/src/racoon/prsa_par.c new file mode 100644 index 00000000..a9761455 --- /dev/null +++ b/ipsec-tools/src/racoon/prsa_par.c @@ -0,0 +1,2062 @@ +/* A Bison parser, made by GNU Bison 2.6.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + 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 3 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.6.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + +/* Substitute the variable and function names. */ +#define yyparse prsaparse +#define yylex prsalex +#define yyerror prsaerror +#define yylval prsalval +#define yychar prsachar +#define yydebug prsadebug +#define yynerrs prsanerrs + +/* Copy the first part of user declarations. */ +/* Line 336 of yacc.c */ +#line 5 "prsa_par.y" + +/* + * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. + * Contributed by: Michal Ludvig , SUSE Labs + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* This file contains a parser for FreeS/WAN-style ipsec.secrets RSA keys. */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#ifdef HAVE_STDARG_H +#include +#else +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "oakley.h" +#include "isakmp_var.h" +#include "handler.h" +#include "crypto_openssl.h" +#include "sockmisc.h" +#include "rsalist.h" + +extern void prsaerror(const char *str, ...); +extern int prsawrap (void); +extern int prsalex (void); + +extern char *prsatext; +extern int prsa_cur_lineno; +extern char *prsa_cur_fname; +extern FILE *prsain; + +int prsa_cur_lineno = 0; +char *prsa_cur_fname = NULL; +struct genlist *prsa_cur_list = NULL; +enum rsa_key_type prsa_cur_type = RSA_TYPE_ANY; + +static RSA *rsa_cur; + +void +prsaerror(const char *s, ...) +{ + char fmt[512]; + + va_list ap; +#ifdef HAVE_STDARG_H + va_start(ap, s); +#else + va_start(ap); +#endif + snprintf(fmt, sizeof(fmt), "%s:%d: %s", + prsa_cur_fname, prsa_cur_lineno, s); + plogv(LLV_ERROR, LOCATION, NULL, fmt, ap); + va_end(ap); +} + +void +prsawarning(const char *s, ...) +{ + char fmt[512]; + + va_list ap; +#ifdef HAVE_STDARG_H + va_start(ap, s); +#else + va_start(ap); +#endif + snprintf(fmt, sizeof(fmt), "%s:%d: %s", + prsa_cur_fname, prsa_cur_lineno, s); + plogv(LLV_WARNING, LOCATION, NULL, fmt, ap); + va_end(ap); +} + +int +prsawrap() +{ + return 1; +} + +/* Line 336 of yacc.c */ +#line 201 "prsa_par.c" + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "y.tab.h". */ +#ifndef PRSA_Y_TAB_H +# define PRSA_Y_TAB_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int prsadebug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + COLON = 258, + HEX = 259, + OBRACE = 260, + EBRACE = 261, + TAG_RSA = 262, + TAG_PUB = 263, + TAG_PSK = 264, + MODULUS = 265, + PUBLIC_EXPONENT = 266, + PRIVATE_EXPONENT = 267, + PRIME1 = 268, + PRIME2 = 269, + EXPONENT1 = 270, + EXPONENT2 = 271, + COEFFICIENT = 272, + ADDR4 = 273, + ADDR6 = 274, + ADDRANY = 275, + SLASH = 276, + NUMBER = 277, + BASE64 = 278 + }; +#endif +/* Tokens. */ +#define COLON 258 +#define HEX 259 +#define OBRACE 260 +#define EBRACE 261 +#define TAG_RSA 262 +#define TAG_PUB 263 +#define TAG_PSK 264 +#define MODULUS 265 +#define PUBLIC_EXPONENT 266 +#define PRIVATE_EXPONENT 267 +#define PRIME1 268 +#define PRIME2 269 +#define EXPONENT1 270 +#define EXPONENT2 271 +#define COEFFICIENT 272 +#define ADDR4 273 +#define ADDR6 274 +#define ADDRANY 275 +#define SLASH 276 +#define NUMBER 277 +#define BASE64 278 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 350 of yacc.c */ +#line 130 "prsa_par.y" + + BIGNUM *bn; + RSA *rsa; + char *chr; + long num; + struct netaddr *naddr; + + +/* Line 350 of yacc.c */ +#line 299 "prsa_par.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE prsalval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int prsaparse (void *YYPARSE_PARAM); +#else +int prsaparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int prsaparse (void); +#else +int prsaparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !PRSA_Y_TAB_H */ + +/* Copy the second part of user declarations. */ + +/* Line 353 of yacc.c */ +#line 327 "prsa_par.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 16 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 60 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 24 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 10 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 26 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 55 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 278 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 6, 8, 13, 17, 20, 25, 28, + 31, 33, 35, 37, 40, 43, 44, 47, 50, 52, + 56, 60, 64, 68, 72, 76, 80 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 25, 0, -1, 25, 26, -1, 26, -1, 28, 28, + 3, 27, -1, 28, 3, 27, -1, 3, 27, -1, + 7, 5, 32, 6, -1, 8, 23, -1, 8, 4, + -1, 29, -1, 30, -1, 20, -1, 18, 31, -1, + 19, 31, -1, -1, 21, 22, -1, 32, 33, -1, + 33, -1, 10, 3, 4, -1, 11, 3, 4, -1, + 12, 3, 4, -1, 13, 3, 4, -1, 14, 3, + 4, -1, 15, 3, 4, -1, 16, 3, 4, -1, + 17, 3, 4, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 155, 155, 156, 160, 164, 168, 175, 207, 216, + 227, 228, 229, 236, 265, 294, 295, 298, 299, 303, + 305, 307, 309, 311, 313, 315, 317 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "COLON", "HEX", "OBRACE", "EBRACE", + "TAG_RSA", "TAG_PUB", "TAG_PSK", "MODULUS", "PUBLIC_EXPONENT", + "PRIVATE_EXPONENT", "PRIME1", "PRIME2", "EXPONENT1", "EXPONENT2", + "COEFFICIENT", "ADDR4", "ADDR6", "ADDRANY", "SLASH", "NUMBER", "BASE64", + "$accept", "statements", "statement", "rsa_statement", "addr", "addr4", + "addr6", "prefix", "params", "param", YY_NULL +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 24, 25, 25, 26, 26, 26, 27, 27, 27, + 28, 28, 28, 29, 30, 31, 31, 32, 32, 33, + 33, 33, 33, 33, 33, 33, 33 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 2, 1, 4, 3, 2, 4, 2, 2, + 1, 1, 1, 2, 2, 0, 2, 2, 1, 3, + 3, 3, 3, 3, 3, 3, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 0, 15, 15, 12, 0, 3, 0, 10, 11, + 0, 0, 6, 0, 13, 14, 1, 2, 0, 0, + 0, 9, 8, 16, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 18, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 17, 19, 20, 21, + 22, 23, 24, 25, 26 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 5, 6, 12, 7, 8, 9, 14, 34, 35 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -18 +static const yytype_int8 yypact[] = +{ + 4, -3, -15, -15, -18, 0, -18, 7, -18, -18, + 6, -2, -18, -13, -18, -18, -18, -18, -3, 9, + 30, -18, -18, -18, -18, -3, 10, 11, 12, 13, + 14, 26, 27, 28, 22, -18, -18, 44, 45, 46, + 47, 48, 49, 50, 51, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -18, -18, 52, -17, 53, -18, -18, 55, -18, 25 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 16, 24, 21, 1, 10, 11, 13, 1, 36, 23, + 18, 20, 25, 37, 38, 39, 40, 41, 2, 3, + 4, 22, 2, 3, 4, 2, 3, 4, 45, 42, + 43, 44, 26, 27, 28, 29, 30, 31, 32, 33, + 26, 27, 28, 29, 30, 31, 32, 33, 47, 48, + 49, 50, 51, 52, 53, 54, 0, 17, 15, 46, + 19 +}; + +#define yypact_value_is_default(yystate) \ + ((yystate) == (-18)) + +#define yytable_value_is_error(yytable_value) \ + YYID (0) + +static const yytype_int8 yycheck[] = +{ + 0, 18, 4, 3, 7, 8, 21, 3, 25, 22, + 3, 5, 3, 3, 3, 3, 3, 3, 18, 19, + 20, 23, 18, 19, 20, 18, 19, 20, 6, 3, + 3, 3, 10, 11, 12, 13, 14, 15, 16, 17, + 10, 11, 12, 13, 14, 15, 16, 17, 4, 4, + 4, 4, 4, 4, 4, 4, -1, 5, 3, 34, + 7 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 18, 19, 20, 25, 26, 28, 29, 30, + 7, 8, 27, 21, 31, 31, 0, 26, 3, 28, + 5, 4, 23, 22, 27, 3, 10, 11, 12, 13, + 14, 15, 16, 17, 32, 33, 27, 3, 3, 3, + 3, 3, 3, 3, 3, 6, 33, 4, 4, 4, + 4, 4, 4, 4, 4 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + + + +/* This macro is provided for backward compatibility. */ + +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULL; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 4: +/* Line 1787 of yacc.c */ +#line 161 "prsa_par.y" + { + rsa_key_insert(prsa_cur_list, (yyvsp[(1) - (4)].naddr), (yyvsp[(2) - (4)].naddr), (yyvsp[(4) - (4)].rsa)); + } + break; + + case 5: +/* Line 1787 of yacc.c */ +#line 165 "prsa_par.y" + { + rsa_key_insert(prsa_cur_list, NULL, (yyvsp[(1) - (3)].naddr), (yyvsp[(3) - (3)].rsa)); + } + break; + + case 6: +/* Line 1787 of yacc.c */ +#line 169 "prsa_par.y" + { + rsa_key_insert(prsa_cur_list, NULL, NULL, (yyvsp[(2) - (2)].rsa)); + } + break; + + case 7: +/* Line 1787 of yacc.c */ +#line 176 "prsa_par.y" + { + if (prsa_cur_type == RSA_TYPE_PUBLIC) { + prsawarning("Using private key for public key purpose.\n"); + if (!rsa_cur->n || !rsa_cur->e) { + prsaerror("Incomplete key. Mandatory parameters are missing!\n"); + YYABORT; + } + } + else { + if (!rsa_cur->n || !rsa_cur->e || !rsa_cur->d) { + prsaerror("Incomplete key. Mandatory parameters are missing!\n"); + YYABORT; + } + if (!rsa_cur->p || !rsa_cur->q || !rsa_cur->dmp1 + || !rsa_cur->dmq1 || !rsa_cur->iqmp) { + if (rsa_cur->p) BN_clear_free(rsa_cur->p); + if (rsa_cur->q) BN_clear_free(rsa_cur->q); + if (rsa_cur->dmp1) BN_clear_free(rsa_cur->dmp1); + if (rsa_cur->dmq1) BN_clear_free(rsa_cur->dmq1); + if (rsa_cur->iqmp) BN_clear_free(rsa_cur->iqmp); + + rsa_cur->p = NULL; + rsa_cur->q = NULL; + rsa_cur->dmp1 = NULL; + rsa_cur->dmq1 = NULL; + rsa_cur->iqmp = NULL; + } + } + (yyval.rsa) = rsa_cur; + rsa_cur = RSA_new(); + } + break; + + case 8: +/* Line 1787 of yacc.c */ +#line 208 "prsa_par.y" + { + if (prsa_cur_type == RSA_TYPE_PRIVATE) { + prsaerror("Public key in private-key file!\n"); + YYABORT; + } + (yyval.rsa) = base64_pubkey2rsa((yyvsp[(2) - (2)].chr)); + free((yyvsp[(2) - (2)].chr)); + } + break; + + case 9: +/* Line 1787 of yacc.c */ +#line 217 "prsa_par.y" + { + if (prsa_cur_type == RSA_TYPE_PRIVATE) { + prsaerror("Public key in private-key file!\n"); + YYABORT; + } + (yyval.rsa) = bignum_pubkey2rsa((yyvsp[(2) - (2)].bn)); + } + break; + + case 12: +/* Line 1787 of yacc.c */ +#line 230 "prsa_par.y" + { + (yyval.naddr) = NULL; + } + break; + + case 13: +/* Line 1787 of yacc.c */ +#line 237 "prsa_par.y" + { + int err; + struct sockaddr_in *sap; + struct addrinfo hints, *res; + + if ((yyvsp[(2) - (2)].num) == -1) (yyvsp[(2) - (2)].num) = 32; + if ((yyvsp[(2) - (2)].num) < 0 || (yyvsp[(2) - (2)].num) > 32) { + prsaerror ("Invalid IPv4 prefix\n"); + YYABORT; + } + (yyval.naddr) = calloc (sizeof(struct netaddr), 1); + (yyval.naddr)->prefix = (yyvsp[(2) - (2)].num); + sap = (struct sockaddr_in *)(&(yyval.naddr)->sa); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_flags = AI_NUMERICHOST; + err = getaddrinfo((yyvsp[(1) - (2)].chr), NULL, &hints, &res); + if (err < 0) { + prsaerror("getaddrinfo(%s): %s\n", (yyvsp[(1) - (2)].chr), gai_strerror(err)); + YYABORT; + } + memcpy(sap, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + free((yyvsp[(1) - (2)].chr)); + } + break; + + case 14: +/* Line 1787 of yacc.c */ +#line 266 "prsa_par.y" + { + int err; + struct sockaddr_in6 *sap; + struct addrinfo hints, *res; + + if ((yyvsp[(2) - (2)].num) == -1) (yyvsp[(2) - (2)].num) = 128; + if ((yyvsp[(2) - (2)].num) < 0 || (yyvsp[(2) - (2)].num) > 128) { + prsaerror ("Invalid IPv6 prefix\n"); + YYABORT; + } + (yyval.naddr) = calloc (sizeof(struct netaddr), 1); + (yyval.naddr)->prefix = (yyvsp[(2) - (2)].num); + sap = (struct sockaddr_in6 *)(&(yyval.naddr)->sa); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + hints.ai_flags = AI_NUMERICHOST; + err = getaddrinfo((yyvsp[(1) - (2)].chr), NULL, &hints, &res); + if (err < 0) { + prsaerror("getaddrinfo(%s): %s\n", (yyvsp[(1) - (2)].chr), gai_strerror(err)); + YYABORT; + } + memcpy(sap, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + free((yyvsp[(1) - (2)].chr)); + } + break; + + case 15: +/* Line 1787 of yacc.c */ +#line 294 "prsa_par.y" + { (yyval.num) = -1; } + break; + + case 16: +/* Line 1787 of yacc.c */ +#line 295 "prsa_par.y" + { (yyval.num) = (yyvsp[(2) - (2)].num); } + break; + + case 19: +/* Line 1787 of yacc.c */ +#line 304 "prsa_par.y" + { if (!rsa_cur->n) rsa_cur->n = (yyvsp[(3) - (3)].bn); else { prsaerror ("Modulus already defined\n"); YYABORT; } } + break; + + case 20: +/* Line 1787 of yacc.c */ +#line 306 "prsa_par.y" + { if (!rsa_cur->e) rsa_cur->e = (yyvsp[(3) - (3)].bn); else { prsaerror ("PublicExponent already defined\n"); YYABORT; } } + break; + + case 21: +/* Line 1787 of yacc.c */ +#line 308 "prsa_par.y" + { if (!rsa_cur->d) rsa_cur->d = (yyvsp[(3) - (3)].bn); else { prsaerror ("PrivateExponent already defined\n"); YYABORT; } } + break; + + case 22: +/* Line 1787 of yacc.c */ +#line 310 "prsa_par.y" + { if (!rsa_cur->p) rsa_cur->p = (yyvsp[(3) - (3)].bn); else { prsaerror ("Prime1 already defined\n"); YYABORT; } } + break; + + case 23: +/* Line 1787 of yacc.c */ +#line 312 "prsa_par.y" + { if (!rsa_cur->q) rsa_cur->q = (yyvsp[(3) - (3)].bn); else { prsaerror ("Prime2 already defined\n"); YYABORT; } } + break; + + case 24: +/* Line 1787 of yacc.c */ +#line 314 "prsa_par.y" + { if (!rsa_cur->dmp1) rsa_cur->dmp1 = (yyvsp[(3) - (3)].bn); else { prsaerror ("Exponent1 already defined\n"); YYABORT; } } + break; + + case 25: +/* Line 1787 of yacc.c */ +#line 316 "prsa_par.y" + { if (!rsa_cur->dmq1) rsa_cur->dmq1 = (yyvsp[(3) - (3)].bn); else { prsaerror ("Exponent2 already defined\n"); YYABORT; } } + break; + + case 26: +/* Line 1787 of yacc.c */ +#line 318 "prsa_par.y" + { if (!rsa_cur->iqmp) rsa_cur->iqmp = (yyvsp[(3) - (3)].bn); else { prsaerror ("Coefficient already defined\n"); YYABORT; } } + break; + + +/* Line 1787 of yacc.c */ +#line 1789 "prsa_par.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +/* Line 2048 of yacc.c */ +#line 320 "prsa_par.y" + + +int prsaparse(void); + +int +prsa_parse_file(struct genlist *list, char *fname, enum rsa_key_type type) +{ + FILE *fp = NULL; + int ret; + + if (!fname) + return -1; + if (type == RSA_TYPE_PRIVATE) { + struct stat st; + if (stat(fname, &st) < 0) + return -1; + if (st.st_mode & (S_IRWXG | S_IRWXO)) { + plog(LLV_ERROR, LOCATION, NULL, + "Too slack permissions on private key '%s'\n", + fname); + plog(LLV_ERROR, LOCATION, NULL, + "Should be at most 0600, now is 0%o\n", + st.st_mode & 0777); + return -1; + } + } + fp = fopen(fname, "r"); + if (!fp) + return -1; + prsain = fp; + prsa_cur_lineno = 1; + prsa_cur_fname = fname; + prsa_cur_list = list; + prsa_cur_type = type; + rsa_cur = RSA_new(); + ret = prsaparse(); + if (rsa_cur) { + RSA_free(rsa_cur); + rsa_cur = NULL; + } + fclose (fp); + prsain = NULL; + return ret; +} diff --git a/ipsec-tools/src/racoon/prsa_par.h b/ipsec-tools/src/racoon/prsa_par.h new file mode 100644 index 00000000..7a7b42ff --- /dev/null +++ b/ipsec-tools/src/racoon/prsa_par.h @@ -0,0 +1,134 @@ +/* A Bison parser, made by GNU Bison 2.6.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + 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 3 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef PRSA_PRSA_PAR_H +# define PRSA_PRSA_PAR_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int prsadebug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + COLON = 258, + HEX = 259, + OBRACE = 260, + EBRACE = 261, + TAG_RSA = 262, + TAG_PUB = 263, + TAG_PSK = 264, + MODULUS = 265, + PUBLIC_EXPONENT = 266, + PRIVATE_EXPONENT = 267, + PRIME1 = 268, + PRIME2 = 269, + EXPONENT1 = 270, + EXPONENT2 = 271, + COEFFICIENT = 272, + ADDR4 = 273, + ADDR6 = 274, + ADDRANY = 275, + SLASH = 276, + NUMBER = 277, + BASE64 = 278 + }; +#endif +/* Tokens. */ +#define COLON 258 +#define HEX 259 +#define OBRACE 260 +#define EBRACE 261 +#define TAG_RSA 262 +#define TAG_PUB 263 +#define TAG_PSK 264 +#define MODULUS 265 +#define PUBLIC_EXPONENT 266 +#define PRIVATE_EXPONENT 267 +#define PRIME1 268 +#define PRIME2 269 +#define EXPONENT1 270 +#define EXPONENT2 271 +#define COEFFICIENT 272 +#define ADDR4 273 +#define ADDR6 274 +#define ADDRANY 275 +#define SLASH 276 +#define NUMBER 277 +#define BASE64 278 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 2049 of yacc.c */ +#line 130 "prsa_par.y" + + BIGNUM *bn; + RSA *rsa; + char *chr; + long num; + struct netaddr *naddr; + + +/* Line 2049 of yacc.c */ +#line 112 "prsa_par.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE prsalval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int prsaparse (void *YYPARSE_PARAM); +#else +int prsaparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int prsaparse (void); +#else +int prsaparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !PRSA_PRSA_PAR_H */ diff --git a/ipsec-tools/src/racoon/prsa_par.y b/ipsec-tools/src/racoon/prsa_par.y new file mode 100644 index 00000000..1987e4d4 --- /dev/null +++ b/ipsec-tools/src/racoon/prsa_par.y @@ -0,0 +1,363 @@ +/* $NetBSD: prsa_par.y,v 1.6 2011/03/02 14:49:21 vanhu Exp $ */ + +/* Id: prsa_par.y,v 1.3 2004/11/08 12:04:23 ludvigm Exp */ + +%{ +/* + * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. + * Contributed by: Michal Ludvig , SUSE Labs + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* This file contains a parser for FreeS/WAN-style ipsec.secrets RSA keys. */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#ifdef HAVE_STDARG_H +#include +#else +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "oakley.h" +#include "isakmp_var.h" +#include "handler.h" +#include "crypto_openssl.h" +#include "sockmisc.h" +#include "rsalist.h" + +extern void prsaerror(const char *str, ...); +extern int prsawrap (void); +extern int prsalex (void); + +extern char *prsatext; +extern int prsa_cur_lineno; +extern char *prsa_cur_fname; +extern FILE *prsain; + +int prsa_cur_lineno = 0; +char *prsa_cur_fname = NULL; +struct genlist *prsa_cur_list = NULL; +enum rsa_key_type prsa_cur_type = RSA_TYPE_ANY; + +static RSA *rsa_cur; + +void +prsaerror(const char *s, ...) +{ + char fmt[512]; + + va_list ap; +#ifdef HAVE_STDARG_H + va_start(ap, s); +#else + va_start(ap); +#endif + snprintf(fmt, sizeof(fmt), "%s:%d: %s", + prsa_cur_fname, prsa_cur_lineno, s); + plogv(LLV_ERROR, LOCATION, NULL, fmt, ap); + va_end(ap); +} + +void +prsawarning(const char *s, ...) +{ + char fmt[512]; + + va_list ap; +#ifdef HAVE_STDARG_H + va_start(ap, s); +#else + va_start(ap); +#endif + snprintf(fmt, sizeof(fmt), "%s:%d: %s", + prsa_cur_fname, prsa_cur_lineno, s); + plogv(LLV_WARNING, LOCATION, NULL, fmt, ap); + va_end(ap); +} + +int +prsawrap() +{ + return 1; +} +%} +%union { + BIGNUM *bn; + RSA *rsa; + char *chr; + long num; + struct netaddr *naddr; +} + +%token COLON HEX +%token OBRACE EBRACE COLON HEX +%token TAG_RSA TAG_PUB TAG_PSK +%token MODULUS PUBLIC_EXPONENT PRIVATE_EXPONENT +%token PRIME1 PRIME2 EXPONENT1 EXPONENT2 COEFFICIENT +%token ADDR4 ADDR6 ADDRANY SLASH NUMBER BASE64 + +%type HEX +%type NUMBER +%type ADDR4 ADDR6 BASE64 + +%type rsa_statement +%type prefix +%type addr4 addr6 addr + +%% +statements: + statements statement + | statement + ; + +statement: + addr addr COLON rsa_statement + { + rsa_key_insert(prsa_cur_list, $1, $2, $4); + } + | addr COLON rsa_statement + { + rsa_key_insert(prsa_cur_list, NULL, $1, $3); + } + | COLON rsa_statement + { + rsa_key_insert(prsa_cur_list, NULL, NULL, $2); + } + ; + +rsa_statement: + TAG_RSA OBRACE params EBRACE + { + if (prsa_cur_type == RSA_TYPE_PUBLIC) { + prsawarning("Using private key for public key purpose.\n"); + if (!rsa_cur->n || !rsa_cur->e) { + prsaerror("Incomplete key. Mandatory parameters are missing!\n"); + YYABORT; + } + } + else { + if (!rsa_cur->n || !rsa_cur->e || !rsa_cur->d) { + prsaerror("Incomplete key. Mandatory parameters are missing!\n"); + YYABORT; + } + if (!rsa_cur->p || !rsa_cur->q || !rsa_cur->dmp1 + || !rsa_cur->dmq1 || !rsa_cur->iqmp) { + if (rsa_cur->p) BN_clear_free(rsa_cur->p); + if (rsa_cur->q) BN_clear_free(rsa_cur->q); + if (rsa_cur->dmp1) BN_clear_free(rsa_cur->dmp1); + if (rsa_cur->dmq1) BN_clear_free(rsa_cur->dmq1); + if (rsa_cur->iqmp) BN_clear_free(rsa_cur->iqmp); + + rsa_cur->p = NULL; + rsa_cur->q = NULL; + rsa_cur->dmp1 = NULL; + rsa_cur->dmq1 = NULL; + rsa_cur->iqmp = NULL; + } + } + $$ = rsa_cur; + rsa_cur = RSA_new(); + } + | TAG_PUB BASE64 + { + if (prsa_cur_type == RSA_TYPE_PRIVATE) { + prsaerror("Public key in private-key file!\n"); + YYABORT; + } + $$ = base64_pubkey2rsa($2); + free($2); + } + | TAG_PUB HEX + { + if (prsa_cur_type == RSA_TYPE_PRIVATE) { + prsaerror("Public key in private-key file!\n"); + YYABORT; + } + $$ = bignum_pubkey2rsa($2); + } + ; + +addr: + addr4 + | addr6 + | ADDRANY + { + $$ = NULL; + } + ; + +addr4: + ADDR4 prefix + { + int err; + struct sockaddr_in *sap; + struct addrinfo hints, *res; + + if ($2 == -1) $2 = 32; + if ($2 < 0 || $2 > 32) { + prsaerror ("Invalid IPv4 prefix\n"); + YYABORT; + } + $$ = calloc (sizeof(struct netaddr), 1); + $$->prefix = $2; + sap = (struct sockaddr_in *)(&$$->sa); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_flags = AI_NUMERICHOST; + err = getaddrinfo($1, NULL, &hints, &res); + if (err < 0) { + prsaerror("getaddrinfo(%s): %s\n", $1, gai_strerror(err)); + YYABORT; + } + memcpy(sap, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + free($1); + } + ; + +addr6: + ADDR6 prefix + { + int err; + struct sockaddr_in6 *sap; + struct addrinfo hints, *res; + + if ($2 == -1) $2 = 128; + if ($2 < 0 || $2 > 128) { + prsaerror ("Invalid IPv6 prefix\n"); + YYABORT; + } + $$ = calloc (sizeof(struct netaddr), 1); + $$->prefix = $2; + sap = (struct sockaddr_in6 *)(&$$->sa); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + hints.ai_flags = AI_NUMERICHOST; + err = getaddrinfo($1, NULL, &hints, &res); + if (err < 0) { + prsaerror("getaddrinfo(%s): %s\n", $1, gai_strerror(err)); + YYABORT; + } + memcpy(sap, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + free($1); + } + ; + +prefix: + /* nothing */ { $$ = -1; } + | SLASH NUMBER { $$ = $2; } + ; +params: + params param + | param + ; + +param: + MODULUS COLON HEX + { if (!rsa_cur->n) rsa_cur->n = $3; else { prsaerror ("Modulus already defined\n"); YYABORT; } } + | PUBLIC_EXPONENT COLON HEX + { if (!rsa_cur->e) rsa_cur->e = $3; else { prsaerror ("PublicExponent already defined\n"); YYABORT; } } + | PRIVATE_EXPONENT COLON HEX + { if (!rsa_cur->d) rsa_cur->d = $3; else { prsaerror ("PrivateExponent already defined\n"); YYABORT; } } + | PRIME1 COLON HEX + { if (!rsa_cur->p) rsa_cur->p = $3; else { prsaerror ("Prime1 already defined\n"); YYABORT; } } + | PRIME2 COLON HEX + { if (!rsa_cur->q) rsa_cur->q = $3; else { prsaerror ("Prime2 already defined\n"); YYABORT; } } + | EXPONENT1 COLON HEX + { if (!rsa_cur->dmp1) rsa_cur->dmp1 = $3; else { prsaerror ("Exponent1 already defined\n"); YYABORT; } } + | EXPONENT2 COLON HEX + { if (!rsa_cur->dmq1) rsa_cur->dmq1 = $3; else { prsaerror ("Exponent2 already defined\n"); YYABORT; } } + | COEFFICIENT COLON HEX + { if (!rsa_cur->iqmp) rsa_cur->iqmp = $3; else { prsaerror ("Coefficient already defined\n"); YYABORT; } } + ; +%% + +int prsaparse(void); + +int +prsa_parse_file(struct genlist *list, char *fname, enum rsa_key_type type) +{ + FILE *fp = NULL; + int ret; + + if (!fname) + return -1; + if (type == RSA_TYPE_PRIVATE) { + struct stat st; + if (stat(fname, &st) < 0) + return -1; + if (st.st_mode & (S_IRWXG | S_IRWXO)) { + plog(LLV_ERROR, LOCATION, NULL, + "Too slack permissions on private key '%s'\n", + fname); + plog(LLV_ERROR, LOCATION, NULL, + "Should be at most 0600, now is 0%o\n", + st.st_mode & 0777); + return -1; + } + } + fp = fopen(fname, "r"); + if (!fp) + return -1; + prsain = fp; + prsa_cur_lineno = 1; + prsa_cur_fname = fname; + prsa_cur_list = list; + prsa_cur_type = type; + rsa_cur = RSA_new(); + ret = prsaparse(); + if (rsa_cur) { + RSA_free(rsa_cur); + rsa_cur = NULL; + } + fclose (fp); + prsain = NULL; + return ret; +} diff --git a/ipsec-tools/src/racoon/prsa_tok.c b/ipsec-tools/src/racoon/prsa_tok.c new file mode 100644 index 00000000..66dc2515 --- /dev/null +++ b/ipsec-tools/src/racoon/prsa_tok.c @@ -0,0 +1,2139 @@ +#line 2 "prsa_tok.c" + +#line 4 "prsa_tok.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer prsa_create_buffer +#define yy_delete_buffer prsa_delete_buffer +#define yy_flex_debug prsa_flex_debug +#define yy_init_buffer prsa_init_buffer +#define yy_flush_buffer prsa_flush_buffer +#define yy_load_buffer_state prsa_load_buffer_state +#define yy_switch_to_buffer prsa_switch_to_buffer +#define yyin prsain +#define yyleng prsaleng +#define yylex prsalex +#define yylineno prsalineno +#define yyout prsaout +#define yyrestart prsarestart +#define yytext prsatext +#define yywrap prsawrap +#define yyalloc prsaalloc +#define yyrealloc prsarealloc +#define yyfree prsafree + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 37 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE prsarestart(prsain ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t prsaleng; + +extern FILE *prsain, *prsaout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up prsatext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up prsatext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via prsarestart()), so that the user can continue scanning by + * just pointing prsain at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when prsatext is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t prsaleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow prsawrap()'s to do buffer switches + * instead of setting up a fresh prsain. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void prsarestart (FILE *input_file ); +void prsa_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE prsa_create_buffer (FILE *file,int size ); +void prsa_delete_buffer (YY_BUFFER_STATE b ); +void prsa_flush_buffer (YY_BUFFER_STATE b ); +void prsapush_buffer_state (YY_BUFFER_STATE new_buffer ); +void prsapop_buffer_state (void ); + +static void prsaensure_buffer_stack (void ); +static void prsa_load_buffer_state (void ); +static void prsa_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER prsa_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE prsa_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE prsa_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE prsa_scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *prsaalloc (yy_size_t ); +void *prsarealloc (void *,yy_size_t ); +void prsafree (void * ); + +#define yy_new_buffer prsa_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + prsaensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + prsa_create_buffer(prsain,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + prsaensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + prsa_create_buffer(prsain,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +typedef unsigned char YY_CHAR; + +FILE *prsain = (FILE *) 0, *prsaout = (FILE *) 0; + +typedef int yy_state_type; + +extern int prsalineno; + +int prsalineno = 1; + +extern char *prsatext; +#define yytext_ptr prsatext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up prsatext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + prsaleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 25 +#define YY_END_OF_BUFFER 26 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[194] = + { 0, + 22, 22, 26, 25, 22, 23, 24, 17, 18, 18, + 18, 18, 3, 25, 25, 25, 25, 25, 25, 25, + 1, 2, 22, 24, 0, 18, 21, 0, 0, 0, + 18, 18, 18, 21, 21, 21, 21, 21, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 18, 0, 21, 8, 7, 18, 0, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 0, 0, 0, 5, + 6, 0, 0, 4, 19, 0, 0, 0, 0, 18, + 0, 0, 0, 0, 21, 21, 0, 21, 21, 21, + 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 18, 0, 0, 0, 0, 21, 0, 0, 0, + 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 12, 13, 0, 0, 20, 20, 20, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, + 0, 20, 20, 20, 21, 21, 21, 0, 0, 0, + 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, + 21, 0, 14, 15, 0, 0, 21, 21, 21, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 10, 11, 0 + + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, + 1, 1, 5, 1, 1, 6, 7, 8, 9, 10, + 11, 11, 12, 13, 13, 13, 13, 14, 1, 1, + 5, 1, 1, 1, 15, 16, 17, 18, 19, 18, + 5, 5, 5, 5, 20, 5, 21, 5, 5, 22, + 5, 23, 24, 5, 25, 5, 5, 5, 5, 5, + 1, 1, 1, 1, 1, 1, 26, 27, 28, 29, + + 30, 31, 5, 5, 32, 5, 5, 33, 34, 35, + 36, 37, 5, 38, 39, 40, 41, 42, 5, 43, + 44, 5, 45, 1, 46, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[47] = + { 0, + 1, 1, 2, 1, 3, 4, 3, 5, 5, 5, + 5, 5, 5, 6, 7, 7, 7, 7, 7, 3, + 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, + 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[213] = + { 0, + 0, 0, 674, 675, 671, 675, 0, 675, 41, 22, + 77, 65, 113, 122, 636, 628, 634, 54, 645, 633, + 675, 675, 665, 0, 88, 130, 154, 163, 0, 0, + 0, 653, 94, 171, 100, 142, 195, 204, 635, 627, + 634, 642, 645, 628, 632, 643, 613, 650, 212, 649, + 220, 246, 0, 0, 0, 648, 183, 254, 280, 0, + 640, 646, 288, 232, 266, 314, 620, 614, 608, 675, + 675, 49, 615, 675, 675, 300, 641, 322, 640, 631, + 630, 637, 329, 636, 123, 164, 335, 343, 369, 0, + 628, 634, 608, 603, 604, 606, 609, 602, 627, 377, + + 626, 355, 383, 625, 391, 624, 615, 622, 398, 621, + 205, 247, 594, 595, 583, 53, 583, 594, 404, 615, + 412, 614, 613, 419, 612, 425, 577, 433, 574, 550, + 533, 482, 675, 675, 448, 452, 438, 444, 450, 456, + 434, 464, 420, 413, 471, 399, 366, 344, 675, 357, + 307, 477, 483, 675, 488, 494, 500, 506, 330, 514, + 323, 291, 72, 252, 250, 519, 525, 675, 530, 536, + 542, 244, 675, 675, 190, 119, 548, 554, 675, 79, + 82, 82, 675, 80, 84, 64, 58, 31, 24, 8, + 675, 675, 675, 566, 569, 574, 577, 580, 584, 586, + + 587, 590, 592, 594, 598, 600, 602, 604, 606, 608, + 610, 612 + } ; + +static yyconst flex_int16_t yy_def[213] = + { 0, + 193, 1, 193, 193, 193, 193, 194, 193, 193, 9, + 9, 11, 195, 11, 14, 14, 193, 193, 193, 14, + 193, 193, 193, 194, 193, 193, 195, 26, 196, 197, + 26, 26, 26, 193, 34, 35, 198, 35, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 199, 193, 200, + 193, 51, 27, 196, 197, 51, 193, 193, 58, 58, + 58, 59, 193, 63, 64, 64, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 200, 193, 193, 201, + 193, 202, 193, 203, 204, 204, 193, 193, 88, 88, + 88, 89, 193, 193, 193, 193, 193, 193, 205, 193, + + 206, 193, 193, 203, 193, 193, 193, 207, 193, 208, + 204, 204, 193, 193, 193, 193, 193, 193, 193, 206, + 193, 193, 209, 193, 210, 193, 208, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 210, 193, 193, 211, 193, 212, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 212, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 0, 193, 193, 193, 193, 193, 193, 193, + + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193 + } ; + +static yyconst flex_int16_t yy_nxt[722] = + { 0, + 4, 5, 6, 7, 4, 4, 8, 9, 10, 11, + 12, 12, 12, 13, 14, 14, 15, 14, 16, 4, + 17, 18, 19, 4, 4, 20, 14, 14, 14, 14, + 14, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 21, 22, 25, 192, 26, 26, + 26, 26, 26, 26, 27, 28, 28, 28, 28, 28, + 193, 133, 134, 191, 193, 190, 28, 28, 28, 28, + 28, 28, 33, 33, 33, 33, 33, 42, 43, 29, + 173, 174, 96, 30, 31, 31, 31, 31, 32, 33, + 97, 44, 189, 188, 45, 48, 48, 49, 50, 50, + + 50, 56, 56, 56, 56, 56, 56, 60, 60, 60, + 60, 61, 62, 187, 186, 193, 185, 184, 183, 193, + 34, 34, 35, 36, 36, 36, 37, 193, 57, 28, + 28, 28, 28, 28, 28, 25, 27, 51, 51, 51, + 51, 51, 51, 27, 52, 52, 52, 52, 52, 62, + 62, 62, 62, 62, 182, 52, 52, 52, 52, 52, + 52, 34, 34, 35, 36, 36, 36, 53, 193, 193, + 52, 52, 52, 52, 52, 52, 57, 27, 58, 58, + 58, 58, 58, 58, 27, 59, 59, 59, 59, 59, + 82, 82, 83, 84, 84, 84, 59, 59, 59, 59, + + 59, 59, 63, 63, 64, 65, 65, 65, 53, 193, + 87, 59, 59, 59, 59, 59, 59, 76, 27, 77, + 77, 77, 77, 78, 79, 25, 181, 80, 80, 80, + 80, 80, 80, 27, 81, 81, 81, 81, 81, 90, + 90, 90, 90, 91, 92, 81, 81, 81, 81, 81, + 81, 193, 193, 81, 81, 81, 81, 81, 81, 57, + 27, 85, 85, 85, 85, 85, 85, 27, 86, 86, + 86, 86, 86, 92, 92, 92, 92, 92, 180, 86, + 86, 86, 86, 86, 86, 193, 176, 86, 86, 86, + 86, 86, 86, 87, 175, 88, 88, 88, 88, 88, + + 88, 27, 89, 89, 89, 89, 89, 99, 99, 100, + 101, 101, 101, 89, 89, 89, 89, 89, 89, 193, + 172, 89, 89, 89, 89, 89, 89, 76, 158, 79, + 79, 79, 79, 79, 103, 158, 104, 104, 104, 104, + 105, 106, 108, 108, 109, 110, 110, 110, 87, 165, + 111, 111, 111, 111, 111, 111, 27, 112, 112, 112, + 112, 112, 102, 102, 102, 102, 102, 102, 112, 112, + 112, 112, 112, 112, 193, 164, 112, 112, 112, 112, + 112, 112, 119, 163, 120, 120, 120, 120, 121, 122, + 123, 123, 124, 125, 125, 125, 103, 162, 106, 106, + + 106, 106, 106, 126, 158, 127, 127, 127, 127, 128, + 129, 137, 137, 138, 139, 139, 139, 119, 158, 122, + 122, 122, 122, 122, 140, 140, 141, 141, 141, 141, + 142, 143, 144, 144, 145, 146, 146, 146, 126, 140, + 129, 129, 129, 129, 129, 139, 139, 139, 139, 139, + 139, 152, 152, 152, 152, 153, 154, 154, 154, 154, + 154, 154, 154, 155, 155, 156, 157, 157, 157, 140, + 151, 143, 143, 143, 143, 143, 158, 150, 159, 159, + 159, 159, 160, 161, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 157, 157, 157, 157, 157, + + 157, 166, 166, 166, 166, 167, 168, 168, 168, 168, + 168, 168, 168, 169, 169, 170, 171, 171, 171, 158, + 149, 161, 161, 161, 161, 161, 168, 168, 168, 168, + 168, 168, 168, 168, 168, 168, 168, 171, 171, 171, + 171, 171, 171, 177, 177, 177, 177, 178, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 24, 148, 24, 24, + 24, 24, 24, 38, 38, 38, 54, 147, 54, 126, + 54, 55, 126, 55, 66, 66, 66, 50, 50, 79, + 79, 102, 102, 84, 84, 106, 106, 107, 107, 107, + + 107, 101, 101, 122, 122, 110, 110, 129, 129, 125, + 125, 143, 143, 146, 146, 161, 161, 140, 140, 119, + 119, 136, 135, 132, 131, 130, 126, 126, 27, 103, + 103, 119, 119, 118, 117, 116, 115, 114, 113, 87, + 112, 103, 103, 27, 27, 76, 76, 98, 95, 94, + 93, 57, 86, 193, 76, 76, 75, 74, 73, 72, + 71, 70, 69, 68, 67, 56, 23, 47, 46, 41, + 40, 39, 23, 193, 3, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193 + } ; + +static yyconst flex_int16_t yy_chk[722] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 9, 190, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 10, 116, 116, 189, 10, 188, 9, 9, 9, 9, + 9, 9, 12, 12, 12, 12, 12, 18, 18, 9, + 163, 163, 72, 9, 11, 11, 11, 11, 11, 11, + 72, 18, 187, 186, 18, 25, 25, 25, 25, 25, + + 25, 33, 33, 33, 33, 33, 33, 35, 35, 35, + 35, 35, 35, 185, 184, 11, 182, 181, 180, 11, + 13, 13, 13, 13, 13, 13, 13, 14, 85, 14, + 14, 14, 14, 14, 14, 26, 85, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 36, + 36, 36, 36, 36, 176, 26, 26, 26, 26, 26, + 26, 27, 27, 27, 27, 27, 27, 27, 28, 86, + 28, 28, 28, 28, 28, 28, 34, 86, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 57, 57, 57, 57, 57, 57, 34, 34, 34, 34, + + 34, 34, 37, 37, 37, 37, 37, 37, 37, 38, + 111, 38, 38, 38, 38, 38, 38, 49, 111, 49, + 49, 49, 49, 49, 49, 51, 175, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 64, + 64, 64, 64, 64, 64, 51, 51, 51, 51, 51, + 51, 52, 112, 52, 52, 52, 52, 52, 52, 58, + 112, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 65, 65, 65, 65, 65, 172, 58, + 58, 58, 58, 58, 58, 59, 165, 59, 59, 59, + 59, 59, 59, 63, 164, 63, 63, 63, 63, 63, + + 63, 63, 63, 63, 63, 63, 63, 76, 76, 76, + 76, 76, 76, 63, 63, 63, 63, 63, 63, 66, + 162, 66, 66, 66, 66, 66, 66, 78, 161, 78, + 78, 78, 78, 78, 83, 159, 83, 83, 83, 83, + 83, 83, 87, 87, 87, 87, 87, 87, 88, 151, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 102, 102, 102, 102, 102, 102, 88, 88, + 88, 88, 88, 88, 89, 150, 89, 89, 89, 89, + 89, 89, 100, 148, 100, 100, 100, 100, 100, 100, + 103, 103, 103, 103, 103, 103, 105, 147, 105, 105, + + 105, 105, 105, 109, 146, 109, 109, 109, 109, 109, + 109, 119, 119, 119, 119, 119, 119, 121, 144, 121, + 121, 121, 121, 121, 124, 143, 124, 124, 124, 124, + 124, 124, 126, 126, 126, 126, 126, 126, 128, 141, + 128, 128, 128, 128, 128, 137, 137, 137, 137, 137, + 137, 138, 138, 138, 138, 138, 138, 139, 139, 139, + 139, 139, 139, 140, 140, 140, 140, 140, 140, 142, + 136, 142, 142, 142, 142, 142, 145, 135, 145, 145, + 145, 145, 145, 145, 152, 152, 152, 152, 152, 152, + 153, 153, 153, 153, 153, 155, 155, 155, 155, 155, + + 155, 156, 156, 156, 156, 156, 156, 157, 157, 157, + 157, 157, 157, 158, 158, 158, 158, 158, 158, 160, + 132, 160, 160, 160, 160, 160, 166, 166, 166, 166, + 166, 166, 167, 167, 167, 167, 167, 169, 169, 169, + 169, 169, 169, 170, 170, 170, 170, 170, 170, 171, + 171, 171, 171, 171, 171, 177, 177, 177, 177, 177, + 177, 178, 178, 178, 178, 178, 194, 131, 194, 194, + 194, 194, 194, 195, 195, 195, 196, 130, 196, 129, + 196, 197, 127, 197, 198, 198, 198, 199, 199, 200, + 200, 201, 201, 202, 202, 203, 203, 204, 204, 204, + + 204, 205, 205, 206, 206, 207, 207, 208, 208, 209, + 209, 210, 210, 211, 211, 212, 212, 125, 123, 122, + 120, 118, 117, 115, 114, 113, 110, 108, 107, 106, + 104, 101, 99, 98, 97, 96, 95, 94, 93, 92, + 91, 84, 82, 81, 80, 79, 77, 73, 69, 68, + 67, 62, 61, 56, 50, 48, 47, 46, 45, 44, + 43, 42, 41, 40, 39, 32, 23, 20, 19, 17, + 16, 15, 5, 3, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int prsa_flex_debug; +int prsa_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *prsatext; +#line 1 "prsa_tok.l" +/* $NetBSD: prsa_tok.l,v 1.4 2006/09/09 16:22:10 manu Exp $ */ +/* Id: prsa_tok.l,v 1.2 2004/07/12 20:43:51 ludvigm Exp */ +#line 6 "prsa_tok.l" +/* + * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. + * Contributed by: Michal Ludvig , SUSE Labs + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* This file contains a tokeniser for FreeS/WAN-style ipsec.secrets RSA keys. */ + +#include +#include +#include +#include "prsa_par.h" + +extern int prsalex (void); +extern int prsa_cur_lineno; + +#line 742 "prsa_tok.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int prsalex_destroy (void ); + +int prsaget_debug (void ); + +void prsaset_debug (int debug_flag ); + +YY_EXTRA_TYPE prsaget_extra (void ); + +void prsaset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *prsaget_in (void ); + +void prsaset_in (FILE * in_str ); + +FILE *prsaget_out (void ); + +void prsaset_out (FILE * out_str ); + +yy_size_t prsaget_leng (void ); + +char *prsaget_text (void ); + +int prsaget_lineno (void ); + +void prsaset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int prsawrap (void ); +#else +extern int prsawrap (void ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( prsatext, prsaleng, 1, prsaout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( prsain )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( prsain ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, prsain))==0 && ferror(prsain)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(prsain); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int prsalex (void); + +#define YY_DECL int prsalex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after prsatext and prsaleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 56 "prsa_tok.l" + +#line 926 "prsa_tok.c" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! prsain ) + prsain = stdin; + + if ( ! prsaout ) + prsaout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + prsaensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + prsa_create_buffer(prsain,YY_BUF_SIZE ); + } + + prsa_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of prsatext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 194 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 675 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 57 "prsa_tok.l" +{ return OBRACE; } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 58 "prsa_tok.l" +{ return EBRACE; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 59 "prsa_tok.l" +{ return COLON; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 60 "prsa_tok.l" +{ return TAG_RSA; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 61 "prsa_tok.l" +{ return TAG_PSK; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 62 "prsa_tok.l" +{ return TAG_PUB; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 63 "prsa_tok.l" +{ + BIGNUM *bn = BN_new(); + BN_hex2bn(&bn, prsatext+2); + prsalval.bn = bn; + return HEX; + } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 69 "prsa_tok.l" +{ + prsalval.chr = strdup(prsatext); + return BASE64; + } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 73 "prsa_tok.l" +{ return MODULUS; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 74 "prsa_tok.l" +{ return PUBLIC_EXPONENT; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 75 "prsa_tok.l" +{ return PRIVATE_EXPONENT; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 76 "prsa_tok.l" +{ return PRIME1; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 77 "prsa_tok.l" +{ return PRIME2; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 78 "prsa_tok.l" +{ return EXPONENT1; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 79 "prsa_tok.l" +{ return EXPONENT2; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 80 "prsa_tok.l" +{ return COEFFICIENT; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 81 "prsa_tok.l" +{ return SLASH; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 82 "prsa_tok.l" +{ prsalval.num = atol(prsatext); return NUMBER; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 83 "prsa_tok.l" +{ return ADDRANY; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 84 "prsa_tok.l" +{ prsalval.chr = strdup(prsatext); return ADDR4; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 85 "prsa_tok.l" +{ prsalval.chr = strdup(prsatext); return ADDR6; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 86 "prsa_tok.l" +; + YY_BREAK +case 23: +/* rule 23 can match eol */ +YY_RULE_SETUP +#line 87 "prsa_tok.l" +{ prsa_cur_lineno++; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 88 "prsa_tok.l" +; + YY_BREAK +case 25: +YY_RULE_SETUP +#line 89 "prsa_tok.l" +ECHO; + YY_BREAK +#line 1143 "prsa_tok.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed prsain at a new source and called + * prsalex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = prsain; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( prsawrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * prsatext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of prsalex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + prsarealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + prsarestart(prsain ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) prsarealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 194 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 194 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 193); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up prsatext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register yy_size_t number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + prsarestart(prsain ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( prsawrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve prsatext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void prsarestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + prsaensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + prsa_create_buffer(prsain,YY_BUF_SIZE ); + } + + prsa_init_buffer(YY_CURRENT_BUFFER,input_file ); + prsa_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void prsa_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * prsapop_buffer_state(); + * prsapush_buffer_state(new_buffer); + */ + prsaensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + prsa_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (prsawrap()) processing, but the only time this flag + * is looked at is after prsawrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void prsa_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + prsain = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE prsa_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) prsaalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in prsa_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) prsaalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in prsa_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + prsa_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with prsa_create_buffer() + * + */ + void prsa_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + prsafree((void *) b->yy_ch_buf ); + + prsafree((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a prsarestart() or at EOF. + */ + static void prsa_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + prsa_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then prsa_init_buffer was _probably_ + * called from prsarestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void prsa_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + prsa_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void prsapush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + prsaensure_buffer_stack(); + + /* This block is copied from prsa_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from prsa_switch_to_buffer. */ + prsa_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void prsapop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + prsa_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + prsa_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void prsaensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)prsaalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in prsaensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)prsarealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in prsaensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE prsa_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) prsaalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in prsa_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + prsa_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to prsalex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * prsa_scan_bytes() instead. + */ +YY_BUFFER_STATE prsa_scan_string (yyconst char * yystr ) +{ + + return prsa_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to prsalex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE prsa_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) prsaalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in prsa_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = prsa_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in prsa_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up prsatext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + prsatext[prsaleng] = (yy_hold_char); \ + (yy_c_buf_p) = prsatext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + prsaleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int prsaget_lineno (void) +{ + + return prsalineno; +} + +/** Get the input stream. + * + */ +FILE *prsaget_in (void) +{ + return prsain; +} + +/** Get the output stream. + * + */ +FILE *prsaget_out (void) +{ + return prsaout; +} + +/** Get the length of the current token. + * + */ +yy_size_t prsaget_leng (void) +{ + return prsaleng; +} + +/** Get the current token. + * + */ + +char *prsaget_text (void) +{ + return prsatext; +} + +/** Set the current line number. + * @param line_number + * + */ +void prsaset_lineno (int line_number ) +{ + + prsalineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see prsa_switch_to_buffer + */ +void prsaset_in (FILE * in_str ) +{ + prsain = in_str ; +} + +void prsaset_out (FILE * out_str ) +{ + prsaout = out_str ; +} + +int prsaget_debug (void) +{ + return prsa_flex_debug; +} + +void prsaset_debug (int bdebug ) +{ + prsa_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from prsalex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + prsain = stdin; + prsaout = stdout; +#else + prsain = (FILE *) 0; + prsaout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * prsalex_init() + */ + return 0; +} + +/* prsalex_destroy is for both reentrant and non-reentrant scanners. */ +int prsalex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + prsa_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + prsapop_buffer_state(); + } + + /* Destroy the stack itself. */ + prsafree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * prsalex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *prsaalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *prsarealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void prsafree (void * ptr ) +{ + free( (char *) ptr ); /* see prsarealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 89 "prsa_tok.l" + + + diff --git a/ipsec-tools/src/racoon/prsa_tok.l b/ipsec-tools/src/racoon/prsa_tok.l new file mode 100644 index 00000000..83e3d141 --- /dev/null +++ b/ipsec-tools/src/racoon/prsa_tok.l @@ -0,0 +1,89 @@ +/* $NetBSD: prsa_tok.l,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: prsa_tok.l,v 1.2 2004/07/12 20:43:51 ludvigm Exp */ + +%{ +/* + * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. + * Contributed by: Michal Ludvig , SUSE Labs + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* This file contains a tokeniser for FreeS/WAN-style ipsec.secrets RSA keys. */ + +#include +#include +#include +#include "prsa_par.h" + +extern int prsalex (void); +extern int prsa_cur_lineno; + +%} + +comment \#.* +digit [0-9] +octet (([01]?{digit}?{digit})|((2([0-4]{digit}))|(25[0-5]))) +addr4 {octet}\.{octet}\.{octet}\.{octet} +hex [0-9a-fA-F] +word6 {hex}{0,4} +base64 [A-Za-z0-9+/=] +addr6 (::({word6}|{addr4})?|({word6}:)+:?({word6}|{addr4})?) +%% +\{ { return OBRACE; } +\} { return EBRACE; } +: { return COLON; } +RSA { return TAG_RSA; } +PSK { return TAG_PSK; } +PUB { return TAG_PUB; } +0x[0-9a-fA-F]+ { + BIGNUM *bn = BN_new(); + BN_hex2bn(&bn, prsatext+2); + prsalval.bn = bn; + return HEX; + } +0s{base64}+ { + prsalval.chr = strdup(prsatext); + return BASE64; + } +Modulus { return MODULUS; } +PublicExponent { return PUBLIC_EXPONENT; } +PrivateExponent { return PRIVATE_EXPONENT; } +Prime1 { return PRIME1; } +Prime2 { return PRIME2; } +Exponent1 { return EXPONENT1; } +Exponent2 { return EXPONENT2; } +Coefficient { return COEFFICIENT; } +\/ { return SLASH; } +{digit}+ { prsalval.num = atol(prsatext); return NUMBER; } +any { return ADDRANY; } +{addr4} { prsalval.chr = strdup(prsatext); return ADDR4; } +{addr6} { prsalval.chr = strdup(prsatext); return ADDR6; } +[ \t]* ; +\n { prsa_cur_lineno++; } +\#.* ; +%% diff --git a/ipsec-tools/src/racoon/racoon.8 b/ipsec-tools/src/racoon/racoon.8 new file mode 100644 index 00000000..58fefdd8 --- /dev/null +++ b/ipsec-tools/src/racoon/racoon.8 @@ -0,0 +1,157 @@ +.\" $NetBSD: racoon.8,v 1.12 2009/01/24 10:42:31 wiz Exp $ +.\" +.\" Id: racoon.8,v 1.4 2005/04/18 11:07:55 manubsd Exp +.\" +.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the project nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd January 23, 2009 +.Dt RACOON 8 +.Os +.\" +.Sh NAME +.Nm racoon +.Nd IKE (ISAKMP/Oakley) key management daemon +.\" +.Sh SYNOPSIS +.Nm racoon +.Bk -words +.Op Fl 46BdFLVv +.Ek +.Bk -words +.Op Fl f Ar configfile +.Ek +.Bk -words +.Op Fl l Ar logfile +.Ek +.Bk -words +.Op Fl P Ar isakmp-natt-port +.Ek +.Bk -words +.Op Fl p Ar isakmp-port +.Ek +.\" +.Sh DESCRIPTION +.Nm +speaks the IKE +.Pq ISAKMP/Oakley +key management protocol, +to establish security associations with other hosts. +The SPD +.Pq Security Policy Database +in the kernel usually triggers +.Nm . +.Nm +usually sends all informational messages, warnings and error messages to +.Xr syslogd 8 +with the facility +.Dv LOG_DAEMON +and the priority +.Dv LOG_INFO . +Debugging messages are sent with the priority +.Dv LOG_DEBUG . +You should configure +.Xr syslog.conf 5 +appropriately to see these messages. +.Bl -tag -width Ds +.It Fl 4 +.It Fl 6 +Specify the default address family for the sockets. +.It Fl B +Install SA(s) from the file which is specified in +.Xr racoon.conf 5 . +.It Fl d +Increase the debug level. +Multiple +.Fl d +arguments will increase the debug level even more. +.It Fl F +Run +.Nm +in the foreground. +.It Fl f Ar configfile +Use +.Ar configfile +as the configuration file instead of the default. +.It Fl L +Include +.Ar file_name:line_number:function_name +in all messages. +.It Fl l Ar logfile +Use +.Ar logfile +as the logging file instead of +.Xr syslogd 8 . +.It Fl P Ar isakmp-natt-port +Use +.Ar isakmp-natt-port +for NAT-Traversal port-floating. +The default is 4500. +.It Fl p Ar isakmp-port +Listen to the ISAKMP key exchange on port +.Ar isakmp-port +instead of the default port number, 500. +.It Fl V +Print racoon version and compilation options and exit. +.It Fl v +This flag causes the packet dump be more verbose, with higher +debugging level. +.El +.Pp +.Nm +assumes the presence of the kernel random number device +.Xr rnd 4 +at +.Pa /dev/urandom . +.\" +.Sh RETURN VALUES +The command exits with 0 on success, and non-zero on errors. +.\" +.Sh FILES +.Bl -tag -width /etc/racoon.conf -compact +.It Pa /etc/racoon.conf +default configuration file. +.El +.\" +.Sh SEE ALSO +.Xr ipsec 4 , +.Xr racoon.conf 5 , +.Xr syslog.conf 5 , +.Xr setkey 8 , +.Xr syslogd 8 +.\" +.Sh HISTORY +The +.Nm +command first appeared in the +.Dq YIPS +Yokogawa IPsec implementation. +.\" +.Sh SECURITY CONSIDERATIONS +The use of IKE phase 1 aggressive mode is not recommended, +as described in +.Pa http://www.kb.cert.org/vuls/id/886601 . diff --git a/ipsec-tools/src/racoon/racoon.conf.5 b/ipsec-tools/src/racoon/racoon.conf.5 new file mode 100644 index 00000000..21e499b8 --- /dev/null +++ b/ipsec-tools/src/racoon/racoon.conf.5 @@ -0,0 +1,1546 @@ +.\" $NetBSD: racoon.conf.5,v 1.61.4.1 2012/08/29 08:42:24 tteras Exp $ +.\" +.\" Id: racoon.conf.5,v 1.54 2006/08/22 18:17:17 manubsd Exp +.\" +.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the project nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd August 29, 2012 +.Dt RACOON.CONF 5 +.Os +.\" +.Sh NAME +.Nm racoon.conf +.Nd configuration file for racoon +.\" +.\" .Sh SYNOPSIS +.\" +.Sh DESCRIPTION +.Nm +is the configuration file for the +.Xr racoon 8 +ISAKMP daemon. +.Xr racoon 8 +negotiates security associations for itself (ISAKMP SA, or phase 1 SA) +and for kernel IPsec (IPsec SA, or phase 2 SA). +The file consists of a sequence of directives and statements. +Each directive is composed by a tag and statements, enclosed by +.Ql { +and +.Ql } . +Lines beginning with +.Ql # +are comments. +.\" +.Ss Meta Syntax +Keywords and special characters that the parser expects exactly are +displayed using +.Ic this +font. +Parameters are specified with +.Ar this +font. +Square brackets +.Po +.Ql \&[ +and +.Ql \&] +.Pc +are used to show optional keywords and parameters. +Note that +you have to pay attention when this manual is describing +.Ar port +numbers. +The +.Ar port +number is always enclosed by +.Ql \&[ +and +.Ql \&] . +In this case, the port number is not an optional keyword. +If it is possible to omit the +.Ar port +number, +the expression becomes +.Bq Bq Ar port . +The vertical bar +.Pq Ql \&| +is used to indicate +a choice between optional parameters. +Parentheses +.Po +.Ql \&( +and +.Ql \&) +.Pc +are used to group keywords and parameters when necessary. +Major parameters are listed below. +.Pp +.Bl -tag -width addressx -compact +.It Ar number +means a hexadecimal or a decimal number. +The former must be prefixed with +.Ql Li 0x . +.It Ar string +.It Ar path +.It Ar file +means any string enclosed in +.Ql \&" +.Pq double quotes . +.It Ar address +means IPv6 and/or IPv4 address. +.It Ar port +means a TCP/UDP port number. +The port number is always enclosed by +.Ql \&[ +and +.Ql \&] . +.It Ar timeunit +is one of following: +.Ic sec , secs , second , seconds , +.Ic min , mins , minute , minutes , +.Ic hour , hours . +.El +.\" +.Ss Privilege separation +.Bl -tag -width Ds -compact +.It Ic privsep { Ar statements Ic } +Specifies privilege separation parameters. +When enabled, these enable +.Xr racoon 8 +to operate with an unprivileged instance doing most of the work, while +a privileged instance takes care of performing the following operations +as root: reading PSK and private keys, launching hook scripts, and +validating passwords against system databases or against PAM. +Please note that using privilege separation makes changes to the +.Ar listen +and +.Ar paths +sections ignored upon configuration reloads. +A +.Xr racoon 8 +restart is required if you want such changes to be taken into account. +.Pp +.Bl -tag -width Ds -compact +.It Ic user Ar user ; +The user to which the unprivileged instance of +.Xr racoon 8 , +should switch. +This can be a quoted user name or a numeric UID. +.It Ic group Ar group ; +The group the unprivileged instance of +.Xr racoon 8 , +should switch. +This can be a quoted group name or a numeric GID. +.It Ic chroot Ar path ; +A directory to which the unprivileged instance of +.Xr racoon 8 +should +.Xr chroot 2 . +This directory should hold a tree where the following files must be +reachable: +.Bl -tag -width Ds -compact +.It Pa /dev/random +.It Pa /dev/urandom +.It The certificates +.It The file containing the Xauth banner +.El +.Pp +The PSK file, the private keys, and the hook scripts are accessed through the +privileged instance of +.Xr racoon 8 +and do not need to be reachable in the +.Xr chroot 2 Ap ed +tree. +.El +.El +.Ss Path Specification +This section specifies various paths used by racoon. +When running in privilege separation mode, +.Ic certificate +and +.Ic script +paths are mandatory. +A +.Xr racoon 8 +restart is required if you want path changes to be taken into account. +.Bl -tag -width Ds -compact +.It Ic path include Ar path ; +Specifies a path to include a file. +See +.Sx File Inclusion . +.It Ic path pre_shared_key Ar file ; +Specifies a file containing pre-shared key(s) for various ID(s). +See +.Sx Pre-shared key File . +.It Ic path certificate Ar path ; +.Xr racoon 8 +will search this directory if a certificate or certificate request is received. +If you run with privilege separation, +.Xr racoon 8 +will refuse to use a certificate stored outside of this directory. +.It Ic path backupsa Ar file ; +Specifies a file to which SA information negotiated by +racoon should be stored. +.Xr racoon 8 +will install SA(s) from the file when started with the +.Fl B +flag. +The file is growing because +.Xr racoon 8 +simply adds SAs to it. +You should maintain the file manually. +.It Ic path script Ar path ; +.Xr racoon 8 +will search this directory for scripts hooks. +If you run with privilege separation, +.Xr racoon 8 +will refuse to execute a script stored outside of this directory. +.It Ic path pidfile Ar file ; +Specifies file where to store PID of process. +If path starts with +.Pa / +it is treated as an absolute path. +Otherwise, it is treated as a relative +path to the VARRUN directory specified at compilation time. +Default is +.Pa racoon.pid . +.El +.\" +.Ss File Inclusion +.Bl -tag -width Ds -compact +.It Ic include Ar file +Specifies other configuration files to be included. +.El +.\" +.Ss Timer Specification +.Bl -tag -width Ds -compact +.It Ic timer { Ar statements Ic } +This section specifies various timer values used by racoon. +.Pp +.Bl -tag -width Ds -compact +.It Ic counter Ar number ; +The maximum number of retries to send. +The default is 5. +.It Ic interval Ar number Ar timeunit ; +The interval to resend, in seconds. +The default time is 10 seconds. +.It Ic persend Ar number ; +The number of packets per send. +The default is 1. +.It Ic phase1 Ar number Ar timeunit ; +The maximum time it should take to complete phase 1. +The default time is 15 seconds. +.It Ic phase2 Ar number Ar timeunit ; +The maximum time it should take to complete phase 2. +The default time is 10 seconds. +.It Ic natt_keepalive Ar number Ar timeunit ; +The interval between sending NAT-Traversal keep-alive packets. +The default time is 20 seconds. +Set to 0s to disable keep-alive packets. +.El +.El +.\" +.Ss Listening Port Specification +.Bl -tag -width Ds -compact +.It Ic listen { Ar statements Ic } +If no +.Ar listen +directive is specified, +.Xr racoon 8 +will listen on all available interface addresses. +The following is the list of valid statements: +.Pp +.Bl -tag -width Ds -compact +.\" How do I express bold brackets; `[' and `]' . +.\" Answer: For bold brackets, do "Ic \&[ foo \&]". +.\" Is the "Bq Ic [ Ar port ] ;" buggy ? +.It Ic isakmp Ar address Bq Bq Ar port ; +If this is specified, +.Xr racoon 8 +will only listen on the defined +.Ar address . +The default port is 500, which is specified by IANA. +You can provide more than one address definition. +.It Ic isakmp_natt Ar address Bq Ar port ; +Same as +.Ic isakmp +but also sets the socket options to accept UDP-encapsulated ESP traffic for +NAT-Traversal. +If you plan to use NAT-T, you should provide at least one address +with port 4500, which is specified by IANA. +There is no default. +.It Ic strict_address ; +Requires that all addresses for ISAKMP be bound. +This statement will be ignored if you do not specify address definitions. +.El +When running in privilege separation mode, you need to restart +.Xr racoon 8 +to have changes to the +.Ar listen +section taken into account. +.Pp +The +.Ar listen +section can also be used to specify the admin socket mode and ownership +if racoon was built with support for admin port. +.Bl -tag -width Ds -compact +.It Ic adminsock Ar path Op Ar owner\ group\ mode ; +The +.Ar path , +.Ar owner , +and +.Ar group +values specify the socket path, owner, and group. +They must be quoted. +The defaults are +.Pa /var/racoon/racoon.sock , +UID 0, and GID 0. +.Ar mode +is the access mode in octal. +The default is 0600. +.It Ic adminsock disabled ; +This directive tells racoon to not listen on the admin socket. +.El +.El +.\" +.Ss Miscellaneous Global Parameters +.Bl -tag -width Ds -compact +.It Ic gss_id_enc Ar enctype ; +Older versions of +.Xr racoon 8 +used ISO-Latin-1 as the encoding of the GSS-API identifier attribute. +For interoperability with Microsoft Windows' GSS-API authentication +scheme, the default encoding has been changed to UTF-16LE. +The +.Ic gss_id_enc +parameter allows +.Xr racoon 8 +to be configured to use the old encoding for compatibility with existing +.Xr racoon 8 +installations. +The following are valid values for +.Ar enctype : +.Pp +.Bl -tag -width Ds -compact +.It Ic utf-16le +Use UTF-16LE to encode the GSS-API identifier attribute. +This is the default encoding. +This encoding is compatible with Microsoft Windows. +.It Ic latin1 +Use ISO-Latin-1 to encode the GSS-API identifier attribute. +This is the encoding used by older versions of +.Xr racoon 8 . +.El +.El +.\" +.Pp +.Bl -tag -width Ds -compact +.It Ic pfkey_buffer Ar kBytes +Specifies the socket send/receive buffer size in kilobytes. +Numerous kernel PF_KEY implementations have problems with dumping +SAD/SDP with large amount of entries (this happens when 100s to +1000s of tunnels are configured). +.Pp +The default value of 0 leaves everything at the OS-specific default value. +If the default buffer size is greater than what is specified here racoon +will not decrease it. +.Pp +This problem is known to be fixed in Linux 2.6.25 and later. +.El +.\" +.Ss Remote Nodes Specifications +.Bl -tag -width Ds -compact +.It Ic remote Ar name Bo Ic inherit Ar parent_name Bc Ic ({ Ar statements Ic } | ;) +Specifies the IKE phase 1 parameters for each remote node. +.Pp +If connection is initiated using racoonctl, a unique match using the +remote IP must be found or the remote block name has to be given. +For received acquires (kernel notices traffic requiring a new SA) the +remote IP and remoteid from matching sainfo block are used to decide +the remoteblock. +If no uniquely matching remoteblock is found using +these criteria, no connection attempt is done. +.Pp +When acting as responder, racoon picks the first proposal that has one +or more acceptable remote configurations. +When determining if a remote +specification is matching the following information is checked: +.Bl -bullet -width Ds -compact +.It +The remote IP is checked against +.Ic remote_address . +.It +ISAKMP exchange type is checked against +.Ic exchange_mode . +.It +ISAKMP SA attributes must match a +.Ic proposal +block. +.It +The remote identity is matched against +.Ic peers_identifier +if +.Ic verify_identifier +is on. +.It +If a certificate request was received, it must match the issuer of +.Ic "certificate_type x509" +certificate. +If certificate request without issuer name was sent, the +.Ic match_empty_cr +parameter specifies whether or not remote block matches. +.El +.Pp +Similarly, NAT-T is enabled if any of the initial remote configuration +candidates allow NAT-T. +.Pp +Sections with +.Ic inherit Ar parent +statements (where +.Ar parent +is either +.Ar address +or a keyword +.Ic anonymous ) +that have all values predefined to those of a given +.Ar parent . +In these sections it is enough to redefine only the changed parameters. +.Pp +The following are valid statements. +.Pp +.Bl -tag -width Ds -compact +.\" +.It Ic remote_address Ar address ; +Defines the IP address of the peer. +.\" +.It Ic exchange_mode ( main | aggressive | base ) ; +Defines the exchange mode for phase 1 when racoon is the initiator. +It also means the acceptable exchange mode when racoon is the responder. +More than one mode can be specified by separating them with a comma. +All of the modes are acceptable. +The first exchange mode is what racoon uses when it is the initiator. +.\" +.It Ic doi Ic ipsec_doi ; +Means to use IPsec DOI as specified in RFC 2407. +You can omit this statement. +.\" +.It Ic situation Ic identity_only ; +Means to use SIT_IDENTITY_ONLY as specified in RFC 2407. +You can omit this statement. +.\" +.It Ic my_identifier Bo Ar qualifier Bc Ar idtype ... ; +Specifies the identifier sent to the remote host +and the type to use in the phase 1 negotiation. +.Ic address, fqdn , user_fqdn , keyid , +and +.Ic asn1dn +can be used as an +.Ar idtype . +The +.Ar qualifier +is currently only used for +.Ic keyid , +and can be either +.Ic file +or +.Ic tag . +The possible values are : +.Bl -tag -width Ds -compact +.It Ic my_identifier Ic address Bq Ar address ; +The type is the IP address. +This is the default type if you do not specify an identifier to use. +.It Ic my_identifier Ic user_fqdn Ar string ; +The type is a USER_FQDN (user fully-qualified domain name). +.It Ic my_identifier Ic fqdn Ar string ; +The type is a FQDN (fully-qualified domain name). +.It Ic my_identifier Ic keyid Bo Ic file Bc Ar file ; +The type is a KEY_ID, read from the file. +.It Ic my_identifier Ic keyid Ic tag Ar string ; +The type is a KEY_ID, specified in the quoted string. +.It Ic my_identifier Ic asn1dn Bq Ar string ; +The type is an ASN.1 distinguished name. +If +.Ar string +is omitted, +.Xr racoon 8 +will get the DN from the Subject field in the certificate. +.El +.\" +.It Ic xauth_login Bq Ar string ; +Specifies the login to use in client-side Hybrid authentication. +It is available only if +.Xr racoon 8 +has been built with this option. +The associated password is looked up in the pre-shared key files, +using the login +.Ic string +as the key id. +.\" +.It Ic peers_identifier Ar idtype ... ; +Specifies the peer's identifier to be received. +If it is not defined then +.Xr racoon 8 +will not verify the peer's identifier in ID payload transmitted from the peer. +If it is defined, the behavior of the verification depends on the flag of +.Ic verify_identifier . +The usage of +.Ar idtype +is the same as +.Ic my_identifier +except that the individual component values of an +.Ic asn1dn +identifier may specified as +.Ic * +to match any value (e.g. "C=XX, O=MyOrg, OU=*, CN=Mine"). +The format of the +specification should correspond to RFC 2253; in particular, commas and certain +other characters - +.Ic ,=+\*[Lt]\*[Gt]#; +- may be included in a name by preceeding them with a backslash "\e", and +arbitrary characters may be inserted in a name with the "\enn" escape, where +nn is the hex representation of the ascii value of the desired character. +Alternative acceptable peer identifiers may be specified by repeating the +.Ic peers_identifier +statement. +.\" +.It Ic verify_identifier (on | off) ; +If you want to verify the peer's identifier, +set this to on. +In this case, if the value defined by +.Ic peers_identifier +is not the same as the peer's identifier in the ID payload, +the negotiation will fail. +The default is off. +.\" +.It Ic certificate_type Ar certspec ; +Specifies a certificate specification. +.Ar certspec +is one of followings: +.Bl -tag -width Ds -compact +.It Ic x509 Ar certfile Ar privkeyfile ; +.Ar certfile +means a file name of a certificate. +.Ar privkeyfile +means a file name of a secret key. +.El +.Bl -tag -width Ds -compact +.It Ic plain_rsa Ar privkeyfile ; +.Ar privkeyfile +means a file name of a private key generated by +.Xr plainrsa-gen 8 . +Required +for RSA authentication. +.El +.It Ic ca_type Ar cacertspec ; +Specifies a root certificate authority specification. +.Ar cacertspec +is one of followings: +.Bl -tag -width Ds -compact +.It Ic x509 Ar cacertfile ; +.Ar cacertfile +means a file name of the root certificate authority. +Default is +.Pa /etc/openssl/cert.pem +.El +.\" +.It Ic mode_cfg (on | off) ; +Gather network information through ISAKMP mode configuration. +Default is off. +.\" +.It Ic weak_phase1_check (on | off) ; +Tells racoon to act on unencrypted deletion messages during phase 1. +This is a small security risk, so the default is off, meaning that +racoon will keep on trying to establish a connection even if the +user credentials are wrong, for instance. +.\" +.It Ic peers_certfile ( dnssec | Ar certfile | Ic plain_rsa Ar pubkeyfile ) ; +If +.Ic dnssec +is defined, +.Xr racoon 8 +will ignore the CERT payload from the peer, +and try to get the peer's certificate from DNS instead. +If +.Ar certfile +is defined, +.Xr racoon 8 +will ignore the CERT payload from the peer, +and will use this certificate as the peer's certificate. +If +.Ic plain_rsa +is defined, +.Xr racoon 8 +will expect +.Ar pubkeyfile +to be the peer's public key that was generated by +.Xr plainrsa-gen 8 . +.\" +.It Ic script Ar script Ic phase1_up +.It Ic script Ar script Ic phase1_down +.It Ic script Ar script Ic phase1_dead +Shell scripts that get executed when a phase 1 SA goes up or down, or +when it is detected as dead by DPD. +All scripts get either +.Ic phase1_up +, +.Ic phase1_down +or +.Ic phase1_dead +as first argument, and the following +variables are set in their environment: +.Bl -tag -width Ds -compact +.It Ev LOCAL_ADDR +The local address of the phase 1 SA. +.It Ev LOCAL_PORT +The local port used for IKE for the phase 1 SA. +.It Ev REMOTE_ADDR +The remote address of the phase 1 SA. +.It Ev REMOTE_PORT +The remote port used for IKE for the phase 1 SA. +.It Ev REMOTE_ID +The remote identity received in IKE for the phase 1 SA. +.El +The following variables are only set if +.Ic mode_cfg +was enabled: +.Bl -tag -width Ds -compact +.It INTERNAL_ADDR4 +An IPv4 internal address obtained by ISAKMP mode config. +.It INTERNAL_NETMASK4 +An IPv4 internal netmask obtained by ISAKMP mode config. +.It INTERNAL_CIDR4 +An IPv4 internal netmask obtained by ISAKMP mode config, in CIDR notation. +.It INTERNAL_DNS4 +The first internal DNS server IPv4 address obtained by ISAKMP mode config. +.It INTERNAL_DNS4_LIST +A list of internal DNS servers IPv4 address obtained by ISAKMP mode config, +separated by spaces. +.It INTERNAL_WINS4 +The first internal WINS server IPv4 address obtained by ISAKMP mode config. +.It INTERNAL_WINS4_LIST +A list of internal WINS servers IPv4 address obtained by ISAKMP mode config, +separated by spaces. +.It SPLIT_INCLUDE +The space separated list of IPv4 addresses and masks (address slash mask) +that define the networks to be encrypted (as opposed to the default where +all the traffic should be encrypted) ; obtained by ISAKMP mode config ; +SPLIT_INCLUDE and SPLIT_LOCAL are mutually exclusive. +.It SPLIT_LOCAL +The space separated list of IPv4 addresses and masks (address slash mask) +that define the networks to be considered local, and thus excluded from the +tunnels ; obtained by ISAKMP mode config. +.It SPLIT_INCLUDE_CIDR +Same as SPLIT_INCLUDE, with netmasks in CIDR notation. +.It SPLIT_LOCAL_CIDR +Same as SPLIT_LOCAL, with netmasks in CIDR notation. +.It DEFAULT_DOMAIN +The DNS default domain name obtained by ISAKMP mode config. +.El +.\" +.\" +.It Ic send_cert (on | off) ; +If you do not want to send a certificate, set this to off. +The default is on. +.\" +.It Ic send_cr (on | off) ; +If you do not want to send a certificate request, set this to off. +The default is on. +.\" +.It Ic match_empty_cr (on | off) ; +Specifies whether this remote block is a valid match when a non-specific +certificate request is received. +The default is on. +.\" +.It Ic verify_cert (on | off) ; +By default, the identifier sent by the remote host (as specified in its +.Ic my_identifier +statement) is compared with the credentials in the certificate +used to authenticate the remote host as follows: +.Bl -tag -width Ds -compact +.It Type Ic asn1dn : +The entire certificate subject name is compared with the identifier, +e.g. "C=XX, O=YY, ...". +.It Type Ic address, fqdn, or user_fqdn : +The certificate's subjectAltName is compared with the identifier. +.El +If the two do not match the negotiation will fail. +If you do not want to verify the identifier using the peer's certificate, +set this to off. +.\" +.It Ic lifetime time Ar number Ar timeunit ; +Define a lifetime of a certain time +which will be proposed in the phase 1 negotiations. +Any proposal will be accepted, and the attribute(s) will not be proposed to +the peer if you do not specify it (them). +They can be individually specified in each proposal. +.\" +.It Ic ike_frag (on | off | force) ; +Enable receiver-side IKE fragmentation if +.Xr racoon 8 +has been built with this feature. +If set to on, racoon will advertise +itself as being capable of receiving packets split by IKE fragmentation. +This extension is there to work around broken firewalls that do not +work with fragmented UDP packets. +IKE fragmentation is always enabled on the sender-side, and it is +used if the peer advertises itself as IKE fragmentation capable. +By selecting force, IKE Fragmentation will +be used when racoon is acting as the initiator even before the remote +peer has advertised itself as IKE fragmentation capable. +.\" +.It Ic esp_frag Ar fraglen ; +This option is only relevant if you use NAT traversal in tunnel mode. +Its purpose is to work around broken DSL routers that reject UDP +fragments, by fragmenting the IP packets before ESP encapsulation. +The result is ESP over UDP of fragmented packets instead of fragmented +ESP over UDP packets (i.e., IP:UDP:ESP:frag(IP) instead of +frag(IP:UDP:ESP:IP)). +.Ar fraglen +is the maximum size of the fragments. +552 should work anywhere, +but the higher +.Ar fraglen +is, the better the performance. +.Pp +Note that because PMTU discovery is broken on many sites, you will +have to use MSS clamping if you want TCP to work correctly. +.\" +.It Ic initial_contact (on | off) ; +Enable this to send an INITIAL-CONTACT message. +The default value is +.Ic on . +This message is useful only when the responder implementation chooses an +old SA when there are multiple SAs with different established time and the +initiator reboots. +If racoon did not send the message, +the responder would use an old SA even when a new SA was established. +For systems that use a KAME derived IPSEC stack, the +.Xr sysctl 8 +variable net.key.preferred_oldsa can be used to control this preference. +When the value is zero, the stack always uses a new SA. +.\" +.It Ic passive (on | off) ; +If you do not want to initiate the negotiation, set this to on. +The default value is +.Ic off . +It is useful for a server. +.\" +.It Ic proposal_check Ar level ; +Specifies the action of lifetime length, key length, and PFS of the phase 2 +selection on the responder side, and the action of lifetime check in +phase 1. +The default level is +.Ic strict . +If the +.Ar level +is: +.Bl -tag -width Ds -compact +.It Ic obey +The responder will obey the initiator anytime. +.It Ic strict +If the responder's lifetime length is longer than the initiator's or +the responder's key length is shorter than the initiator's, +the responder will use the initiator's value. +Otherwise, the proposal will be rejected. +If PFS is not required by the responder, the responder will obey the proposal. +If PFS is required by both sides and the responder's group is not equal to +the initiator's, then the responder will reject the proposal. +.It Ic claim +If the responder's lifetime length is longer than the initiator's or +the responder's key length is shorter than the initiator's, +the responder will use the initiator's value. +If the responder's lifetime length is shorter than the initiator's, +the responder uses its own length AND sends a RESPONDER-LIFETIME notify +message to an initiator in the case of lifetime (phase 2 only). +For PFS, this directive behaves the same as +.Ic strict . +.It Ic exact +If the initiator's lifetime or key length is not equal to the responder's, +the responder will reject the proposal. +If PFS is required by both sides and the responder's group is not equal to +the initiator's, then the responder will reject the proposal. +.El +.\" +.It Ic support_proxy (on | off) ; +If this value is set to on, then both values of ID payloads in the +phase 2 exchange are always used as the addresses of end-point of +IPsec-SAs. +The default is off. +.\" +.It Ic generate_policy (on | off | require | unique) ; +This directive is for the responder. +Therefore you should set +.Ic passive +to on in order that +.Xr racoon 8 +only becomes a responder. +If the responder does not have any policy in SPD during phase 2 +negotiation, and the directive is set to on, then +.Xr racoon 8 +will choose the first proposal in the +SA payload from the initiator, and generate policy entries from the proposal. +It is useful to negotiate with clients whose IP address is allocated +dynamically. +Note that an inappropriate policy might be installed into the responder's SPD +by the initiator, +so other communications might fail if such policies are installed +due to a policy mismatch between the initiator and the responder. +.Ic on +and +.Ic require +values mean the same thing (generate a require policy). +.Ic unique +tells racoon to set up unique policies, with a monotoning increasing +reqid number (between 1 and IPSEC_MANUAL_REQID_MAX). +This directive is ignored in the initiator case. +The default value is +.Ic off . +.\" +.\" +.It Ic nat_traversal (on | off | force) ; +This directive enables use of the NAT-Traversal IPsec extension +(NAT-T). +NAT-T allows one or both peers to reside behind a NAT gateway (i.e., +doing address- or port-translation). +If a NAT gateway is detected during the phase 1 handshake, racoon will +attempt to negotiate the use of NAT-T with the remote peer. +If the negotiation succeeds, all ESP and AH packets for the given connection +will be encapsulated into UDP datagrams (port 4500, by default). +Possible values are: +.Bl -tag -width Ds -compact +.It Ic on +NAT-T is used when a NAT gateway is detected between the peers. +.It Ic off +NAT-T is not proposed/accepted. +This is the default. +.It Ic force +NAT-T is used regardless of whether a NAT gateway is detected between the +peers or not. +.El +Please note that NAT-T support is a compile-time option. +Although it is enabled in the source distribution by default, it +may not be available in your particular build. +In that case you will get a +warning when using any NAT-T related config options. +.\" +.It Ic dpd_delay Ar delay ; +This option activates the DPD and sets the time (in seconds) allowed +between 2 proof of liveliness requests. +The default value is +.Ic 0 , +which disables DPD monitoring, but still negotiates DPD support. +.\" +.It Ic dpd_retry Ar delay ; +If +.Ic dpd_delay +is set, this sets the delay (in seconds) to wait for a proof of +liveliness before considering it as failed and send another request. +The default value is +.Ic 5 . +.\" +.It Ic dpd_maxfail Ar number ; +If +.Ic dpd_delay +is set, this sets the maximum number of liveliness proofs to request +(without reply) before considering the peer is dead. +The default value is +.Ic 5 . +.\" +.It Ic rekey (on | off | force) ; +Enable automatic renegotiation of expired phase1 when there are non-dying +phase2 SAs. +Possible values are: +.Bl -tag -width Ds -compact +.It Ic force +Rekeying is done unconditionally. +.It Ic on +Rekeying is done only if DPD monitoring is active. +This is the default. +.It Ic off +No automatic rekeying. +Do note that turning off automatic rekeying will +result in inaccurate DPD monitoring. +.El +.\" +.It Ic nonce_size Ar number ; +define the byte size of nonce value. +Racoon can send any value although +RFC2409 specifies that the value MUST be between 8 and 256 bytes. +The default size is 16 bytes. +.\" +.It Ic ph1id Ar number ; +An optional number to identify the remote proposal and to link it +only with sainfos who have the same number. +Defaults to 0. +.\" +.It Ic proposal { Ar sub-substatements Ic } +.Bl -tag -width Ds -compact +.\" +.It Ic encryption_algorithm Ar algorithm ; +Specifies the encryption algorithm used for the phase 1 negotiation. +This directive must be defined. +.Ar algorithm +is one of following: +.Ic des, 3des, blowfish, cast128, aes, camellia +.\".Ic rc5 , idea +for Oakley. +For other transforms, this statement should not be used. +.\" +.It Ic hash_algorithm Ar algorithm ; +Defines the hash algorithm used for the phase 1 negotiation. +This directive must be defined. +.Ar algorithm +is one of following: +.Ic md5, sha1, sha256, sha384, sha512 +for Oakley. +.\" +.It Ic authentication_method Ar type ; +Defines the authentication method used for the phase 1 negotiation. +This directive must be defined. +.Ar type +is one of: +.Ic pre_shared_key , rsasig +(for plain RSA authentication), +.Ic gssapi_krb , hybrid_rsa_server , +.Ic hybrid_rsa_client , xauth_rsa_server , xauth_rsa_client , xauth_psk_server +or +.Ic xauth_psk_client . +.\" +.It Ic dh_group Ar group ; +Defines the group used for the Diffie-Hellman exponentiations. +This directive must be defined. +.Ar group +is one of following: +.Ic modp768 , modp1024 , modp1536 , +.Ic modp2048 , modp3072 , modp4096 , +.Ic modp6144 , modp8192 . +Or you can define 1, 2, 5, 14, 15, 16, 17, or 18 as the DH group number. +When you want to use aggressive mode, +you must define the same DH group in each proposal. +.It Ic lifetime time Ar number Ar timeunit ; +Defines the lifetime of the phase 1 SA proposal. +Refer to the description of the +.Ic lifetime +directive defined in the +.Ic remote +directive. +.It Ic gss_id Ar string ; +Defines the GSS-API endpoint name, to be included as an attribute in the SA, +if the +.Ic gssapi_krb +authentication method is used. +If this is not defined, the default value of +.Ql host/hostname +is used, where hostname is the value returned by the +.Xr hostname 1 +command. +.El +.El +.Pp +.It Ic remote Po Ar address | Ic anonymous Pc Bo Bo Ar port Bc Bc \ +Bo Ic inherit Ar parent Bc Ic { Ar statements Ic } +Deprecated format of specifying a remote block. +This will be removed in future. +It is a remnant from time when remote block was decided +solely based on the peers IP address. +.Pp +This is equivalent to: +.Bd -literal -offset +remote "address" [inherit "parent-address"] { + remote_address address; +} +.Ed +.El +.\" +.Ss Sainfo Specifications +.Bl -tag -width Ds -compact +.It Ic sainfo Po Ar local_id | Ic anonymous Pc \ +Po Ar remote_id | Ic clientaddr | Ic anonymous Pc \ +Bo Ic from Ar idtype Bo Ar string Bc Bc Bo Ic group Ar string Bc \ +Ic { Ar statements Ic } +Defines the parameters of the IKE phase 2 (IPsec-SA establishment). +.Pp +The +.Ar local_id +and +.Ar remote_id +strings are constructed like: +.Pp +.Ic address Ar address +.Bq Ic / Ar prefix +.Bq Ic [ Ar port ] +.Ar ul_proto +.Pp +or +.Pp +.Ic subnet Ar address +.Bq Ic / Ar prefix +.Bq Ic [ Ar port ] +.Ar ul_proto +.Pp +An id string should be expressed to match the exact value of an ID payload. +This is not like a filter rule. +For example, if you define 3ffe:501:4819::/48 as +.Ar local_id . +3ffe:501:4819:1000:/64 will not match. +In the case of a longest prefix (selecting a single host), +.Ar address +instructs to send ID type of ADDRESS while +.Ar subnet +instructs to send ID type of SUBNET. +Otherwise, these instructions are identical. +.Pp +The +.Ic anonymous +keyword can be used to match any id. +The +.Ic clientaddr +keyword can be used to match a remote id that is equal to either the peer +ip address or the mode_cfg ip address (if assigned). +This can be useful +to restrict policy generation when racoon is acting as a client gateway +for peers with dynamic ip addresses. +.Pp +The +.Ic from +keyword allows an sainfo to only match for peers that use a specific phase1 +id value during authentication. +The +.Ic group +keyword allows an XAuth group membership check to be performed +for this sainfo section. +When the mode_cfg auth source is set to +.Ic system +or +.Ic ldap , +the XAuth user is verified to be a member of the specified group +before allowing a matching SA to be negotiated. +.Pp +.Bl -tag -width Ds -compact +.\" +.It Ic pfs_group Ar group ; +define the group of Diffie-Hellman exponentiations. +If you do not require PFS then you can omit this directive. +Any proposal will be accepted if you do not specify one. +.Ar group +is one of following: +.Ic modp768 , modp1024 , modp1536 , +.Ic modp2048 , modp3072 , modp4096 , +.Ic modp6144 , modp8192 . +Or you can define 1, 2, 5, 14, 15, 16, 17, or 18 as the DH group number. +.\" +.It Ic lifetime time Ar number Ar timeunit ; +define how long an IPsec-SA will be used, in timeunits. +Any proposal will be accepted, and no attribute(s) will be proposed to +the peer if you do not specify it(them). +See the +.Ic proposal_check +directive. +.\" +.It Ic remoteid Ar number ; +Sainfos will only be used if their remoteid matches the ph1id of the +remote section used for phase 1. +Defaults to 0, which is also the default for ph1id. +.El +.\" +.Pp +.Xr racoon 8 +does not have a list of security protocols to be negotiated. +The list of security protocols are passed by SPD in the kernel. +Therefore you have to define all of the potential algorithms +in the phase 2 proposals even if there are algorithms which will not be used. +These algorithms are define by using the following three directives, +with a single comma as the separator. +For algorithms that can take variable-length keys, algorithm names +can be followed by a key length, like +.Dq Li blowfish 448 . +.Xr racoon 8 +will compute the actual phase 2 proposals by computing +the permutation of the specified algorithms, +and then combining them with the security protocol specified by the SPD. +For example, if +.Ic des , 3des , hmac_md5 , +and +.Ic hmac_sha1 +are specified as algorithms, we have four combinations for use with ESP, +and two for AH. +Then, based on the SPD settings, +.Xr racoon 8 +will construct the actual proposals. +If the SPD entry asks for ESP only, there will be 4 proposals. +If it asks for both AH and ESP, there will be 8 proposals. +Note that the kernel may not support the algorithm you have specified. +.\" +.Bl -tag -width Ds -compact +.It Ic encryption_algorithm Ar algorithms ; +.Ic des , 3des , des_iv64 , des_iv32 , +.Ic rc5 , rc4 , idea , 3idea , +.Ic cast128 , blowfish , null_enc , +.Ic twofish , rijndael , aes , camellia +.Pq used with ESP +.\" +.It Ic authentication_algorithm Ar algorithms ; +.Ic des , 3des , des_iv64 , des_iv32 , +.Ic hmac_md5 , hmac_sha1 , hmac_sha256, hmac_sha384, hmac_sha512, non_auth +.Pq used with ESP authentication and AH +.\" +.It Ic compression_algorithm Ar algorithms ; +.Ic deflate +.Pq used with IPComp +.El +.El +.\" +.Ss Logging level +.Bl -tag -width Ds -compact +.It Ic log Ar level ; +Defines the logging level. +.Ar level +is one of following: +.Ic error , warning , notify , info , debug +or +.Ic debug2 . +The default is +.Ic info . +If you set the logging level too high on slower machines, +IKE negotiation can fail due to timing constraint changes. +.El +.\" +.Ss Specifies the way to pad +.Bl -tag -width Ds -compact +.It Ic padding { Ar statements Ic } +specifies the padding format. +The following are valid statements: +.Bl -tag -width Ds -compact +.It Ic randomize (on | off) ; +Enables the use of a randomized value for padding. +The default is on. +.It Ic randomize_length (on | off) ; +The pad length will be random. +The default is off. +.It Ic maximum_length Ar number ; +Defines a maximum padding length. +If +.Ic randomize_length +is off, this is ignored. +The default is 20 bytes. +.It Ic exclusive_tail (on | off) ; +Means to put the number of pad bytes minus one into the last part +of the padding. +The default is on. +.It Ic strict_check (on | off) ; +Means to constrain the peer to set the number of pad bytes. +The default is off. +.El +.El +.Ss ISAKMP mode configuration settings +.Bl -tag -width Ds -compact +.It Ic mode_cfg { Ar statements Ic } +Defines the information to return for remote hosts' ISAKMP mode config +requests. +Also defines the authentication source for remote peers +authenticating through Xauth. +.Pp +The following are valid statements: +.Bl -tag -width Ds -compact +.It Ic auth_source (system | radius | pam | ldap) ; +Specifies the source for authentication of users through Xauth. +.Ar system +means to use the Unix user database. +This is the default. +.Ar radius +means to use a RADIUS server. +It works only if +.Xr racoon 8 +was built with libradius support. +Radius configuration is handled by statements in the +.Ic radiuscfg +section. +.Ar pam +means to use PAM. +It works only if +.Xr racoon 8 +was built with libpam support. +.Ar ldap +means to use LDAP. +It works only if +.Xr racoon 8 +was built with libldap support. +LDAP configuration is handled by statements in the +.Ic ldapcfg +section. +.It Ic auth_groups Ar "group1", ... ; +Specifies the group memberships for Xauth in quoted group name strings. +When defined, the authenticating user must be a member of at least one +group for Xauth to succeed. +.It Ic group_source (system | ldap) ; +Specifies the source for group validation of users through Xauth. +.Ar system +means to use the Unix user database. +This is the default. +.Ar ldap +means to use LDAP. +It works only if +.Xr racoon 8 +was built with libldap support and requires LDAP authentication. +LDAP configuration is handled by statements in the +.Ic ldapcfg +section. +.It Ic conf_source (local | radius | ldap) ; +Specifies the source for IP addresses and netmask allocated through ISAKMP +mode config. +.Ar local +means to use the local IP pool defined by the +.Ic network4 +and +.Ic pool_size +statements. +This is the default. +.Ar radius +means to use a RADIUS server. +It works only if +.Xr racoon 8 +was built with libradius support and requires RADIUS authentication. +RADIUS configuration is handled by statements in the +.Ic radiuscfg +section. +.Ar ldap +means to use an LDAP server. +It works only if +.Xr racoon 8 +was built with libldap support and requires LDAP authentication. +LDAP configuration is handled by +statements in the +.Ic ldapcfg +section. +.It Ic accounting (none | system | radius | pam) ; +Enables or disables accounting for Xauth logins and logouts. +The default is +.Ar none +which disable accounting. +Specifying +.Ar system +enables system accounting through +.Xr utmp 5 . +Specifying +.Ar radius +enables RADIUS accounting. +It works only if +.Xr racoon 8 +was built with libradius support and requires RADIUS authentication. +RADIUS configuration is handled by statements in the +.Ic radiuscfg +section. +Specifying +.Ar pam +enables PAM accounting. +It works only if +.Xr racoon 8 +was build with libpam support and requires PAM authentication. +.It Ic pool_size Ar size +Specify the size of the IP address pool, either local or allocated +through RADIUS. +.Ic conf_source +selects the local pool or the RADIUS configuration, but in both +configurations, you cannot have more than +.Ar size +users connected at the same time. +The default is 255. +.It Ic network4 Ar address ; +.It Ic netmask4 Ar address ; +The local IP pool base address and network mask from which dynamically +allocated IPv4 addresses should be taken. +This is used if +.Ic conf_source +is set to +.Ar local +or if the RADIUS server returned +.Ar 255.255.255.254 . +Default is +.Ar 0.0.0.0/0.0.0.0 . +.It Ic dns4 Ar addresses ; +A list of IPv4 addresses for DNS servers, separated by commas, or on multiple +.Ic dns4 +lines. +.It Ic wins4 Ar addresses ; +A list of IPv4 address for WINS servers. +The keyword +.It nbns4 +can also be used as an alias for +.It wins4 . +.It Ic split_network (include | local_lan) Ar network/mask, ... +The network configuration to send, in CIDR notation (e.g. 192.168.1.0/24). +If +.Ic include +is specified, the tunnel should be only used to encrypt the indicated +destinations ; otherwise, if +.Ic local_lan +is used, everything will pass through the tunnel but those destinations. +.It Ic default_domain Ar domain ; +The default DNS domain to send. +.It Ic split_dns Ar "domain", ... +The split dns configuration to send, in quoted domain name strings. +This list can be used to describe a list of domain names for which +a peer should query a modecfg assigned dns server. +DNS queries for all other domains would be handled locally. +(Cisco VPN client only). +.It Ic banner Ar path ; +The path of a file displayed on the client at connection time. +Default is +.Ar /etc/motd . +.It Ic auth_throttle Ar delay ; +On each failed Xauth authentication attempt, refuse new attempts for a set +.Ar delay +of seconds. +This is to avoid dictionary attacks on Xauth passwords. +Default is one second. +Set to zero to disable authentication delay. +.It Ic pfs_group Ar group ; +Sets the PFS group used in the client proposal (Cisco VPN client only). +Default is 0. +.It Ic save_passwd (on | off) ; +Allow the client to save the Xauth password (Cisco VPN client only). +Default is off. +.El +.El +.Ss Ldap configuration settings +.Bl -tag -width Ds -compact +.It Ic ldapcfg { Ar statements Ic } +Defines the parameters that will be used to communicate with an ldap +server for +.Ic xauth +authentication. +.Pp +The following are valid statements: +.Bl -tag -width Ds -compact +.It Ic version (2 | 3) ; +The ldap protocol version used to communicate with the server. +The default is +.Ic 3 . +.It Ic host Ar (hostname | address) ; +The host name or ip address of the ldap server. +The default is +.Ic localhost . +.It Ic port Ar number ; +The port that the ldap server is configured to listen on. +The default is +.Ic 389 . +.It Ic base Ar distinguished name ; +The ldap search base. +This option has no default value. +.It Ic subtree (on | off) ; +Use the subtree ldap search scope. +Otherwise, use the one level search scope. +The default is +.Ic off . +.It Ic bind_dn Ar distinguished name ; +The user dn used to optionally bind as before performing ldap search operations. +If this option is not specified, anonymous binds are used. +.It Ic bind_pw Ar string ; +The password used when binding as +.Ic bind_dn . +.It Ic attr_user Ar attribute name ; +The attribute used to specify a users name in an ldap directory. +For example, +if a user dn is "cn=jdoe,dc=my,dc=net" then the attribute would be "cn". +The default value is +.Ic cn . +.It Ic attr_addr Ar attribute name ; +.It Ic attr_mask Ar attribute name ; +The attributes used to specify a users network address and subnet mask in an +ldap directory. +These values are forwarded during mode_cfg negotiation when +the conf_source is set to ldap. +The default values are +.Ic racoon-address +and +.Ic racoon-netmask . +.It Ic attr_group Ar attribute name ; +The attribute used to specify a group name in an ldap directory. +For example, +if a group dn is "cn=users,dc=my,dc=net" then the attribute would be "cn". +The default value is +.Ic cn . +.It Ic attr_member Ar attribute name ; +The attribute used to specify group membership in an ldap directory. +The default value is +.Ic member . +.El +.El +.Ss Radius configuration settings +.Bl -tag -width Ds -compact +.It Ic radiuscfg { Ar statements Ic } +Defines the parameters that will be used to communicate with radius +servers for +.Ic xauth +authentication. +If radius is selected as the xauth authentication or accounting +source and no servers are defined in this section, settings from +the system +.Xr radius.conf 5 +configuration file will be used instead. +.Pp +The following are valid statements: +.Bl -tag -width Ds -compact +.It Ic auth Ar (hostname | address) [port] sharedsecret ; +The host name or ip address, optional port value and shared secret value +of a radius authentication server. +Up to 5 radius authentication servers +may be specified using multiple lines. +.It Ic acct Ar (hostname | address) [port] sharedsecret ; +The host name or ip address, optional port value and shared secret value +of a radius accounting server. +Up to 5 radius accounting servers may be +specified using multiple lines. +.It Ic timeout Ar seconds ; +The timeout for receiving replies from radius servers. +The default is +.Ic 3 . +.It Ic retries Ar count ; +The maximum number of repeated requests to make before giving up +on a radius server. +The default is +.Ic 3 . +.El +.El +.Ss Special directives +.Bl -tag -width Ds -compact +.It Ic complex_bundle (on | off) ; +defines the interpretation of proposal in the case of SA bundle. +Normally +.Dq IP AH ESP IP payload +is proposed as +.Dq AH tunnel and ESP tunnel . +The interpretation is more common to other IKE implementations, however, +it allows very limited set of combinations for proposals. +With the option enabled, it will be proposed as +.Dq AH transport and ESP tunnel . +The default value is +.Ic off . +.El +.\" +.Ss Pre-shared key File +The pre-shared key file defines pairs of identifiers and corresponding +shared secret keys which are used in the pre-shared key authentication +method in phase 1. +The pair in each line is separated by some number of blanks and/or tab +characters like in the +.Xr hosts 5 +file. +Key can include blanks because everything after the first blanks +is interpreted as the secret key. +Lines starting with +.Ql # +are ignored. +Keys which start with +.Ql 0x +are interpreted as hexadecimal strings. +Note that the file must be owned by the user ID running +.Xr racoon 8 +.Pq usually the privileged user , +and must not be accessible by others. +.\" +.Sh EXAMPLES +The following shows how the remote directive should be configured. +.Bd -literal -offset +path pre_shared_key "/usr/local/v6/etc/psk.txt" ; +remote anonymous +{ + exchange_mode aggressive,main,base; + lifetime time 24 hour; + proposal { + encryption_algorithm 3des; + hash_algorithm sha1; + authentication_method pre_shared_key; + dh_group 2; + } +} + +sainfo anonymous +{ + pfs_group 2; + lifetime time 12 hour ; + encryption_algorithm 3des, blowfish 448, twofish, rijndael ; + authentication_algorithm hmac_sha1, hmac_md5 ; + compression_algorithm deflate ; +} +.Ed +.Pp +If you are configuring plain RSA authentication, the remote directive +should look like the following: +.Bd -literal -offset +path certificate "/usr/local/v6/etc" ; +remote anonymous +{ + exchange_mode main,base ; + lifetime time 12 hour ; + certificate_type plain_rsa "/usr/local/v6/etc/myrsakey.priv"; + peers_certfile plain_rsa "/usr/local/v6/etc/yourrsakey.pub"; + proposal { + encryption_algorithm aes ; + hash_algorithm sha1 ; + authentication_method rsasig ; + dh_group 2 ; + } +} +.Ed +.Pp +The following is a sample for the pre-shared key file. +.Bd -literal -offset +10.160.94.3 mekmitasdigoat +172.16.1.133 0x12345678 +194.100.55.1 whatcertificatereally +3ffe:501:410:ffff:200:86ff:fe05:80fa mekmitasdigoat +3ffe:501:410:ffff:210:4bff:fea2:8baa mekmitasdigoat +foo@kame.net mekmitasdigoat +foo.kame.net hoge +.Ed +.\" +.Sh SEE ALSO +.Xr racoon 8 , +.Xr racoonctl 8 , +.Xr setkey 8 +.\" +.Sh HISTORY +The +.Nm +configuration file first appeared in the +.Dq YIPS +Yokogawa IPsec implementation. +.\" +.Sh BUGS +Some statements may not be handled by +.Xr racoon 8 +yet. +.Pp +Diffie-Hellman computation can take a very long time, and may cause +unwanted timeouts, specifically when a large D-H group is used. +.\" +.Sh SECURITY CONSIDERATIONS +The use of IKE phase 1 aggressive mode is not recommended, +as described in +.Li http://www.kb.cert.org/vuls/id/886601 . diff --git a/ipsec-tools/src/racoon/racoonctl.8 b/ipsec-tools/src/racoon/racoonctl.8 new file mode 100644 index 00000000..697f3ede --- /dev/null +++ b/ipsec-tools/src/racoon/racoonctl.8 @@ -0,0 +1,228 @@ +.\" $NetBSD: racoonctl.8,v 1.22 2009/03/12 14:01:09 wiz Exp $ +.\" +.\" Id: racoonctl.8,v 1.6 2006/05/07 21:32:59 manubsd Exp +.\" +.\" Copyright (C) 2004 Emmanuel Dreyfus +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the project nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd March 12, 2009 +.Dt RACOONCTL 8 +.Os +.\" +.Sh NAME +.Nm racoonctl +.Nd racoon administrative control tool +.\" +.Sh SYNOPSIS +.Nm +.Op opts +reload-config +.Nm +.Op opts +show-schedule +.Nm +.Op opts +show-sa +.Op isakmp|esp|ah|ipsec +.Nm +.Op opts +get-sa-cert +.Op inet|inet6 +.Ar src dst +.Nm +.Op opts +flush-sa +.Op isakmp|esp|ah|ipsec +.Nm +.Op opts +delete-sa +.Ar saopts +.Nm +.Op opts +establish-sa +.Op Fl w +.Op Fl n Ar remoteconf +.Op Fl u Ar identity +.Ar saopts +.Nm +.Op opts +vpn-connect +.Op Fl u Ar identity +.Ar vpn_gateway +.Nm +.Op opts +vpn-disconnect +.Ar vpn_gateway +.Nm +.Op opts +show-event +.Nm +.Op opts +logout-user +.Ar login +.\" +.Sh DESCRIPTION +.Nm +is used to control +.Xr racoon 8 +operation, if ipsec-tools was configured with adminport support. +Communication between +.Nm +and +.Xr racoon 8 +is done through a UNIX socket. +By changing the default mode and ownership +of the socket, you can allow non-root users to alter +.Xr racoon 8 +behavior, so do that with caution. +.Pp +The following general options are available: +.Bl -tag -width Ds +.It Fl d +Debug mode. +Hexdump sent admin port commands. +.It Fl l +Increase verbosity. +Mainly for show-sa command. +.It Fl s Ar socket +Specify unix socket name used to connecting racoon. +.El +.\" +.Pp +The following commands are available: +.Bl -tag -width Ds +.It reload-config +This should cause +.Xr racoon 8 +to reload its configuration file. +.It show-schedule +Unknown command. +.It show-sa Op isakmp|esp|ah|ipsec +Dump the SA: All the SAs if no SA class is provided, or either ISAKMP SAs, +IPsec ESP SAs, IPsec AH SAs, or all IPsec SAs. +Use +.Fl l +to increase verbosity. +.It get-sa-cert Oo inet|inet6 Oc Ar src dst +Output the raw certificate that was used to authenticate the phase 1 +matching +.Ar src +and +.Ar dst . +.It flush-sa Op isakmp|esp|ah|ipsec +is used to flush all SAs if no SA class is provided, or a class of SAs, +either ISAKMP SAs, IPsec ESP SAs, IPsec AH SAs, or all IPsec SAs. +.It establish-sa Oo Fl w Oc Oo Fl n Ar remoteconf Oc Oo Fl u Ar username \ +Oc Ar saopts +Establish an SA, either an ISAKMP SA, IPsec ESP SA, or IPsec AH SA. +The optional +.Fl u Ar username +can be used when establishing an ISAKMP SA while hybrid auth is in use. +The exact remote block to use can be specified with +.Fl n Ar remoteconf . +.Nm +will prompt you for the password associated with +.Ar username +and these credentials will be used in the Xauth exchange. +.Pp +Specifying +.Fl w +will make racoonctl wait until the SA is actually established or +an error occurs. +.Pp +.Ar saopts +has the following format: +.Bl -tag -width Bl +.It isakmp {inet|inet6} Ar src Ar dst +.It {esp|ah} {inet|inet6} Ar src/prefixlen/port Ar dst/prefixlen/port +{icmp|tcp|udp|gre|any} +.El +.It vpn-connect Oo Fl u Ar username Oc Ar vpn_gateway +This is a particular case of the previous command. +It will establish an ISAKMP SA with +.Ar vpn_gateway . +.It delete-sa Ar saopts +Delete an SA, either an ISAKMP SA, IPsec ESP SA, or IPsec AH SA. +.It vpn-disconnect Ar vpn_gateway +This is a particular case of the previous command. +It will kill all SAs associated with +.Ar vpn_gateway . +.It show-event +Listen for all events reported by +.Xr racoon 8 . +.It logout-user Ar login +Delete all SA established on behalf of the Xauth user +.Ar login . +.El +.Pp +Command shortcuts are available: +.Bl -tag -width XXX -compact -offset indent +.It rc +reload-config +.It ss +show-sa +.It sc +show-schedule +.It fs +flush-sa +.It ds +delete-sa +.It es +establish-sa +.It vc +vpn-connect +.It vd +vpn-disconnect +.It se +show-event +.It lu +logout-user +.El +.\" +.Sh RETURN VALUES +The command should exit with 0 on success, and non-zero on errors. +.\" +.Sh FILES +.Bl -tag -width 30n -compact +.It Pa /var/racoon/racoon.sock No or +.It Pa /var/run/racoon.sock +.Xr racoon 8 +control socket. +.El +.\" +.Sh SEE ALSO +.Xr ipsec 4 , +.Xr racoon 8 +.Sh HISTORY +Once was +.Ic kmpstat +in the KAME project. +It turned into +.Nm +but remained undocumented for a while. +.An Emmanuel Dreyfus Aq manu@NetBSD.org +wrote this man page. diff --git a/ipsec-tools/src/racoon/racoonctl.c b/ipsec-tools/src/racoon/racoonctl.c new file mode 100644 index 00000000..da28ecd7 --- /dev/null +++ b/ipsec-tools/src/racoon/racoonctl.c @@ -0,0 +1,1529 @@ +/* $NetBSD: racoonctl.c,v 1.18 2010/11/12 09:08:26 tteras Exp $ */ + +/* Id: racoonctl.c,v 1.11 2006/04/06 17:06:25 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * Copyright (C) 2008 Timo Teras. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include + +#include "var.h" +#include "vmbuf.h" +#include "misc.h" +#include "gcmalloc.h" + +#include "racoonctl.h" +#include "admin.h" +#include "schedule.h" +#include "handler.h" +#include "sockmisc.h" +#include "vmbuf.h" +#include "plog.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#include "isakmp_unity.h" +#include "ipsec_doi.h" +#include "evt.h" + +char *adminsock_path = ADMINSOCK_PATH; + +static void usage __P((void)); +static vchar_t *get_combuf __P((int, char **)); +static int handle_recv __P((vchar_t *)); +static vchar_t *f_reload __P((int, char **)); +static vchar_t *f_getsched __P((int, char **)); +static vchar_t *f_getsa __P((int, char **)); +static vchar_t *f_getsacert __P((int, char **)); +static vchar_t *f_flushsa __P((int, char **)); +static vchar_t *f_deletesa __P((int, char **)); +static vchar_t *f_exchangesa __P((int, char **)); +static vchar_t *f_vpnc __P((int, char **)); +static vchar_t *f_vpnd __P((int, char **)); +static vchar_t *f_getevt __P((int, char **)); +#ifdef ENABLE_HYBRID +static vchar_t *f_logoutusr __P((int, char **)); +#endif + +struct cmd_tag { + vchar_t *(*func) __P((int, char **)); + char *str; +} cmdtab[] = { + { f_reload, "reload-config" }, + { f_reload, "rc" }, + { f_getsched, "show-schedule" }, + { f_getsched, "sc" }, + { f_getsa, "show-sa" }, + { f_getsa, "ss" }, + { f_getsacert, "get-cert" }, + { f_getsacert, "gc" }, + { f_flushsa, "flush-sa" }, + { f_flushsa, "fs" }, + { f_deletesa, "delete-sa" }, + { f_deletesa, "ds" }, + { f_exchangesa, "establish-sa" }, + { f_exchangesa, "es" }, + { f_vpnc, "vpn-connect" }, + { f_vpnc, "vc" }, + { f_vpnd, "vpn-disconnect" }, + { f_vpnd, "vd" }, + { f_getevt, "show-event" }, + { f_getevt, "se" }, +#ifdef ENABLE_HYBRID + { f_logoutusr, "logout-user" }, + { f_logoutusr, "lu" }, +#endif + { NULL, NULL }, +}; + +struct evtmsg { + int type; + char *msg; +} evtmsg[] = { + { EVT_RACOON_QUIT, "Racoon terminated" }, + + { EVT_PHASE1_UP, "Phase 1 established" }, + { EVT_PHASE1_DOWN, "Phase 1 deleted" }, + { EVT_PHASE1_NO_RESPONSE, "Phase 1 error: peer not responding" }, + { EVT_PHASE1_NO_PROPOSAL, "Phase 1 error: no proposal chosen" }, + { EVT_PHASE1_AUTH_FAILED, + "Phase 1 error: authentication failed (bad certificate?)" }, + { EVT_PHASE1_DPD_TIMEOUT, "Phase 1 error: dead peer detected" }, + { EVT_PHASE1_MODE_CFG, "Phase 1 mode configuration done" }, + { EVT_PHASE1_XAUTH_SUCCESS, "Phase 1 Xauth succeeded" }, + { EVT_PHASE1_XAUTH_FAILED, "Phase 1 Xauth failed" }, + + { EVT_PHASE2_NO_PHASE1, "Phase 2 error: no suitable phase 1" }, + { EVT_PHASE2_UP, "Phase 2 established" }, + { EVT_PHASE2_DOWN, "Phase 2 deleted" }, + { EVT_PHASE2_NO_RESPONSE, "Phase 2 error: no response" }, +}; + +static vchar_t *get_proto_and_index __P((int, char **, u_int16_t *)); +static int get_proto __P((char *)); +static vchar_t *get_index __P((int, char **)); +static int get_family __P((char *)); +static vchar_t *get_comindexes __P((int, int, char **)); +static int get_comindex __P((char *, char **, char **, char **)); +static int get_ulproto __P((char *)); + +struct proto_tag { + int proto; + char *str; +} prototab[] = { + { ADMIN_PROTO_ISAKMP, "isakmp" }, + { ADMIN_PROTO_IPSEC, "ipsec" }, + { ADMIN_PROTO_AH, "ah" }, + { ADMIN_PROTO_ESP, "esp" }, + { ADMIN_PROTO_INTERNAL, "internal" }, + { 0, NULL }, +}; + +struct ulproto_tag { + int ul_proto; + char *str; +} ulprototab[] = { + { 0, "any" }, + { IPPROTO_ICMP, "icmp" }, + { IPPROTO_TCP, "tcp" }, + { IPPROTO_UDP, "udp" }, + { IPPROTO_GRE, "gre" }, + { 0, NULL }, +}; + +int so; + +static char _addr1_[NI_MAXHOST], _addr2_[NI_MAXHOST]; + +char *pname; +int long_format = 0; +int evt_quit_event = 0; + +void dump_isakmp_sa __P((char *, int)); +void dump_internal __P((char *, int)); +char *pindex_isakmp __P((isakmp_index *)); +void print_schedule __P((caddr_t, int)); +void print_evt __P((struct evt_async *)); +char * fixed_addr __P((char *, char *, int)); + +static void +usage() +{ + printf( +"Usage:\n" +" %s [opts] reload-config\n" +" %s [opts] show-schedule\n" +" %s [opts] show-sa [protocol]\n" +" %s [opts] flush-sa [protocol]\n" +" %s [opts] delete-sa \n" +" %s [opts] establish-sa [-u identity] [-n remoteconf] [-w] \n" +" %s [opts] vpn-connect [-u identity] vpn_gateway\n" +" %s [opts] vpn-disconnect vpn_gateway\n" +" %s [opts] show-event\n" +" %s [opts] logout-user login\n" +"\n" +"General options:\n" +" -d Debug: hexdump admin messages before sending\n" +" -l Increase output verbosity (mainly for show-sa)\n" +" -s Specify adminport socket to use (default: %s)\n" +"\n" +"Parameter specifications:\n" +" : \"isakmp\", \"esp\" or \"ah\".\n" +" In the case of \"show-sa\" or \"flush-sa\", you can use \"ipsec\".\n" +"\n" +" : \"isakmp\" \n" +" : {\"esp\",\"ah\"} \n" +" \n" +" : \"inet\" or \"inet6\"\n" +" : \"icmp\", \"tcp\", \"udp\", \"gre\" or \"any\"\n" +"\n", + pname, pname, pname, pname, pname, pname, pname, pname, pname, pname, + ADMINSOCK_PATH); +} + +/* + * Check for proper racoonctl interface + */ +#if ((RACOONCTL_INTERFACE_MAJOR != 1) || (RACOONCTL_INTERFACE < 20041230)) +#error "Incompatible racoonctl interface" +#endif + +int +main(ac, av) + int ac; + char **av; +{ + vchar_t *combuf; + int c; + + pname = *av; + + /* + * Check for proper racoonctl interface + */ + if ((racoonctl_interface_major != RACOONCTL_INTERFACE_MAJOR) || + (racoonctl_interface < RACOONCTL_INTERFACE)) + errx(1, "Incompatible racoonctl interface"); + +#ifdef __linux__ + /* + * Disable GNU extensions that will prevent racoonct vc -u login + * from working (GNU getopt(3) does not like options after vc) + */ + setenv("POSIXLY_CORRECT", "1", 0); +#endif + while ((c = getopt(ac, av, "lds:")) != -1) { + switch(c) { + case 'l': + long_format++; + break; + + case 'd': + loglevel++; + break; + + case 's': + adminsock_path = optarg; + break; + + default: + usage(); + exit(0); + } + } + + ac -= optind; + av += optind; + + combuf = get_combuf(ac, av); + if (!combuf) + err(1, "kmpstat"); + + if (loglevel) + racoon_hexdump(combuf, ((struct admin_com *)combuf)->ac_len); + + com_init(); + + if (com_send(combuf) != 0) + goto bad; + + vfree(combuf); + + do { + if (com_recv(&combuf) != 0) + goto bad; + if (handle_recv(combuf) != 0) + goto bad; + vfree(combuf); + } while (evt_quit_event != 0); + + close(so); + exit(0); + +bad: + close(so); + if (errno == EEXIST) + exit(0); + exit(1); +} + +/* %%% */ +/* + * return command buffer. + */ +static vchar_t * +get_combuf(ac, av) + int ac; + char **av; +{ + struct cmd_tag *cp; + + if (ac == 0) { + usage(); + exit(0); + } + + /* checking the string of command. */ + for (cp = &cmdtab[0]; cp->str; cp++) { + if (strcmp(*av, cp->str) == 0) { + break; + } + } + if (!cp->str) { + printf("Invalid command [%s]\n", *av); + errno = EINVAL; + return NULL; + } + + ac--; + av++; + return (cp->func)(ac, av); +} + +static vchar_t * +make_request(u_int16_t cmd, u_int16_t proto, size_t len) +{ + vchar_t *buf; + struct admin_com *head; + + buf = vmalloc(sizeof(struct admin_com) + len); + if (buf == NULL) + errx(1, "not enough core"); + + head = (struct admin_com *) buf->v; + head->ac_len = buf->l; + head->ac_cmd = ADMIN_FLAG_VERSION | cmd; + head->ac_version = 1; + head->ac_proto = proto; + + return buf; +} + +static vchar_t * +f_reload(ac, av) + int ac; + char **av; +{ + return make_request(ADMIN_RELOAD_CONF, 0, 0); +} + +static vchar_t * +f_getevt(ac, av) + int ac; + char **av; +{ + evt_quit_event = -1; + if (ac >= 1) + errx(1, "too many arguments"); + + return make_request(ADMIN_SHOW_EVT, 0, 0); +} + +static vchar_t * +f_getsched(ac, av) + int ac; + char **av; +{ + return make_request(ADMIN_SHOW_SCHED, 0, 0); +} + +static vchar_t * +f_getsa(ac, av) + int ac; + char **av; +{ + int proto; + + /* need protocol */ + if (ac != 1) + errx(1, "insufficient arguments"); + proto = get_proto(*av); + if (proto == -1) + errx(1, "unknown protocol %s", *av); + + return make_request(ADMIN_SHOW_SA, proto, 0); +} + +static vchar_t * +f_getsacert(ac, av) + int ac; + char **av; +{ + vchar_t *buf, *index; + struct admin_com_indexes *com; + + index = get_index(ac, av); + if (index == NULL) + return NULL; + + com = (struct admin_com_indexes *) index->v; + buf = make_request(ADMIN_GET_SA_CERT, ADMIN_PROTO_ISAKMP, index->l); + if (buf == NULL) + errx(1, "Cannot allocate buffer"); + + memcpy(buf->v+sizeof(struct admin_com), index->v, index->l); + + vfree(index); + + return buf; +} + +static vchar_t * +f_flushsa(ac, av) + int ac; + char **av; +{ + vchar_t *buf; + struct admin_com *head; + int proto; + + /* need protocol */ + if (ac != 1) + errx(1, "insufficient arguments"); + proto = get_proto(*av); + if (proto == -1) + errx(1, "unknown protocol %s", *av); + + return make_request(ADMIN_FLUSH_SA, proto, 0); +} + +static vchar_t * +f_deletesa(ac, av) + int ac; + char **av; +{ + vchar_t *buf, *index; + int proto; + + /* need protocol */ + if (ac < 1) + errx(1, "insufficient arguments"); + proto = get_proto(*av); + if (proto == -1) + errx(1, "unknown protocol %s", *av); + + /* get index(es) */ + av++; + ac--; + switch (proto) { + case ADMIN_PROTO_ISAKMP: + index = get_index(ac, av); + if (index == NULL) + return NULL; + break; + case ADMIN_PROTO_AH: + case ADMIN_PROTO_ESP: + index = get_index(ac, av); + if (index == NULL) + return NULL; + break; + default: + errno = EPROTONOSUPPORT; + return NULL; + } + + buf = make_request(ADMIN_DELETE_SA, proto, index->l); + if (buf == NULL) + goto out; + + memcpy(buf->v + sizeof(struct admin_com), index->v, index->l); + +out: + if (index != NULL) + vfree(index); + + return buf; +} + +static vchar_t * +f_deleteallsadst(ac, av) + int ac; + char **av; +{ + vchar_t *buf, *index; + u_int16_t proto; + + index = get_proto_and_index(ac, av, &proto); + if (index == NULL) + return NULL; + + buf = make_request(ADMIN_DELETE_ALL_SA_DST, proto, index->l); + if (buf == NULL) + goto out; + + memcpy(buf->v+sizeof(struct admin_com), index->v, index->l); + +out: + if (index != NULL) + vfree(index); + + return buf; +} + +static vchar_t * +f_exchangesa(ac, av) + int ac; + char **av; +{ + vchar_t *buf, *index; + u_int16_t proto; + int cmd = ADMIN_ESTABLISH_SA; + size_t com_len = 0; + char *id = NULL; + char *key = NULL; + char *remoteconf = NULL; + struct admin_com_psk *acp; + int wait = 0; + + if (ac < 1) + errx(1, "insufficient arguments"); + + /* Optional -u identity */ + if (strcmp(av[0], "-u") == 0) { + if (ac < 2) + errx(1, "-u require an argument"); + + id = av[1]; + if ((key = getpass("Password: ")) == NULL) + errx(1, "getpass() failed: %s", strerror(errno)); + + com_len += sizeof(*acp) + strlen(id) + 1 + strlen(key) + 1; + cmd = ADMIN_ESTABLISH_SA_PSK; + + av += 2; + ac -= 2; + } + + if (ac >= 2 && strcmp(av[0], "-n") == 0) { + /* Remoteconf name */ + remoteconf = av[1]; + av += 2; + ac -= 2; + } + + if (ac >= 1 && strcmp(av[0], "-w") == 0) { + wait = 1; + av++; + ac--; + } + + index = get_proto_and_index(ac, av, &proto); + if (index == NULL) + return NULL; + + if (proto == ADMIN_PROTO_ISAKMP && cmd == ADMIN_ESTABLISH_SA && + remoteconf != NULL) + com_len += strlen(remoteconf) + 1; + + if (wait) { + switch (proto) { + case ADMIN_PROTO_ISAKMP: + evt_quit_event = EVT_PHASE1_MODE_CFG; + break; + case ADMIN_PROTO_AH: + case ADMIN_PROTO_ESP: + evt_quit_event = EVT_PHASE2_UP; + break; + default: + errno = EPROTONOSUPPORT; + return NULL; + } + } + + com_len += index->l; + buf = make_request(cmd, proto, com_len); + if (buf == NULL) + errx(1, "Cannot allocate buffer"); + + memcpy(buf->v+sizeof(struct admin_com), index->v, index->l); + + if (proto == ADMIN_PROTO_ISAKMP && cmd == ADMIN_ESTABLISH_SA && + remoteconf != NULL) { + strcpy(buf->v + sizeof(struct admin_com) + index->l, + remoteconf); + } else if (id && key) { + char *data; + acp = (struct admin_com_psk *) + (buf->v + sizeof(struct admin_com) + index->l); + + acp->id_type = IDTYPE_USERFQDN; + acp->id_len = strlen(id) + 1; + acp->key_len = strlen(key) + 1; + + data = (char *)(acp + 1); + strcpy(data, id); + + data = (char *)(data + acp->id_len); + strcpy(data, key); + } + + vfree(index); + + return buf; +} + +static vchar_t * +f_vpnc(ac, av) + int ac; + char **av; +{ + char *nav[] = {NULL, NULL, NULL, NULL, NULL, NULL}; + int nac = 0; + char *isakmp = "isakmp"; + char *inet = "inet"; + char *srcaddr; + struct addrinfo hints, *res; + struct sockaddr *src; + char *idx; + + if (ac < 1) + errx(1, "insufficient arguments"); + + evt_quit_event = EVT_PHASE1_MODE_CFG; + + /* Optional -u identity */ + if (strcmp(av[0], "-u") == 0) { + if (ac < 2) + errx(1, "-u require an argument"); + + nav[nac++] = av[0]; + nav[nac++] = av[1]; + + ac -= 2; + av += 2; + } + + if (ac < 1) + errx(1, "VPN gateway required"); + if (ac > 1) + warnx("Extra arguments"); + + /* + * Find the source address + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + if (getaddrinfo(av[0], "4500", &hints, &res) != 0) + errx(1, "Cannot resolve destination address"); + + if ((src = getlocaladdr(res->ai_addr)) == NULL) + errx(1, "cannot find source address"); + + if ((srcaddr = saddr2str(src)) == NULL) + errx(1, "cannot read source address"); + + /* We get "ip[port]" strip the port */ + if ((idx = index(srcaddr, '[')) == NULL) + errx(1, "unexpected source address format"); + *idx = '\0'; + + nav[nac++] = isakmp; + nav[nac++] = inet; + nav[nac++] = srcaddr; + nav[nac++] = av[0]; + + return f_exchangesa(nac, nav); +} + +static vchar_t * +f_vpnd(ac, av) + int ac; + char **av; +{ + char *nav[] = {NULL, NULL, NULL, NULL}; + int nac = 0; + char *isakmp = "isakmp"; + char *inet = "inet"; + char *anyaddr = "0.0.0.0"; + char *idx; + + if (ac < 1) + errx(1, "VPN gateway required"); + if (ac > 1) + warnx("Extra arguments"); + + evt_quit_event = EVT_PHASE1_DOWN; + + nav[nac++] = isakmp; + nav[nac++] = inet; + nav[nac++] = anyaddr; + nav[nac++] = av[0]; + + return f_deleteallsadst(nac, nav); +} + +#ifdef ENABLE_HYBRID +static vchar_t * +f_logoutusr(ac, av) + int ac; + char **av; +{ + vchar_t *buf; + char *user; + size_t userlen; + + /* need username */ + if (ac < 1) + errx(1, "insufficient arguments"); + user = av[0]; + userlen = strlen(user); + if ((user == NULL) || (userlen > LOGINLEN)) + errx(1, "bad login (too long?)"); + + buf = make_request(ADMIN_LOGOUT_USER, 0, userlen); + if (buf == NULL) + return NULL; + + strncpy(buf->v + sizeof(struct admin_com), user, userlen); + + return buf; +} +#endif /* ENABLE_HYBRID */ + +static vchar_t * +get_proto_and_index(ac, av, proto) + int ac; + char **av; + u_int16_t *proto; +{ + vchar_t *index = NULL; + + /* need protocol */ + if (ac < 1) + errx(1, "insufficient arguments"); + *proto = get_proto(*av); + if (*proto == (u_int16_t) -1) + errx(1, "unknown protocol %s", *av); + + /* get index(es) */ + av++; + ac--; + switch (*proto) { + case ADMIN_PROTO_ISAKMP: + case ADMIN_PROTO_AH: + case ADMIN_PROTO_ESP: + index = get_index(ac, av); + break; + default: + errno = EPROTONOSUPPORT; + break; + } + return index; +} + +static int +get_proto(str) + char *str; +{ + struct proto_tag *cp; + + if (str == NULL) { + errno = EINVAL; + return -1; + } + + /* checking the string of command. */ + for (cp = &prototab[0]; cp->str; cp++) { + if (strcmp(str, cp->str) == 0) + return cp->proto; + } + + errno = EINVAL; + return -1; +} + +static vchar_t * +get_index(ac, av) + int ac; + char **av; +{ + int family; + + if (ac != 3 && ac != 4) { + errno = EINVAL; + return NULL; + } + + /* checking the string of family */ + family = get_family(*av); + if (family == -1) + return NULL; + av++; + ac--; + + return get_comindexes(family, ac, av); +} + +static int +get_family(str) + char *str; +{ + if (strcmp("inet", str) == 0) + return AF_INET; +#ifdef INET6 + else if (strcmp("inet6", str) == 0) + return AF_INET6; +#endif + errno = EAFNOSUPPORT; + return -1; +} + +static vchar_t * +get_comindexes(family, ac, av) + int family; + int ac; + char **av; +{ + vchar_t *buf; + struct admin_com_indexes *ci; + char *p_name = NULL, *p_port = NULL; + char *p_prefs = NULL, *p_prefd = NULL; + struct sockaddr *src = NULL, *dst = NULL; + int ulproto; + + if (ac != 2 && ac != 3) { + errno = EINVAL; + return NULL; + } + + if (get_comindex(*av, &p_name, &p_port, &p_prefs) == -1) + goto bad; + src = get_sockaddr(family, p_name, p_port); + if (p_name) { + racoon_free(p_name); + p_name = NULL; + } + if (p_port) { + racoon_free(p_port); + p_port = NULL; + } + if (src == NULL) + goto bad; + av++; + ac--; + if (get_comindex(*av, &p_name, &p_port, &p_prefd) == -1) + goto bad; + dst = get_sockaddr(family, p_name, p_port); + if (p_name) { + racoon_free(p_name); + p_name = NULL; + } + if (p_port) { + racoon_free(p_port); + p_port = NULL; + } + if (dst == NULL) + goto bad; + + buf = vmalloc(sizeof(*ci)); + if (buf == NULL) + goto bad; + + av++; + ac--; + if(ac){ + ulproto = get_ulproto(*av); + if (ulproto == -1) + goto bad; + }else + ulproto=0; + + ci = (struct admin_com_indexes *)buf->v; + if(p_prefs) + ci->prefs = (u_int8_t)atoi(p_prefs); /* XXX should be handled error. */ + else + ci->prefs = 32; + if(p_prefd) + ci->prefd = (u_int8_t)atoi(p_prefd); /* XXX should be handled error. */ + else + ci->prefd = 32; + ci->ul_proto = ulproto; + memcpy(&ci->src, src, sysdep_sa_len(src)); + memcpy(&ci->dst, dst, sysdep_sa_len(dst)); + + if (p_name) + racoon_free(p_name); + + return buf; + + bad: + if (p_name) + racoon_free(p_name); + if (p_port) + racoon_free(p_port); + if (p_prefs) + racoon_free(p_prefs); + if (p_prefd) + racoon_free(p_prefd); + return NULL; +} + +static int +get_comindex(str, name, port, pref) + char *str, **name, **port, **pref; +{ + char *p; + + *name = *port = *pref = NULL; + + *name = racoon_strdup(str); + STRDUP_FATAL(*name); + p = strpbrk(*name, "/["); + if (p != NULL) { + if (*(p + 1) == '\0') + goto bad; + if (*p == '/') { + *p = '\0'; + *pref = racoon_strdup(p + 1); + STRDUP_FATAL(*pref); + p = strchr(*pref, '['); + if (p != NULL) { + if (*(p + 1) == '\0') + goto bad; + *p = '\0'; + *port = racoon_strdup(p + 1); + STRDUP_FATAL(*port); + p = strchr(*pref, ']'); + if (p == NULL) + goto bad; + *p = '\0'; + } + } else if (*p == '[') { + if (*pref == NULL) + goto bad; + *p = '\0'; + *port = racoon_strdup(p + 1); + STRDUP_FATAL(*port); + p = strchr(*pref, ']'); + if (p == NULL) + goto bad; + *p = '\0'; + } else { + /* XXX */ + } + } + + return 0; + + bad: + + if (*name) + racoon_free(*name); + if (*port) + racoon_free(*port); + if (*pref) + racoon_free(*pref); + *name = *port = *pref = NULL; + return -1; +} + +static int +get_ulproto(str) + char *str; +{ + struct ulproto_tag *cp; + + if(str == NULL){ + errno = EINVAL; + return -1; + } + + /* checking the string of upper layer protocol. */ + for (cp = &ulprototab[0]; cp->str; cp++) { + if (strcmp(str, cp->str) == 0) + return cp->ul_proto; + } + + errno = EINVAL; + return -1; +} + +/* %%% */ +void +dump_isakmp_sa(buf, len) + char *buf; + int len; +{ + struct ph1dump *pd; + struct tm *tm; + char tbuf[56]; + caddr_t p = NULL; + +/* isakmp status header */ +/* short header; + 1234567890123456789012 0000000000000000:0000000000000000 000000000000 +*/ +char *header1 = +"Destination Cookies Created"; + +/* semi long header; + 1234567890123456789012 0000000000000000:0000000000000000 00 X 00 X 0000-00-00 00:00:00 000000 +*/ +char *header2 = +"Destination Cookies ST S V E Created Phase2"; + +/* long header; + 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000000000000000:0000000000000000 00 X 00 X 0000-00-00 00:00:00 000000 +*/ +char *header3 = +"Source Destination Cookies ST S V E Created Phase2"; + +/* phase status header */ +/* short format; + side stats source address destination address + xxx xxxxx 1234567890123456789012 1234567890123456789012 +*/ + + static char *estr[] = { "", "B", "M", "U", "A", "I", }; + + switch (long_format) { + case 0: + printf("%s\n", header1); + break; + case 1: + printf("%s\n", header2); + break; + case 2: + default: + printf("%s\n", header3); + break; + } + + if (len % sizeof(*pd)) + printf("invalid length %d\n", len); + len /= sizeof(*pd); + + pd = (struct ph1dump *)buf; + + while (len-- > 0) { + /* source address */ + if (long_format >= 2) { + GETNAMEINFO((struct sockaddr *)&pd->local, _addr1_, _addr2_); + switch (long_format) { + case 0: + break; + case 1: + p = fixed_addr(_addr1_, _addr2_, 22); + break; + case 2: + default: + p = fixed_addr(_addr1_, _addr2_, 45); + break; + } + printf("%s ", p); + } + + /* destination address */ + GETNAMEINFO((struct sockaddr *)&pd->remote, _addr1_, _addr2_); + switch (long_format) { + case 0: + case 1: + p = fixed_addr(_addr1_, _addr2_, 22); + break; + case 2: + default: + p = fixed_addr(_addr1_, _addr2_, 45); + break; + } + printf("%s ", p); + + printf("%s ", pindex_isakmp(&pd->index)); + + /* statuc, side and version */ + if (long_format >= 1) { + printf("%2d %c %2x ", + pd->status, + pd->side == INITIATOR ? 'I' : 'R', + pd->version); + if (ARRAYLEN(estr) > pd->etype) + printf("%s ", estr[pd->etype]); + } + + /* created date */ + if (pd->created) { + tm = localtime(&pd->created); + strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %T", tm); + } else + snprintf(tbuf, sizeof(tbuf), " "); + printf("%s ", tbuf); + + /* counter of phase 2 */ + if (long_format >= 1) + printf("%6d ", pd->ph2cnt); + + printf("\n"); + + pd++; + } + + return; +} + +/* %%% */ +void +dump_internal(buf, tlen) + char *buf; + int tlen; +{ + struct ph2handle *iph2; + struct sockaddr *addr; + +/* +short header; + source address destination address + 1234567890123456789012 1234567890123456789012 +*/ +char *short_h1 = +"Source Destination "; + +/* +long header; + source address destination address + 123456789012345678901234567890123456789012345 123456789012345678901234567890123456789012345 + 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000 +*/ +char *long_h1 = +"Source Destination "; + + printf("%s\n", long_format ? long_h1 : short_h1); + + while (tlen > 0) { + iph2 = (struct ph2handle *)buf; + addr = (struct sockaddr *)(++iph2); + + GETNAMEINFO(addr, _addr1_, _addr2_); + printf("%s ", long_format ? + fixed_addr(_addr1_, _addr2_, 45) + : fixed_addr(_addr1_, _addr2_, 22)); + addr++; + tlen -= sysdep_sa_len(addr); + + GETNAMEINFO(addr, _addr1_, _addr2_); + printf("%s ", long_format ? + fixed_addr(_addr1_, _addr2_, 45) + : fixed_addr(_addr1_, _addr2_, 22)); + addr++; + tlen -= sysdep_sa_len(addr); + + printf("\n"); + } + + return; +} + +/* %%% */ +char * +pindex_isakmp(index) + isakmp_index *index; +{ + static char buf[64]; + u_char *p; + int i, j; + + memset(buf, 0, sizeof(buf)); + + /* copy index */ + p = (u_char *)index; + for (j = 0, i = 0; i < sizeof(isakmp_index); i++) { + snprintf((char *)&buf[j], sizeof(buf) - j, "%02x", p[i]); + j += 2; + switch (i) { + case 7: +#if 0 + case 15: +#endif + buf[j++] = ':'; + } + } + + return buf; +} + +/* print schedule */ +char *str_sched_stat[] = { +"off", +"on", +"dead", +}; + +char *str_sched_id[] = { +"PH1resend", +"PH1lifetime", +"PH2resend", +"PSTacquire", +"PSTlifetime", +}; + +void +print_schedule(buf, len) + caddr_t buf; + int len; +{ + struct scheddump *sc = (struct scheddump *)buf; + struct tm *tm; + char tbuf[56]; + + if (len % sizeof(*sc)) + printf("invalid length %d\n", len); + len /= sizeof(*sc); + + /* 00000000 00000000 00000000 xxx........*/ + printf("index tick xtime created\n"); + + while (len-- > 0) { + tm = localtime(&sc->created); + strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %T", tm); + + printf("%-8ld %-8ld %-8ld %s\n", + sc->id, + (long)sc->tick, + (long)sc->xtime, + tbuf); + sc++; + } + + return; +} + + +void +print_evt(evtdump) + struct evt_async *evtdump; +{ + int i; + char *srcstr; + char *dststr; + + for (i = 0; i < sizeof(evtmsg) / sizeof(evtmsg[0]); i++) + if (evtmsg[i].type == evtdump->ec_type) + break; + + if (evtmsg[i].msg == NULL) + printf("Event %d: ", evtdump->ec_type); + else + printf("%s : ", evtmsg[i].msg); + + if ((srcstr = saddr2str((struct sockaddr *)&evtdump->ec_ph1src)) == NULL) + printf("unknown"); + else + printf("%s", srcstr); + printf(" -> "); + if ((dststr = saddr2str((struct sockaddr *)&evtdump->ec_ph1dst)) == NULL) + printf("unknown"); + else + printf("%s", dststr); + printf("\n"); +} + +/* + * Print ISAKMP mode config info (IP and banner) + */ +void +print_cfg(buf, len) + caddr_t buf; + int len; +{ + struct evt_async *evtdump = (struct evt_async *)buf; + struct isakmp_data *attr; + char *banner = NULL; + struct in_addr addr4; + + memset(&addr4, 0, sizeof(addr4)); + + if (evtdump->ec_type != EVT_PHASE1_MODE_CFG) + return; + + len -= sizeof(*evtdump); + attr = (struct isakmp_data *)(evtdump + 1); + + while (len > 0) { + if (len < sizeof(*attr)) { + printf("short attribute too short\n"); + break; + } + + if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { + /* Short attribute, skip */ + len -= sizeof(*attr); + attr++; + } else { /* Long attribute */ + char *n; + + if (len < (sizeof(*attr) + ntohs(attr->lorv))) { + printf("long attribute too long\n"); + break; + } + + switch (ntohs(attr->type) & ~ISAKMP_GEN_MASK) { + case INTERNAL_IP4_ADDRESS: + if (ntohs(attr->lorv) < sizeof(addr4)) { + printf("addr4 attribute too short\n"); + break; + } + memcpy(&addr4, attr + 1, sizeof(addr4)); + break; + + case UNITY_BANNER: + banner = racoon_malloc(ntohs(attr->lorv) + 1); + if (banner == NULL) { + printf("malloc failed\n"); + break; + } + memcpy(banner, attr + 1, ntohs(attr->lorv)); + banner[ntohs(attr->lorv)] = '\0'; + break; + + default: + break; + } + + len -= (sizeof(*attr) + ntohs(attr->lorv)); + n = (char *)attr; + attr = (struct isakmp_data *) + (n + sizeof(*attr) + ntohs(attr->lorv)); + } + } + + if (len > 0) + printf("Bound to address %s\n", inet_ntoa(addr4)); + else + printf("VPN connexion established\n"); + + if (banner) { + struct winsize win; + int col = 0; + int i; + + if (ioctl(1, TIOCGWINSZ, &win) != 1) + col = win.ws_col; + + for (i = 0; i < col; i++) + printf("%c", '='); + printf("\n%s\n", banner); + for (i = 0; i < col; i++) + printf("%c", '='); + printf("\n"); + racoon_free(banner); + } +} + + +char * +fixed_addr(addr, port, len) + char *addr, *port; + int len; +{ + static char _addr_buf_[BUFSIZ]; + char *p; + int plen, i; + + /* initialize */ + memset(_addr_buf_, ' ', sizeof(_addr_buf_)); + + plen = strlen(port); + if (len < plen + 1) + return NULL; + + p = _addr_buf_; + for (i = 0; i < len - plen - 1 && addr[i] != '\0'; /*noting*/) + *p++ = addr[i++]; + *p++ = '.'; + + for (i = 0; i < plen && port[i] != '\0'; /*noting*/) + *p++ = port[i++]; + + _addr_buf_[len] = '\0'; + + return _addr_buf_; +} + +static int +handle_recv(combuf) + vchar_t *combuf; +{ + struct admin_com *com; + caddr_t buf; + int len; + + com = (struct admin_com *)combuf->v; + if (com->ac_cmd & ADMIN_FLAG_LONG_REPLY) + len = ((u_int32_t)com->ac_len) + (((u_int32_t)com->ac_len_high) << 16); + else + len = com->ac_len; + len -= sizeof(*com); + buf = combuf->v + sizeof(*com); + + switch (com->ac_cmd & ~ADMIN_FLAG_LONG_REPLY) { + case ADMIN_SHOW_SCHED: + print_schedule(buf, len); + break; + + case ADMIN_SHOW_EVT: { + struct evt_async *ec; + + /* We got no event? */ + if (len == 0) + break; + + if (len < sizeof(struct evt_async)) + errx(1, "Short buffer\n"); + + ec = (struct evt_async *) buf; + if (evt_quit_event <= 0) + print_evt(ec); + else if (evt_quit_event == ec->ec_type) { + switch (ec->ec_type) { + case EVT_PHASE1_MODE_CFG: + print_cfg(ec, len); + break; + default: + print_evt(ec); + break; + } + evt_quit_event = 0; + } + break; + } + + case ADMIN_GET_SA_CERT: + fwrite(buf, len, 1, stdout); + break; + + case ADMIN_SHOW_SA: + { + switch (com->ac_proto) { + case ADMIN_PROTO_ISAKMP: + dump_isakmp_sa(buf, len); + break; + case ADMIN_PROTO_IPSEC: + case ADMIN_PROTO_AH: + case ADMIN_PROTO_ESP: + { + struct sadb_msg *msg = (struct sadb_msg *)buf; + + switch (msg->sadb_msg_errno) { + case ENOENT: + switch (msg->sadb_msg_type) { + case SADB_DELETE: + case SADB_GET: + printf("No entry.\n"); + break; + case SADB_DUMP: + printf("No SAD entries.\n"); + break; + } + break; + case 0: + while (1) { + pfkey_sadump(msg); + if (msg->sadb_msg_seq == 0) + break; + msg = (struct sadb_msg *)((caddr_t)msg + + PFKEY_UNUNIT64(msg->sadb_msg_len)); + } + break; + default: + printf("%s.\n", strerror(msg->sadb_msg_errno)); + } + } + break; + case ADMIN_PROTO_INTERNAL: + dump_internal(buf, len); + break; + default: + printf("Invalid proto [%d]\n", com->ac_proto); + } + + } + break; + + default: + /* IGNORE */ + break; + } + + return 0; + +bad: + return -1; +} diff --git a/ipsec-tools/src/racoon/racoonctl.h b/ipsec-tools/src/racoon/racoonctl.h new file mode 100644 index 00000000..d5072131 --- /dev/null +++ b/ipsec-tools/src/racoon/racoonctl.h @@ -0,0 +1,53 @@ +/* $NetBSD: racoonctl.h,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: racoonctl.h,v 1.3 2005/06/19 22:37:47 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _RACOONCTL_H +#define _RACOONCTL_H + +/* bumped on any change to the interface */ +#define RACOONCTL_INTERFACE 20050619 +extern u_int32_t racoonctl_interface; + +/* bumped when introducing changes that break backward compatibility */ +#define RACOONCTL_INTERFACE_MAJOR 1 +extern u_int32_t racoonctl_interface_major; + +extern u_int32_t loglevel; + +int com_init(void); +int com_send(vchar_t *); +int com_recv(vchar_t **); +struct sockaddr *get_sockaddr(int, char *, char *); + +#endif /* _RACOONCTL_H */ + diff --git a/ipsec-tools/src/racoon/remoteconf.c b/ipsec-tools/src/racoon/remoteconf.c new file mode 100644 index 00000000..04ae2687 --- /dev/null +++ b/ipsec-tools/src/racoon/remoteconf.c @@ -0,0 +1,1248 @@ +/* $NetBSD: remoteconf.c,v 1.26 2011/03/14 15:50:36 vanhu Exp $ */ + +/* Id: remoteconf.c,v 1.38 2006/05/06 15:52:44 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include PATH_IPSEC_H + +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "genlist.h" +#include "debug.h" + +#include "isakmp_var.h" +#ifdef ENABLE_HYBRID +#include "isakmp_xauth.h" +#endif +#include "isakmp.h" +#include "ipsec_doi.h" +#include "crypto_openssl.h" +#include "oakley.h" +#include "remoteconf.h" +#include "localconf.h" +#include "grabmyaddr.h" +#include "policy.h" +#include "proposal.h" +#include "vendorid.h" +#include "gcmalloc.h" +#include "strnames.h" +#include "algorithm.h" +#include "nattraversal.h" +#include "isakmp_frag.h" +#include "handler.h" +#include "genlist.h" +#include "rsalist.h" + +typedef TAILQ_HEAD(_rmtree, remoteconf) remoteconf_tailq_head_t; +static remoteconf_tailq_head_t rmtree, rmtree_save; + +/* + * Script hook names and script hook paths + */ +char *script_names[SCRIPT_MAX + 1] = { + "phase1_up", "phase1_down", "phase1_dead" }; + +/*%%%*/ + +int +rmconf_match_identity(rmconf, id_p) + struct remoteconf *rmconf; + vchar_t *id_p; +{ + struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *) id_p->v; + struct sockaddr *sa; + caddr_t sa1, sa2; + vchar_t ident; + struct idspec *id; + struct genlist_entry *gpb; + + /* compare with the ID if specified. */ + if (!genlist_next(rmconf->idvl_p, 0)) + return 0; + + for (id = genlist_next(rmconf->idvl_p, &gpb); id; id = genlist_next(0, &gpb)) { + /* No ID specified in configuration, so it is ok */ + if (id->id == 0) + return 0; + + /* check the type of both IDs */ + if (id->idtype != doi2idtype(id_b->type)) + continue; /* ID type mismatch */ + + /* compare defined ID with the ID sent by peer. */ + switch (id->idtype) { + case IDTYPE_ASN1DN: + ident.v = id_p->v + sizeof(*id_b); + ident.l = id_p->l - sizeof(*id_b); + if (eay_cmp_asn1dn(id->id, &ident) == 0) + return 0; + break; + case IDTYPE_ADDRESS: + sa = (struct sockaddr *)id->id->v; + sa2 = (caddr_t)(id_b + 1); + switch (sa->sa_family) { + case AF_INET: + if (id_p->l - sizeof(*id_b) != sizeof(struct in_addr)) + continue; /* ID value mismatch */ + sa1 = (caddr_t) &((struct sockaddr_in *)sa)->sin_addr; + if (memcmp(sa1, sa2, sizeof(struct in_addr)) == 0) + return 0; + break; +#ifdef INET6 + case AF_INET6: + if (id_p->l - sizeof(*id_b) != sizeof(struct in6_addr)) + continue; /* ID value mismatch */ + sa1 = (caddr_t) &((struct sockaddr_in6 *)sa)->sin6_addr; + if (memcmp(sa1, sa2, sizeof(struct in6_addr)) == 0) + return 0; + break; +#endif + default: + break; + } + break; + default: + if (memcmp(id->id->v, id_b + 1, id->id->l) == 0) + return 0; + break; + } + } + + plog(LLV_WARNING, LOCATION, NULL, "No ID match.\n"); + if (rmconf->verify_identifier) + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; + + return 0; +} + +static int +rmconf_match_etype_and_approval(rmconf, etype, approval) + struct remoteconf *rmconf; + int etype; + struct isakmpsa *approval; +{ + struct isakmpsa *p; + + if (check_etypeok(rmconf, (void *) (intptr_t) etype) == 0) + return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; + + if (approval == NULL) + return 0; + + if (etype == ISAKMP_ETYPE_AGG && + approval->dh_group != rmconf->dh_group) + return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; + + if (checkisakmpsa(rmconf->pcheck_level, approval, + rmconf->proposal) == NULL) + return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; + + return 0; +} + +enum rmconf_match_t { + MATCH_NONE = 0, + MATCH_BASIC = 0x0000001, + MATCH_ADDRESS = 0x0000002, + MATCH_SA = 0x0000004, + MATCH_IDENTITY = 0x0000008, + MATCH_AUTH_IDENTITY = 0x0000010, +}; + +static int +rmconf_match_type(rmsel, rmconf) + struct rmconfselector *rmsel; + struct remoteconf *rmconf; +{ + int ret = MATCH_NONE, tmp; + + /* No match at all: unwanted anonymous */ + if ((rmsel->flags & GETRMCONF_F_NO_ANONYMOUS) && + rmconf->remote->sa_family == AF_UNSPEC){ + plog(LLV_DEBUG2, LOCATION, rmsel->remote, + "Not matched: Anonymous conf.\n"); + return MATCH_NONE; + } + + if ((rmsel->flags & GETRMCONF_F_NO_PASSIVE) && rmconf->passive){ + plog(LLV_DEBUG2, LOCATION, rmsel->remote, + "Not matched: passive conf.\n"); + return MATCH_NONE; + } + + ret |= MATCH_BASIC; + + /* Check address */ + if (rmsel->remote != NULL) { + if (rmconf->remote->sa_family != AF_UNSPEC) { + if (cmpsaddr(rmsel->remote, rmconf->remote) == CMPSADDR_MISMATCH){ + plog(LLV_DEBUG2, LOCATION, rmsel->remote, + "Not matched: address mismatch.\n"); + return MATCH_NONE; + } + + /* Address matched */ + ret |= MATCH_ADDRESS; + } + } + + /* Check etype and approval */ + if (rmsel->etype != ISAKMP_ETYPE_NONE) { + tmp=rmconf_match_etype_and_approval(rmconf, rmsel->etype, + rmsel->approval); + if (tmp != 0){ + plog(LLV_DEBUG2, LOCATION, rmsel->remote, + "Not matched: etype (%d)/approval mismatch (%d).\n", rmsel->etype, tmp); + return MATCH_NONE; + } + ret |= MATCH_SA; + } + + /* Check identity */ + if (rmsel->identity != NULL && rmconf->verify_identifier) { + if (rmconf_match_identity(rmconf, rmsel->identity) != 0){ + plog(LLV_DEBUG2, LOCATION, rmsel->remote, + "Not matched: identity mismatch.\n"); + return MATCH_NONE; + } + ret |= MATCH_IDENTITY; + } + + /* Check certificate request */ + if (rmsel->certificate_request != NULL) { + if (oakley_get_certtype(rmsel->certificate_request) != + oakley_get_certtype(rmconf->mycert)){ + plog(LLV_DEBUG2, LOCATION, rmsel->remote, + "Not matched: cert type mismatch.\n"); + return MATCH_NONE; + } + + if (rmsel->certificate_request->l > 1) { + vchar_t *issuer; + + issuer = eay_get_x509asn1issuername(rmconf->mycert); + if (rmsel->certificate_request->l - 1 != issuer->l || + memcmp(rmsel->certificate_request->v + 1, + issuer->v, issuer->l) != 0) { + vfree(issuer); + plog(LLV_DEBUG2, LOCATION, rmsel->remote, + "Not matched: cert issuer mismatch.\n"); + return MATCH_NONE; + } + vfree(issuer); + } else { + if (!rmconf->match_empty_cr){ + plog(LLV_DEBUG2, LOCATION, rmsel->remote, + "Not matched: empty certificate request.\n"); + return MATCH_NONE; + } + } + + ret |= MATCH_AUTH_IDENTITY; + } + + return ret; +} + +void rmconf_selector_from_ph1(rmsel, iph1) + struct rmconfselector *rmsel; + struct ph1handle *iph1; +{ + memset(rmsel, 0, sizeof(*rmsel)); + rmsel->flags = 0; + rmsel->remote = iph1->remote; + rmsel->etype = iph1->etype; + rmsel->approval = iph1->approval; + rmsel->identity = iph1->id_p; + rmsel->certificate_request = iph1->cr_p; +} + +int +enumrmconf(rmsel, enum_func, enum_arg) + struct rmconfselector *rmsel; + int (* enum_func)(struct remoteconf *rmconf, void *arg); + void *enum_arg; +{ + struct remoteconf *p; + int ret = 0; + + RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) { + plog(LLV_DEBUG2, LOCATION, rmsel->remote, + "Checking remote conf \"%s\" %s.\n", p->name, + p->remote->sa_family == AF_UNSPEC ? + "anonymous" : saddr2str(p->remote)); + + if (rmsel != NULL) { + if (rmconf_match_type(rmsel, p) == MATCH_NONE){ + plog(LLV_DEBUG2, LOCATION, rmsel->remote, + "Not matched.\n"); + continue; + } + } + + plog(LLV_DEBUG2, LOCATION, NULL, + "enumrmconf: \"%s\" matches.\n", p->name); + + ret = (*enum_func)(p, enum_arg); + if (ret) + break; + } + + return ret; +} + +struct rmconf_find_context { + struct rmconfselector sel; + + struct remoteconf *rmconf; + int match_type; + int num_found; +}; + +static int +rmconf_find(rmconf, ctx) + struct remoteconf *rmconf; + void *ctx; +{ + struct rmconf_find_context *fctx = (struct rmconf_find_context *) ctx; + int match_type; + + /* First matching remote conf? */ + match_type = rmconf_match_type(&fctx->sel, rmconf); + + if (fctx->rmconf != NULL) { + /* More ambiguous matches are ignored. */ + if (match_type < fctx->match_type) + return 0; + + if (match_type == fctx->match_type) { + /* Ambiguous match */ + fctx->num_found++; + return 0; + } + } + + /* More exact match found */ + fctx->match_type = match_type; + fctx->num_found = 1; + fctx->rmconf = rmconf; + + return 0; +} + +/* + * search remote configuration. + * don't use port number to search if its value is either IPSEC_PORT_ANY. + * If matching anonymous entry, then new entry is copied from anonymous entry. + * If no anonymous entry found, then return NULL. + * OUT: NULL: NG + * Other: remote configuration entry. + */ + +struct remoteconf * +getrmconf(remote, flags) + struct sockaddr *remote; + int flags; +{ + struct rmconf_find_context ctx; + int n = 0; + + memset(&ctx, 0, sizeof(ctx)); + ctx.sel.flags = flags; + ctx.sel.remote = remote; + + if (enumrmconf(&ctx.sel, rmconf_find, &ctx) != 0) { + plog(LLV_ERROR, LOCATION, remote, + "multiple exact configurations.\n"); + return NULL; + } + + if (ctx.rmconf == NULL) { + plog(LLV_DEBUG, LOCATION, remote, + "no remote configuration found.\n"); + return NULL; + } + + if (ctx.num_found != 1) { + plog(LLV_DEBUG, LOCATION, remote, + "multiple non-exact configurations found.\n"); + return NULL; + } + + plog(LLV_DEBUG, LOCATION, remote, + "configuration \"%s\" selected.\n", + ctx.rmconf->name); + + return ctx.rmconf; +} + +struct remoteconf * +getrmconf_by_ph1(iph1) + struct ph1handle *iph1; +{ + struct rmconf_find_context ctx; + + memset(&ctx, 0, sizeof(ctx)); + rmconf_selector_from_ph1(&ctx.sel, iph1); + if (loglevel >= LLV_DEBUG) { + char *idstr = NULL; + + if (iph1->id_p != NULL) + idstr = ipsecdoi_id2str(iph1->id_p); + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "getrmconf_by_ph1: remote %s, identity %s.\n", + saddr2str(iph1->remote), idstr ? idstr : ""); + + if (idstr) + racoon_free(idstr); + } + + if (enumrmconf(&ctx.sel, rmconf_find, &ctx) != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "multiple exact configurations.\n"); + return RMCONF_ERR_MULTIPLE; + } + + if (ctx.rmconf == NULL) { + plog(LLV_DEBUG, LOCATION, iph1->remote, + "no remote configuration found\n"); + return NULL; + } + + if (ctx.num_found != 1) { + plog(LLV_DEBUG, LOCATION, iph1->remote, + "multiple non-exact configurations found.\n"); + return RMCONF_ERR_MULTIPLE; + } + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "configuration \"%s\" selected.\n", + ctx.rmconf->name); + + return ctx.rmconf; +} + +struct remoteconf * +getrmconf_by_name(name) + const char *name; +{ + struct remoteconf *p; + + plog(LLV_DEBUG, LOCATION, NULL, + "getrmconf_by_name: remote \"%s\".\n", + name); + + RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) { + if (p->name == NULL) + continue; + + if (strcmp(name, p->name) == 0) + return p; + } + + return NULL; +} + +struct remoteconf * +newrmconf() +{ + struct remoteconf *new; + int i; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) + return NULL; + + new->proposal = NULL; + + /* set default */ + new->doitype = IPSEC_DOI; + new->sittype = IPSECDOI_SIT_IDENTITY_ONLY; + new->idvtype = IDTYPE_UNDEFINED; + new->idvl_p = genlist_init(); + new->nonce_size = DEFAULT_NONCE_SIZE; + new->passive = FALSE; + new->ike_frag = FALSE; + new->esp_frag = IP_MAXPACKET; + new->ini_contact = TRUE; + new->mode_cfg = FALSE; + new->pcheck_level = PROP_CHECK_STRICT; + new->verify_identifier = FALSE; + new->verify_cert = TRUE; + new->cacertfile = NULL; + new->send_cert = TRUE; + new->send_cr = TRUE; + new->match_empty_cr = FALSE; + new->support_proxy = FALSE; + for (i = 0; i <= SCRIPT_MAX; i++) + new->script[i] = NULL; + new->gen_policy = FALSE; + new->nat_traversal = FALSE; + new->rsa_private = genlist_init(); + new->rsa_public = genlist_init(); + new->idv = NULL; + new->key = NULL; + + new->dpd = TRUE; /* Enable DPD support by default */ + new->dpd_interval = 0; /* Disable DPD checks by default */ + new->dpd_retry = 5; + new->dpd_maxfails = 5; + + new->rekey = REKEY_ON; + + new->weak_phase1_check = 0; + +#ifdef ENABLE_HYBRID + new->xauth = NULL; +#endif + + new->lifetime = oakley_get_defaultlifetime(); + + return new; +} + +void * +dupidvl(entry, arg) + void *entry; + void *arg; +{ + struct idspec *id; + struct idspec *old = (struct idspec *) entry; + id = newidspec(); + if (!id) return (void *) -1; + + if (set_identifier(&id->id, old->idtype, old->id) != 0) { + racoon_free(id); + return (void *) -1; + } + + id->idtype = old->idtype; + + genlist_append(arg, id); + return NULL; +} + +void * +duprsa(entry, arg) + void *entry; + void *arg; +{ + struct rsa_key *new; + + new = rsa_key_dup((struct rsa_key *)entry); + if (new == NULL) + return (void *) -1; + genlist_append(arg, new); + + /* keep genlist_foreach going */ + return NULL; +} + +/* Creates shallow copy of a remote config. Used for "inherit" keyword. */ +struct remoteconf * +duprmconf_shallow (rmconf) + struct remoteconf *rmconf; +{ + struct remoteconf *new; + struct proposalspec *prspec; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) + return NULL; + + memcpy(new, rmconf, sizeof(*new)); + new->name = NULL; + new->inherited_from = rmconf; + + new->proposal = NULL; /* will be filled by set_isakmp_proposal() */ + + return new; +} + +/* Copies pointer structures of an inherited remote config. + * Used by "inherit" mechanism in a two step copy method, necessary to + * prevent both double free() and memory leak during config reload. + */ +int +duprmconf_finish (new) + struct remoteconf *new; +{ + struct remoteconf *rmconf; + int i; + + if (new->inherited_from == NULL) + return 0; /* nothing todo, no inheritance */ + + rmconf = new->inherited_from; + + /* duplicate dynamic structures unless value overridden */ + if (new->etypes != NULL && new->etypes == rmconf->etypes) + new->etypes = dupetypes(new->etypes); + if (new->idvl_p == rmconf->idvl_p) { + new->idvl_p = genlist_init(); + genlist_foreach(rmconf->idvl_p, dupidvl, new->idvl_p); + } + + if (new->rsa_private == rmconf->rsa_private) { + new->rsa_private = genlist_init(); + genlist_foreach(rmconf->rsa_private, duprsa, new->rsa_private); + } + if (new->rsa_public == rmconf->rsa_public) { + new->rsa_public = genlist_init(); + genlist_foreach(rmconf->rsa_public, duprsa, new->rsa_public); + } + if (new->remote != NULL && new->remote == rmconf->remote) { + new->remote = racoon_malloc(sizeof(*new->remote)); + if (new->remote == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "duprmconf_finish: malloc failed (remote)\n"); + exit(1); + } + memcpy(new->remote, rmconf->remote, sizeof(*new->remote)); + } + if (new->spspec != NULL && new->spspec == rmconf->spspec) { + dupspspec_list(new, rmconf); + } + + /* proposal has been deep copied already from spspec's, see + * cfparse.y:set_isakmp_proposal, which in turn calls + * cfparse.y:expand_isakmpspec where the copying happens. + */ + +#ifdef ENABLE_HYBRID + if (new->xauth != NULL && new->xauth == rmconf->xauth) { + new->xauth = xauth_rmconf_dup(new->xauth); + if (new->xauth == NULL) + exit(1); + } +#endif + + /* duplicate strings unless value overridden */ + if (new->mycertfile != NULL && new->mycertfile == rmconf->mycertfile) { + new->mycertfile = racoon_strdup(new->mycertfile); + STRDUP_FATAL(new->mycertfile); + } + if (new->myprivfile != NULL && new->myprivfile == rmconf->myprivfile) { + new->myprivfile = racoon_strdup(new->myprivfile); + STRDUP_FATAL(new->myprivfile); + } + if (new->peerscertfile != NULL && new->peerscertfile == rmconf->peerscertfile) { + new->peerscertfile = racoon_strdup(new->peerscertfile); + STRDUP_FATAL(new->peerscertfile); + } + if (new->cacertfile != NULL && new->cacertfile == rmconf->cacertfile) { + new->cacertfile = racoon_strdup(new->cacertfile); + STRDUP_FATAL(new->cacertfile); + } + if (new->idv != NULL && new->idv == rmconf->idv) { + new->idv = vdup(new->idv); + STRDUP_FATAL(new->idv); + } + if (new->key != NULL && new->key == rmconf->key) { + new->key = vdup(new->key); + STRDUP_FATAL(new->key); + } + if (new->mycert != NULL && new->mycert == rmconf->mycert) { + new->mycert = vdup(new->mycert); + STRDUP_FATAL(new->mycert); + } + if (new->peerscert != NULL && new->peerscert == rmconf->peerscert) { + new->peerscert = vdup(new->peerscert); + STRDUP_FATAL(new->peerscert); + } + if (new->cacert != NULL && new->cacert == rmconf->cacert) { + new->cacert = vdup(new->cacert); + STRDUP_FATAL(new->cacert); + } + for (i = 0; i <= SCRIPT_MAX; i++) + if (new->script[i] != NULL && new->script[i] == rmconf->script[i]) { + new->script[i] = vdup(new->script[i]); + STRDUP_FATAL(new->script[i]); + } + + return 0; +} + +static void +idspec_free(void *data) +{ + vfree (((struct idspec *)data)->id); + free (data); +} + +void +delrmconf(rmconf) + struct remoteconf *rmconf; +{ + int i; + +#ifdef ENABLE_HYBRID + if (rmconf->xauth) + xauth_rmconf_delete(&rmconf->xauth); +#endif + if (rmconf->etypes){ + deletypes(rmconf->etypes); + rmconf->etypes=NULL; + } + if (rmconf->idv) + vfree(rmconf->idv); + if (rmconf->key) + vfree(rmconf->key); + if (rmconf->idvl_p) + genlist_free(rmconf->idvl_p, idspec_free); + if (rmconf->dhgrp) + oakley_dhgrp_free(rmconf->dhgrp); + if (rmconf->proposal) + delisakmpsa(rmconf->proposal); + flushspspec(rmconf); + if (rmconf->mycert) + vfree(rmconf->mycert); + if (rmconf->mycertfile) + racoon_free(rmconf->mycertfile); + if (rmconf->myprivfile) + racoon_free(rmconf->myprivfile); + if (rmconf->peerscert) + vfree(rmconf->peerscert); + if (rmconf->peerscertfile) + racoon_free(rmconf->peerscertfile); + if (rmconf->cacert) + vfree(rmconf->cacert); + if (rmconf->cacertfile) + racoon_free(rmconf->cacertfile); + if (rmconf->rsa_private) + genlist_free(rmconf->rsa_private, rsa_key_free); + if (rmconf->rsa_public) + genlist_free(rmconf->rsa_public, rsa_key_free); + if (rmconf->name) + racoon_free(rmconf->name); + if (rmconf->remote) + racoon_free(rmconf->remote); + for (i = 0; i <= SCRIPT_MAX; i++) + if (rmconf->script[i]) + vfree(rmconf->script[i]); + + racoon_free(rmconf); +} + +void +delisakmpsa(sa) + struct isakmpsa *sa; +{ + if (sa->dhgrp) + oakley_dhgrp_free(sa->dhgrp); + if (sa->next) + delisakmpsa(sa->next); +#ifdef HAVE_GSSAPI + if (sa->gssid) + vfree(sa->gssid); +#endif + racoon_free(sa); +} + +struct etypes * +dupetypes(orig) + struct etypes *orig; +{ + struct etypes *new; + + if (!orig) + return NULL; + + new = racoon_malloc(sizeof(struct etypes)); + if (new == NULL) + return NULL; + + new->type = orig->type; + new->next = NULL; + + if (orig->next) + new->next=dupetypes(orig->next); + + return new; +} + +void +deletypes(e) + struct etypes *e; +{ + if (e->next) + deletypes(e->next); + racoon_free(e); +} + +/* + * insert into head of list. + */ +void +insrmconf(new) + struct remoteconf *new; +{ + if (new->name == NULL) { + new->name = racoon_strdup(saddr2str(new->remote)); + } + if (new->remote == NULL) { + new->remote = newsaddr(sizeof(struct sockaddr)); + new->remote->sa_family = AF_UNSPEC; + } + + TAILQ_INSERT_HEAD(&rmtree, new, chain); +} + +void +remrmconf(rmconf) + struct remoteconf *rmconf; +{ + TAILQ_REMOVE(&rmtree, rmconf, chain); +} + +void +flushrmconf() +{ + struct remoteconf *p, *next; + + for (p = TAILQ_FIRST(&rmtree); p; p = next) { + next = TAILQ_NEXT(p, chain); + remrmconf(p); + delrmconf(p); + } +} + +void +initrmconf() +{ + TAILQ_INIT(&rmtree); +} + +void +rmconf_start_reload() +{ + rmtree_save=rmtree; + initrmconf(); +} + +void +rmconf_finish_reload() +{ + remoteconf_tailq_head_t rmtree_tmp; + + rmtree_tmp=rmtree; + rmtree=rmtree_save; + flushrmconf(); + initrmconf(); + rmtree=rmtree_tmp; +} + + + +/* check exchange type to be acceptable */ +int +check_etypeok(rmconf, ctx) + struct remoteconf *rmconf; + void *ctx; +{ + u_int8_t etype = (u_int8_t) (intptr_t) ctx; + struct etypes *e; + + for (e = rmconf->etypes; e != NULL; e = e->next) { + if (e->type == etype) + return 1; + plog(LLV_DEBUG2, LOCATION, NULL, + "Etype mismatch: got %d, expected %d.\n", e->type, etype); + } + + return 0; +} + +/*%%%*/ +struct isakmpsa * +newisakmpsa() +{ + struct isakmpsa *new; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) + return NULL; + + /* + * Just for sanity, make sure this is initialized. This is + * filled in for real when the ISAKMP proposal is configured. + */ + new->vendorid = VENDORID_UNKNOWN; + + new->next = NULL; +#ifdef HAVE_GSSAPI + new->gssid = NULL; +#endif + + return new; +} + +/* + * insert into tail of list. + */ +void +insisakmpsa(new, rmconf) + struct isakmpsa *new; + struct remoteconf *rmconf; +{ + struct isakmpsa *p; + + if (rmconf->proposal == NULL) { + rmconf->proposal = new; + return; + } + + for (p = rmconf->proposal; p->next != NULL; p = p->next) + ; + p->next = new; +} + +static void * +dump_peers_identifiers (void *entry, void *arg) +{ + struct idspec *id = (struct idspec*) entry; + char buf[1024], *pbuf; + pbuf = buf; + pbuf += sprintf (pbuf, "\tpeers_identifier %s", + s_idtype (id->idtype)); + if (id->id) + pbuf += sprintf (pbuf, " \"%s\"", id->id->v); + plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); + return NULL; +} + +static int +dump_rmconf_single (struct remoteconf *p, void *data) +{ + struct etypes *etype = p->etypes; + struct isakmpsa *prop = p->proposal; + char buf[1024], *pbuf; + + pbuf = buf; + + pbuf += sprintf(pbuf, "remote \"%s\"", p->name); + if (p->inherited_from) + pbuf += sprintf(pbuf, " inherit \"%s\"", + p->inherited_from->name); + plog(LLV_INFO, LOCATION, NULL, "%s {\n", buf); + pbuf = buf; + pbuf += sprintf(pbuf, "\texchange_type "); + while (etype) { + pbuf += sprintf (pbuf, "%s%s", s_etype(etype->type), + etype->next != NULL ? ", " : ";\n"); + etype = etype->next; + } + plog(LLV_INFO, LOCATION, NULL, "%s", buf); + plog(LLV_INFO, LOCATION, NULL, "\tdoi %s;\n", s_doi(p->doitype)); + pbuf = buf; + pbuf += sprintf(pbuf, "\tmy_identifier %s", s_idtype (p->idvtype)); + if (p->idvtype == IDTYPE_ASN1DN) { + plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); + plog(LLV_INFO, LOCATION, NULL, + "\tcertificate_type %s \"%s\" \"%s\";\n", + oakley_get_certtype(p->mycert) == ISAKMP_CERT_X509SIGN + ? "x509" : "*UNKNOWN*", + p->mycertfile, p->myprivfile); + + switch (oakley_get_certtype(p->peerscert)) { + case ISAKMP_CERT_NONE: + plog(LLV_INFO, LOCATION, NULL, + "\t/* peers certificate from payload */\n"); + break; + case ISAKMP_CERT_X509SIGN: + plog(LLV_INFO, LOCATION, NULL, + "\tpeers_certfile \"%s\";\n", p->peerscertfile); + break; + case ISAKMP_CERT_DNS: + plog(LLV_INFO, LOCATION, NULL, + "\tpeers_certfile dnssec;\n"); + break; + default: + plog(LLV_INFO, LOCATION, NULL, + "\tpeers_certfile *UNKNOWN* (%d)\n", + oakley_get_certtype(p->peerscert)); + break; + } + } + else { + if (p->idv) + pbuf += sprintf (pbuf, " \"%s\"", p->idv->v); + plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); + genlist_foreach(p->idvl_p, &dump_peers_identifiers, NULL); + } + + plog(LLV_INFO, LOCATION, NULL, "\trekey %s;\n", + p->rekey == REKEY_FORCE ? "force" : s_switch (p->rekey)); + plog(LLV_INFO, LOCATION, NULL, "\tsend_cert %s;\n", + s_switch (p->send_cert)); + plog(LLV_INFO, LOCATION, NULL, "\tsend_cr %s;\n", + s_switch (p->send_cr)); + plog(LLV_INFO, LOCATION, NULL, "\tmatch_empty_cr %s;\n", + s_switch (p->match_empty_cr)); + plog(LLV_INFO, LOCATION, NULL, "\tverify_cert %s;\n", + s_switch (p->verify_cert)); + plog(LLV_INFO, LOCATION, NULL, "\tverify_identifier %s;\n", + s_switch (p->verify_identifier)); + plog(LLV_INFO, LOCATION, NULL, "\tnat_traversal %s;\n", + p->nat_traversal == NATT_FORCE ? + "force" : s_switch (p->nat_traversal)); + plog(LLV_INFO, LOCATION, NULL, "\tnonce_size %d;\n", + p->nonce_size); + plog(LLV_INFO, LOCATION, NULL, "\tpassive %s;\n", + s_switch (p->passive)); + plog(LLV_INFO, LOCATION, NULL, "\tike_frag %s;\n", + p->ike_frag == ISAKMP_FRAG_FORCE ? + "force" : s_switch (p->ike_frag)); + plog(LLV_INFO, LOCATION, NULL, "\tesp_frag %d;\n", p->esp_frag); + plog(LLV_INFO, LOCATION, NULL, "\tinitial_contact %s;\n", + s_switch (p->ini_contact)); + plog(LLV_INFO, LOCATION, NULL, "\tgenerate_policy %s;\n", + s_switch (p->gen_policy)); + plog(LLV_INFO, LOCATION, NULL, "\tsupport_proxy %s;\n", + s_switch (p->support_proxy)); + + while (prop) { + plog(LLV_INFO, LOCATION, NULL, "\n"); + plog(LLV_INFO, LOCATION, NULL, + "\t/* prop_no=%d, trns_no=%d */\n", + prop->prop_no, prop->trns_no); + plog(LLV_INFO, LOCATION, NULL, "\tproposal {\n"); + plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime time %lu sec;\n", + (long)prop->lifetime); + plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime bytes %zd;\n", + prop->lifebyte); + plog(LLV_INFO, LOCATION, NULL, "\t\tdh_group %s;\n", + alg_oakley_dhdef_name(prop->dh_group)); + plog(LLV_INFO, LOCATION, NULL, "\t\tencryption_algorithm %s;\n", + alg_oakley_encdef_name(prop->enctype)); + plog(LLV_INFO, LOCATION, NULL, "\t\thash_algorithm %s;\n", + alg_oakley_hashdef_name(prop->hashtype)); + plog(LLV_INFO, LOCATION, NULL, "\t\tauthentication_method %s;\n", + alg_oakley_authdef_name(prop->authmethod)); + plog(LLV_INFO, LOCATION, NULL, "\t}\n"); + prop = prop->next; + } + plog(LLV_INFO, LOCATION, NULL, "}\n"); + plog(LLV_INFO, LOCATION, NULL, "\n"); + + return 0; +} + +void +dumprmconf() +{ + enumrmconf(NULL, dump_rmconf_single, NULL); +} + +struct idspec * +newidspec() +{ + struct idspec *new; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) + return NULL; + new->idtype = IDTYPE_ADDRESS; + + return new; +} + +vchar_t * +script_path_add(path) + vchar_t *path; +{ + char *script_dir; + vchar_t *new_path; + vchar_t *new_storage; + vchar_t **sp; + size_t len; + size_t size; + + script_dir = lcconf->pathinfo[LC_PATHTYPE_SCRIPT]; + + /* Try to find the script in the script directory */ + if ((path->v[0] != '/') && (script_dir != NULL)) { + len = strlen(script_dir) + sizeof("/") + path->l + 1; + + if ((new_path = vmalloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return NULL; + } + + new_path->v[0] = '\0'; + (void)strlcat(new_path->v, script_dir, len); + (void)strlcat(new_path->v, "/", len); + (void)strlcat(new_path->v, path->v, len); + + vfree(path); + path = new_path; + } + + return path; +} + + +struct isakmpsa * +dupisakmpsa(struct isakmpsa *sa) +{ + struct isakmpsa *res = NULL; + + if(sa == NULL) + return NULL; + + res = newisakmpsa(); + if(res == NULL) + return NULL; + + *res = *sa; +#ifdef HAVE_GSSAPI + if (sa->gssid != NULL) + res->gssid = vdup(sa->gssid); +#endif + res->next = NULL; + + if(sa->dhgrp != NULL) + oakley_setdhgroup(sa->dh_group, &res->dhgrp); + + return res; + +} + +#ifdef ENABLE_HYBRID +int +isakmpsa_switch_authmethod(authmethod) + int authmethod; +{ + switch(authmethod) { + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I; + break; + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I; + break; + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I; + break; + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I; + break; + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I; + break; + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I; + break; + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: + authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I; + break; + default: + break; + } + + return authmethod; +} +#endif + +/* + * Given a proposed ISAKMP SA, and a list of acceptable + * ISAKMP SAs, it compares using pcheck_level policy and + * returns first match (if any). + */ +struct isakmpsa * +checkisakmpsa(pcheck_level, proposal, acceptable) + int pcheck_level; + struct isakmpsa *proposal, *acceptable; +{ + struct isakmpsa *p; + + for (p = acceptable; p != NULL; p = p->next){ + plog(LLV_DEBUG2, LOCATION, NULL, + "checkisakmpsa:\nauthmethod: %d / %d\n", + isakmpsa_switch_authmethod(proposal->authmethod), isakmpsa_switch_authmethod(p->authmethod)); + if (isakmpsa_switch_authmethod(proposal->authmethod) != isakmpsa_switch_authmethod(p->authmethod) || + proposal->enctype != p->enctype || + proposal->dh_group != p->dh_group || + proposal->hashtype != p->hashtype) + continue; + + switch (pcheck_level) { + case PROP_CHECK_OBEY: + break; + + case PROP_CHECK_CLAIM: + case PROP_CHECK_STRICT: + if (proposal->encklen < p->encklen || +#if 0 + proposal->lifebyte > p->lifebyte || +#endif + proposal->lifetime > p->lifetime) + continue; + break; + + case PROP_CHECK_EXACT: + if (proposal->encklen != p->encklen || +#if 0 + proposal->lifebyte != p->lifebyte || +#endif + proposal->lifetime != p->lifetime) + continue; + break; + + default: + continue; + } + + return p; + } + + return NULL; +} diff --git a/ipsec-tools/src/racoon/remoteconf.h b/ipsec-tools/src/racoon/remoteconf.h new file mode 100644 index 00000000..3ebe004e --- /dev/null +++ b/ipsec-tools/src/racoon/remoteconf.h @@ -0,0 +1,243 @@ +/* $NetBSD: remoteconf.h,v 1.16 2011/03/14 15:50:36 vanhu Exp $ */ + +/* Id: remoteconf.h,v 1.26 2006/05/06 15:52:44 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _REMOTECONF_H +#define _REMOTECONF_H + +/* remote configuration */ + +#include +#include "genlist.h" +#ifdef ENABLE_HYBRID +#include "isakmp_var.h" +#include "isakmp_xauth.h" +#endif + +struct ph1handle; +struct secprotospec; + +struct etypes { + int type; + struct etypes *next; +}; + +/* ISAKMP SA specification */ +struct isakmpsa { + int prop_no; + int trns_no; + time_t lifetime; + size_t lifebyte; + int enctype; + int encklen; + int authmethod; + int hashtype; + int vendorid; +#ifdef HAVE_GSSAPI + vchar_t *gssid; +#endif + int dh_group; /* don't use it if aggressive mode */ + struct dhgroup *dhgrp; /* don't use it if aggressive mode */ + + struct isakmpsa *next; /* next transform */ +}; + +/* Certificate information */ +struct rmconf_cert { + vchar_t *data; /* certificate payload */ + char *filename; /* name of local file */ +}; + +/* Script hooks */ +#define SCRIPT_PHASE1_UP 0 +#define SCRIPT_PHASE1_DOWN 1 +#define SCRIPT_PHASE1_DEAD 2 +#define SCRIPT_MAX 2 +extern char *script_names[SCRIPT_MAX + 1]; + +struct remoteconf { + char *name; /* remote configuration name */ + struct sockaddr *remote; /* remote IP address */ + /* if family is AF_UNSPEC, that is + * for anonymous configuration. */ + + struct etypes *etypes; /* exchange type list. the head + * is a type to be sent first. */ + int doitype; /* doi type */ + int sittype; /* situation type */ + + int idvtype; /* my identifier type */ + vchar_t *idv; /* my identifier */ + vchar_t *key; /* my pre-shared key */ + struct genlist *idvl_p; /* peer's identifiers list */ + + char *myprivfile; /* file name of my private key file */ + char *mycertfile; /* file name of my certificate */ + vchar_t *mycert; /* my certificate */ + char *peerscertfile; /* file name of peer's certifcate */ + vchar_t *peerscert; /* peer's certificate */ + char *cacertfile; /* file name of CA */ + vchar_t *cacert; /* CA certificate */ + + int send_cert; /* send to CERT or not */ + int send_cr; /* send to CR or not */ + int match_empty_cr; /* does this match if CR is empty */ + int verify_cert; /* verify a CERT strictly */ + int verify_identifier; /* vefify the peer's identifier */ + int nonce_size; /* the number of bytes of nonce */ + int passive; /* never initiate */ + int ike_frag; /* IKE fragmentation */ + int esp_frag; /* ESP fragmentation */ + int mode_cfg; /* Gets config through mode config */ + int support_proxy; /* support mip6/proxy */ +#define GENERATE_POLICY_NONE 0 +#define GENERATE_POLICY_REQUIRE 1 +#define GENERATE_POLICY_UNIQUE 2 + int gen_policy; /* generate policy if no policy found */ + int ini_contact; /* initial contact */ + int pcheck_level; /* level of propocl checking */ + int nat_traversal; /* NAT-Traversal */ + vchar_t *script[SCRIPT_MAX + 1];/* script hooks paths */ + int dh_group; /* use it when only aggressive mode */ + struct dhgroup *dhgrp; /* use it when only aggressive mode */ + /* above two can't be defined by user*/ + + int dpd; /* Negociate DPD support ? */ + int dpd_retry; /* in seconds */ + int dpd_interval; /* in seconds */ + int dpd_maxfails; + + int rekey; /* rekey ph1 when active ph2s? */ +#define REKEY_OFF FALSE +#define REKEY_ON TRUE +#define REKEY_FORCE 2 + + uint32_t ph1id; /* ph1id to be matched with sainfo sections */ + + int weak_phase1_check; /* act on unencrypted deletions ? */ + + struct isakmpsa *proposal; /* proposal list */ + struct remoteconf *inherited_from; /* the original rmconf + from which this one + was inherited */ + + time_t lifetime; /* for isakmp/ipsec */ + int lifebyte; /* for isakmp/ipsec */ + struct secprotospec *spspec; /* the head is always current spec. */ + + struct genlist *rsa_private, /* lists of PlainRSA keys to use */ + *rsa_public; + +#ifdef ENABLE_HYBRID + struct xauth_rmconf *xauth; +#endif + + TAILQ_ENTRY(remoteconf) chain; /* next remote conf */ +}; + +#define RMCONF_NONCE_SIZE(rmconf) \ + (rmconf != NULL ? rmconf->nonce_size : DEFAULT_NONCE_SIZE) + +struct dhgroup; + +struct idspec { + int idtype; /* identifier type */ + vchar_t *id; /* identifier */ +}; + +struct rmconfselector { + int flags; + struct sockaddr *remote; + int etype; + struct isakmpsa *approval; + vchar_t *identity; + vchar_t *certificate_request; +}; + +extern void rmconf_selector_from_ph1 __P((struct rmconfselector *rmsel, + struct ph1handle *iph1)); +extern int enumrmconf __P((struct rmconfselector *rmsel, + int (* enum_func)(struct remoteconf *rmconf, void *arg), + void *enum_arg)); + +#define GETRMCONF_F_NO_ANONYMOUS 0x0001 +#define GETRMCONF_F_NO_PASSIVE 0x0002 + +#define RMCONF_ERR_MULTIPLE ((struct remoteconf *) -1) + +extern int rmconf_match_identity __P((struct remoteconf *rmconf, + vchar_t *id_p)); +extern struct remoteconf *getrmconf __P((struct sockaddr *remote, int flags)); +extern struct remoteconf *getrmconf_by_ph1 __P((struct ph1handle *iph1)); +extern struct remoteconf *getrmconf_by_name __P((const char *name)); + +extern struct remoteconf *newrmconf __P((void)); +extern struct remoteconf *duprmconf_shallow __P((struct remoteconf *)); +extern int duprmconf_finish __P((struct remoteconf *)); +extern void delrmconf __P((struct remoteconf *)); +extern void deletypes __P((struct etypes *)); +extern struct etypes * dupetypes __P((struct etypes *)); +extern void insrmconf __P((struct remoteconf *)); +extern void remrmconf __P((struct remoteconf *)); +extern void flushrmconf __P((void)); +extern void dupspspec_list __P((struct remoteconf *, struct remoteconf *)); +extern void flushspspec __P((struct remoteconf *)); +extern void initrmconf __P((void)); +extern void rmconf_start_reload __P((void)); +extern void rmconf_finish_reload __P((void)); + +extern int check_etypeok __P((struct remoteconf *, void *)); + +extern struct isakmpsa *newisakmpsa __P((void)); +extern struct isakmpsa *dupisakmpsa __P((struct isakmpsa *)); +extern void delisakmpsa __P((struct isakmpsa *)); +extern void insisakmpsa __P((struct isakmpsa *, struct remoteconf *)); +#ifdef ENABLE_HYBRID +extern int isakmpsa_switch_authmethod __P((int authmethod)); +#else +static inline int isakmpsa_switch_authmethod(int authmethod) +{ + return authmethod; +} +#endif +extern struct isakmpsa * checkisakmpsa __P((int pcheck, + struct isakmpsa *proposal, + struct isakmpsa *acceptable)); + + +extern void dumprmconf __P((void)); + +extern struct idspec *newidspec __P((void)); + +extern vchar_t *script_path_add __P((vchar_t *)); + +#endif /* _REMOTECONF_H */ diff --git a/ipsec-tools/src/racoon/rsalist.c b/ipsec-tools/src/racoon/rsalist.c new file mode 100644 index 00000000..f152c825 --- /dev/null +++ b/ipsec-tools/src/racoon/rsalist.c @@ -0,0 +1,275 @@ +/* $NetBSD: rsalist.c,v 1.6 2011/03/14 15:50:36 vanhu Exp $ */ + +/* Id: rsalist.c,v 1.3 2004/11/08 12:04:23 ludvigm Exp */ + +/* + * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. + * Contributed by: Michal Ludvig , SUSE Labs + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "misc.h" +#include "plog.h" +#include "sockmisc.h" +#include "rsalist.h" +#include "genlist.h" +#include "remoteconf.h" +#include "crypto_openssl.h" + +#ifndef LIST_FIRST +#define LIST_FIRST(head) ((head)->lh_first) +#endif + +#ifndef LIST_NEXT +#define LIST_NEXT(elm, field) ((elm)->field.le_next) +#endif + +/* from prsa_tok.l */ +int prsa_parse_file(struct genlist *list, const char *fname, enum rsa_key_type type); + +int +rsa_key_insert(struct genlist *list, struct netaddr *src, + struct netaddr *dst, RSA *rsa) +{ + struct rsa_key *rsa_key; + + rsa_key = calloc(sizeof(struct rsa_key), 1); + rsa_key->rsa = rsa; + + if (src) + rsa_key->src = src; + else + rsa_key->src = calloc(sizeof(*rsa_key->src), 1); + + if (dst) + rsa_key->dst = dst; + else + rsa_key->dst = calloc(sizeof(*rsa_key->dst), 1); + + genlist_append(list, rsa_key); + + return 0; +} + +struct rsa_key * +rsa_key_dup(struct rsa_key *key) +{ + struct rsa_key *new; + + new = calloc(sizeof(struct rsa_key), 1); + if (new == NULL) + return NULL; + + if (key->rsa) { + new->rsa = key->rsa->d != NULL ? RSAPrivateKey_dup(key->rsa) : RSAPublicKey_dup(key->rsa); + if (new->rsa == NULL) + goto dup_error; + } + + if (key->src) { + new->src = malloc(sizeof(*new->src)); + if (new->src == NULL) + goto dup_error; + memcpy(new->src, key->src, sizeof(*new->src)); + } + if (key->dst) { + new->dst = malloc(sizeof(*new->dst)); + if (new->dst == NULL) + goto dup_error; + memcpy(new->dst, key->dst, sizeof(*new->dst)); + } + + return new; + +dup_error: + if (new->rsa != NULL) + RSA_free(new->rsa); + if (new->dst != NULL) + free(new->dst); + if (new->src != NULL) + free(new->src); + + free(new); + return NULL; +} + +void +rsa_key_free(void *data) +{ + struct rsa_key *rsa_key; + + + rsa_key = (struct rsa_key *)data; + if (rsa_key->src) + free(rsa_key->src); + if (rsa_key->dst) + free(rsa_key->dst); + if (rsa_key->rsa) + RSA_free(rsa_key->rsa); + + free(rsa_key); +} + +static void * +rsa_key_dump_one(void *entry, void *arg) +{ + struct rsa_key *key = entry; + + plog(LLV_DEBUG, LOCATION, NULL, "Entry %s\n", + naddrwop2str_fromto("%s -> %s", key->src, + key->dst)); + if (loglevel > LLV_DEBUG) + RSA_print_fp(stdout, key->rsa, 4); + + return NULL; +} + +void +rsa_key_dump(struct genlist *list) +{ + genlist_foreach(list, rsa_key_dump_one, NULL); +} + +static void * +rsa_list_count_one(void *entry, void *arg) +{ + if (arg) + (*(unsigned long *)arg)++; + return NULL; +} + +unsigned long +rsa_list_count(struct genlist *list) +{ + unsigned long count = 0; + genlist_foreach(list, rsa_list_count_one, &count); + return count; +} + +struct lookup_result { + struct ph1handle *iph1; + int max_score; + struct genlist *winners; +}; + +static void * +rsa_lookup_key_one(void *entry, void *data) +{ + int local_score, remote_score; + struct lookup_result *req = data; + struct rsa_key *key = entry; + + local_score = naddr_score(key->src, req->iph1->local); + remote_score = naddr_score(key->dst, req->iph1->remote); + + plog(LLV_DEBUG, LOCATION, NULL, "Entry %s scored %d/%d\n", + naddrwop2str_fromto("%s -> %s", key->src, key->dst), + local_score, remote_score); + + if (local_score >= 0 && remote_score >= 0) { + if (local_score + remote_score > req->max_score) { + req->max_score = local_score + remote_score; +// genlist_free(req->winners, NULL); + } + + if (local_score + remote_score >= req->max_score) { + genlist_append(req->winners, key); + } + } + + /* Always traverse the whole list */ + return NULL; +} + +struct genlist * +rsa_lookup_keys(struct ph1handle *iph1, int my) +{ + struct genlist *list; + struct lookup_result r; + + plog(LLV_DEBUG, LOCATION, NULL, "Looking up RSA key for %s\n", + saddr2str_fromto("%s <-> %s", iph1->local, iph1->remote)); + + r.iph1 = iph1; + r.max_score = -1; + r.winners = genlist_init(); + + if (my) + list = iph1->rmconf->rsa_private; + else + list = iph1->rmconf->rsa_public; + + genlist_foreach(list, rsa_lookup_key_one, &r); + + if (loglevel >= LLV_DEBUG) + rsa_key_dump(r.winners); + + return r.winners; +} + +int +rsa_parse_file(struct genlist *list, const char *fname, enum rsa_key_type type) +{ + int ret; + + plog(LLV_DEBUG, LOCATION, NULL, "Parsing %s\n", fname); + ret = prsa_parse_file(list, fname, type); + if (loglevel >= LLV_DEBUG) + rsa_key_dump(list); + return ret; +} + +RSA * +rsa_try_check_rsasign(vchar_t *source, vchar_t *sig, struct genlist *list) +{ + struct rsa_key *key; + struct genlist_entry *gp; + + for(key = genlist_next(list, &gp); key; key = genlist_next(NULL, &gp)) { + plog(LLV_DEBUG, LOCATION, NULL, "Checking key %s...\n", + naddrwop2str_fromto("%s -> %s", key->src, key->dst)); + if (eay_check_rsasign(source, sig, key->rsa) == 0) { + plog(LLV_DEBUG, LOCATION, NULL, " ... YEAH!\n"); + return key->rsa; + } + plog(LLV_DEBUG, LOCATION, NULL, " ... nope.\n"); + } + return NULL; +} diff --git a/ipsec-tools/src/racoon/rsalist.h b/ipsec-tools/src/racoon/rsalist.h new file mode 100644 index 00000000..bc6a8d9f --- /dev/null +++ b/ipsec-tools/src/racoon/rsalist.h @@ -0,0 +1,67 @@ +/* $NetBSD: rsalist.h,v 1.6 2011/03/14 15:50:36 vanhu Exp $ */ + +/* Id: rsalist.h,v 1.2 2004/07/12 20:43:51 ludvigm Exp */ +/* + * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. + * Contributed by: Michal Ludvig , SUSE Labs + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _RSALIST_H +#define _RSALIST_H + +#include +#include + +#include "handler.h" +#include "genlist.h" + +enum rsa_key_type { + RSA_TYPE_ANY = 0, + RSA_TYPE_PUBLIC, + RSA_TYPE_PRIVATE +}; + +struct rsa_key { + struct netaddr *src; + struct netaddr *dst; + RSA *rsa; +}; + +int rsa_key_insert(struct genlist *list, struct netaddr *src, struct netaddr *dst, RSA *rsa); +struct rsa_key *rsa_key_dup(struct rsa_key *key); +void rsa_key_free(void *data); +void rsa_key_dump(struct genlist *list); + +struct genlist *rsa_lookup_keys(struct ph1handle *iph1, int my); +RSA *rsa_try_check_rsasign(vchar_t *source, vchar_t *sig, struct genlist *list); + +unsigned long rsa_list_count(struct genlist *list); + +int rsa_parse_file(struct genlist *list, const char *fname, enum rsa_key_type type); + +#endif /* _RSALIST_H */ diff --git a/ipsec-tools/src/racoon/safefile.c b/ipsec-tools/src/racoon/safefile.c new file mode 100644 index 00000000..52410920 --- /dev/null +++ b/ipsec-tools/src/racoon/safefile.c @@ -0,0 +1,93 @@ +/* $NetBSD: safefile.c,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* $KAME: safefile.c,v 1.5 2001/03/05 19:54:06 thorpej Exp $ */ + +/* + * Copyright (C) 2000 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "plog.h" +#include "debug.h" +#include "misc.h" +#include "safefile.h" + +int +safefile(path, secret) + const char *path; + int secret; +{ + struct stat s; + uid_t me; + + /* no setuid */ + if (getuid() != geteuid()) { + plog(LLV_ERROR, LOCATION, NULL, + "setuid'ed execution not allowed\n"); + return -1; + } + + if (stat(path, &s) != 0) + return -1; + + /* the file must be owned by the running uid */ + me = getuid(); + if (s.st_uid != me) { + plog(LLV_ERROR, LOCATION, NULL, + "%s has invalid owner uid\n", path); + return -1; + } + + switch (s.st_mode & S_IFMT) { + case S_IFREG: + break; + default: + plog(LLV_ERROR, LOCATION, NULL, + "%s is an invalid file type 0x%x\n", path, + (s.st_mode & S_IFMT)); + return -1; + } + + /* secret file should not be read by others */ + if (secret) { + if ((s.st_mode & S_IRWXG) != 0 || (s.st_mode & S_IRWXO) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "%s has weak file permission\n", path); + return -1; + } + } + + return 0; +} diff --git a/ipsec-tools/src/racoon/safefile.h b/ipsec-tools/src/racoon/safefile.h new file mode 100644 index 00000000..c8d6a6c3 --- /dev/null +++ b/ipsec-tools/src/racoon/safefile.h @@ -0,0 +1,39 @@ +/* $NetBSD: safefile.h,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: safefile.h,v 1.4 2004/07/12 18:32:12 ludvigm Exp */ + +/* + * Copyright (C) 2000 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SAFEFILE_H +#define _SAFEFILE_H + +extern int safefile __P((const char *, int)); + +#endif /* _SAFEFILE_H */ diff --git a/ipsec-tools/src/racoon/sainfo.c b/ipsec-tools/src/racoon/sainfo.c new file mode 100644 index 00000000..b6577c2e --- /dev/null +++ b/ipsec-tools/src/racoon/sainfo.c @@ -0,0 +1,413 @@ +/* $NetBSD: sainfo.c,v 1.14 2011/02/02 15:21:34 vanhu Exp $ */ + +/* $KAME: sainfo.c,v 1.16 2003/06/27 07:32:39 sakane Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "debug.h" + +#include "localconf.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "ipsec_doi.h" +#include "oakley.h" +#include "handler.h" +#include "algorithm.h" +#include "sainfo.h" +#include "gcmalloc.h" + +typedef LIST_HEAD(_sitree, sainfo) sainfo_tailq_head_t; +static sainfo_tailq_head_t sitree, sitree_save; + +/* %%% + * modules for ipsec sa info + */ +/* + * return matching entry. + * no matching entry found and if there is anonymous entry, return it. + * else return NULL. + * First pass is for sainfo from a specified peer, second for others. + */ +struct sainfo * +getsainfo(loc, rmt, peer, client, remoteid) + const vchar_t *loc, *rmt, *peer, *client; + uint32_t remoteid; +{ + struct sainfo *s = NULL; + + /* debug level output */ + if(loglevel >= LLV_DEBUG) { + char *dloc, *drmt, *dpeer, *dclient; + + if (loc == NULL) + dloc = strdup("ANONYMOUS"); + else + dloc = ipsecdoi_id2str(loc); + + if (rmt == SAINFO_ANONYMOUS) + drmt = strdup("ANONYMOUS"); + else if (rmt == SAINFO_CLIENTADDR) + drmt = strdup("CLIENTADDR"); + else + drmt = ipsecdoi_id2str(rmt); + + if (peer == NULL) + dpeer = strdup("NULL"); + else + dpeer = ipsecdoi_id2str(peer); + + if (client == NULL) + dclient = strdup("NULL"); + else + dclient = ipsecdoi_id2str(client); + + plog(LLV_DEBUG, LOCATION, NULL, + "getsainfo params: loc=\'%s\' rmt=\'%s\' peer=\'%s\' client=\'%s\' id=%u\n", + dloc, drmt, dpeer, dclient, remoteid ); + + racoon_free(dloc); + racoon_free(drmt); + racoon_free(dpeer); + racoon_free(dclient); + } + + LIST_FOREACH(s, &sitree, chain) { + const char *sainfostr = sainfo2str(s); + plog(LLV_DEBUG, LOCATION, NULL, + "evaluating sainfo: %s\n", sainfostr); + + if(s->remoteid != remoteid) { + plog(LLV_DEBUG, LOCATION, NULL, + "remoteid mismatch: %u != %u\n", + s->remoteid, remoteid); + continue; + } + + /* compare 'from' id value */ + if (s->id_i != NULL) + if (ipsecdoi_chkcmpids(peer, s->id_i, 0)) + continue; + + /* compare ids - client */ + if( s->iddst == SAINFO_CLIENTADDR ) { + /* + * This sainfo section enforces client address + * checking. Prevent match if the client value + * ( modecfg or tunnel address ) is NULL. + */ + + if (client == NULL) + continue; + + if( rmt == SAINFO_CLIENTADDR ) { + /* + * In the case where a supplied rmt value is + * also SAINFO_CLIENTADDR, we are comparing + * with another sainfo to check for duplicate. + * Only compare the local values to determine + * a match. + */ + + if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0)) + return s; + } + else { + /* + * In the case where a supplied rmt value is + * not SAINFO_CLIENTADDR, do a standard match + * for local values and enforce that the rmt + * id matches the client address value. + */ + + if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0) && + !ipsecdoi_chkcmpids(rmt, client, 0)) + return s; + } + + continue; + } + + + /* compare ids - standard */ + if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0) && + !ipsecdoi_chkcmpids(rmt, s->iddst, 0)) + return s; + } + + return NULL; +} + +struct sainfo * +newsainfo() +{ + struct sainfo *new; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) + return NULL; + + new->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT; + new->lifebyte = IPSECDOI_ATTR_SA_LD_KB_MAX; + + return new; +} + +void +delsainfo(si) + struct sainfo *si; +{ + int i; + + for (i = 0; i < MAXALGCLASS; i++) + delsainfoalg(si->algs[i]); + + if (si->idsrc) + vfree(si->idsrc); + if (si->iddst != NULL && + si->iddst != SAINFO_CLIENTADDR) + vfree(si->iddst); + +#ifdef ENABLE_HYBRID + if (si->group) + vfree(si->group); +#endif + + racoon_free(si); +} + +int prisainfo(s) + struct sainfo *s; +{ + /* + * determine the matching priority + * of an sainfo section + */ + + int pri = 0; + + if(s->remoteid) + pri += 3; + + if(s->id_i) + pri += 3; + + if(s->idsrc) + pri++; + + if(s->iddst) + pri++; + + return pri; +} + +void +inssainfo(new) + struct sainfo *new; +{ + if(LIST_EMPTY(&sitree)) { + + /* first in list */ + LIST_INSERT_HEAD(&sitree, new, chain); + } + else { + int npri, spri; + struct sainfo *s, *n; + + /* + * insert our new sainfo section + * into our list which is sorted + * based on the match priority + */ + + npri = prisainfo(new); + + s = LIST_FIRST(&sitree); + while (1) { + + spri = prisainfo(s); + n = LIST_NEXT(s, chain); + + if(npri > spri) + { + /* higher priority */ + LIST_INSERT_BEFORE(s, new, chain); + return; + } + + if(n == NULL) + { + /* last in list */ + LIST_INSERT_AFTER(s, new, chain); + return; + } + + s = n; + } + } +} + +void +remsainfo(si) + struct sainfo *si; +{ + LIST_REMOVE(si, chain); +} + +void +flushsainfo() +{ + struct sainfo *s, *next; + + for (s = LIST_FIRST(&sitree); s; s = next) { + next = LIST_NEXT(s, chain); + remsainfo(s); + delsainfo(s); + } +} + +void +initsainfo() +{ + LIST_INIT(&sitree); +} + +struct sainfoalg * +newsainfoalg() +{ + struct sainfoalg *new; + + new = racoon_calloc(1, sizeof(*new)); + if (new == NULL) + return NULL; + + return new; +} + +void +delsainfoalg(alg) + struct sainfoalg *alg; +{ + struct sainfoalg *a, *next; + + for (a = alg; a; a = next) { + next = a->next; + racoon_free(a); + } +} + +void +inssainfoalg(head, new) + struct sainfoalg **head; + struct sainfoalg *new; +{ + struct sainfoalg *a; + + for (a = *head; a && a->next; a = a->next) + ; + if (a) + a->next = new; + else + *head = new; +} + +const char * +sainfo2str(si) + const struct sainfo *si; +{ + static char buf[256]; + + char *idloc = NULL, *idrmt = NULL, *id_i; + + if (si->idsrc == SAINFO_ANONYMOUS) + idloc = strdup("ANONYMOUS"); + else + idloc = ipsecdoi_id2str(si->idsrc); + + if (si->iddst == SAINFO_ANONYMOUS) + idrmt = strdup("ANONYMOUS"); + else if (si->iddst == SAINFO_CLIENTADDR) + idrmt = strdup("CLIENTADDR"); + else + idrmt = ipsecdoi_id2str(si->iddst); + + if (si->id_i == NULL) + id_i = strdup("ANY"); + else + id_i = ipsecdoi_id2str(si->id_i); + + snprintf(buf, 255, "loc=\'%s\', rmt=\'%s\', peer=\'%s\', id=%u", + idloc, idrmt, id_i, si->remoteid); + + racoon_free(idloc); + racoon_free(idrmt); + racoon_free(id_i); + + return buf; +} + +void sainfo_start_reload(void){ + sitree_save=sitree; + initsainfo(); +} + +void sainfo_finish_reload(void){ + sainfo_tailq_head_t sitree_tmp; + + sitree_tmp=sitree; + sitree=sitree_save; + flushsainfo(); + sitree=sitree_tmp; +} + +void save_sainfotree_restore(void){ + flushsainfo(); + sitree=sitree_save; +} diff --git a/ipsec-tools/src/racoon/sainfo.h b/ipsec-tools/src/racoon/sainfo.h new file mode 100644 index 00000000..e708cd66 --- /dev/null +++ b/ipsec-tools/src/racoon/sainfo.h @@ -0,0 +1,92 @@ +/* $NetBSD: sainfo.h,v 1.8 2011/02/02 15:21:34 vanhu Exp $ */ + +/* Id: sainfo.h,v 1.5 2006/07/09 17:19:38 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SAINFO_H +#define _SAINFO_H + +#include + +#define SAINFO_ANONYMOUS ((void *)NULL) +#define SAINFO_CLIENTADDR ((void *)~0) + +/* SA info */ +struct sainfo { + vchar_t *idsrc; + vchar_t *iddst; + /* + * idsrc and iddst are constructed body of ID payload. + * that is (struct ipsecdoi_id_b) + ID value. + * If idsrc == NULL, that is anonymous entry. + * If idsrc == ~0, that is client address entry. + */ + +#ifdef ENABLE_HYBRID + vchar_t *group; +#endif + + time_t lifetime; + int lifebyte; + int pfs_group; /* only use when pfs is required. */ + vchar_t *id_i; /* identifier of the authorized initiator */ + struct sainfoalg *algs[MAXALGCLASS]; + + uint32_t remoteid; + + LIST_ENTRY(sainfo) chain; +}; + +/* algorithm type */ +struct sainfoalg { + int alg; + int encklen; /* key length if encryption algorithm */ + struct sainfoalg *next; +}; + +extern struct sainfo *getsainfo __P((const vchar_t *, + const vchar_t *, const vchar_t *, const vchar_t *, uint32_t)); +extern struct sainfo *newsainfo __P((void)); +extern void delsainfo __P((struct sainfo *)); +extern void inssainfo __P((struct sainfo *)); +extern void remsainfo __P((struct sainfo *)); +extern void flushsainfo __P((void)); +extern void initsainfo __P((void)); +extern struct sainfoalg *newsainfoalg __P((void)); +extern void delsainfoalg __P((struct sainfoalg *)); +extern void inssainfoalg __P((struct sainfoalg **, struct sainfoalg *)); +extern const char * sainfo2str __P((const struct sainfo *)); + +extern void sainfo_start_reload __P((void)); +extern void sainfo_finish_reload __P((void)); +extern void save_sainfotree_restore __P((void)); + +#endif /* _SAINFO_H */ diff --git a/ipsec-tools/src/racoon/samples/psk.txt.in b/ipsec-tools/src/racoon/samples/psk.txt.in new file mode 100644 index 00000000..52f1a550 --- /dev/null +++ b/ipsec-tools/src/racoon/samples/psk.txt.in @@ -0,0 +1,21 @@ +# IPv4/v6 addresses +10.160.94.3 mekmitasdigoat +172.16.1.133 mekmitasdigoat +194.100.55.1 whatcertificatereally +203.178.141.208 mekmitasdigoat +206.175.160.18 mekmitasdigoat +206.175.160.20 mekmitasdigoat +206.175.160.21 mekmitasdigoat +206.175.160.22 mekmitasdigoat +206.175.160.23 mekmitasdigoat +206.175.160.36 mekmitasdigoat +206.175.161.125 mekmitasdigoat +206.175.161.154 mekmitasdigoat +206.175.161.156 mekmitasdigoat +206.175.161.182 mekmitasdigoat +3ffe:501:410:ffff:200:86ff:fe05:80fa mekmitasdigoat +3ffe:501:410:ffff:210:4bff:fea2:8baa mekmitasdigoat +# USER_FQDN +sakane@kame.net mekmitasdigoat +# FQDN +kame hoge diff --git a/ipsec-tools/src/racoon/samples/psk.txt.sample b/ipsec-tools/src/racoon/samples/psk.txt.sample new file mode 100644 index 00000000..2ad1d0b4 --- /dev/null +++ b/ipsec-tools/src/racoon/samples/psk.txt.sample @@ -0,0 +1,10 @@ +# IPv4/v6 addresses +10.160.94.3 mekmitasdigoat +172.16.1.133 0x12345678 +194.100.55.1 whatcertificatereally +3ffe:501:410:ffff:200:86ff:fe05:80fa mekmitasdigoat +3ffe:501:410:ffff:210:4bff:fea2:8baa mekmitasdigoat +# USER_FQDN +foo@kame.net mekmitasdigoat +# FQDN +foo.kame.net hoge diff --git a/ipsec-tools/src/racoon/samples/racoon.conf.in b/ipsec-tools/src/racoon/samples/racoon.conf.in new file mode 100644 index 00000000..29b79516 --- /dev/null +++ b/ipsec-tools/src/racoon/samples/racoon.conf.in @@ -0,0 +1,121 @@ +# $KAME: racoon.conf.in,v 1.18 2001/08/16 06:33:40 itojun Exp $ + +# "path" affects "include" directives. "path" must be specified before any +# "include" directive with relative file path. +# you can overwrite "path" directive afterwards, however, doing so may add +# more confusion. +path include "@sysconfdir_x@/racoon"; +#include "remote.conf"; + +# the file should contain key ID/key pairs, for pre-shared key authentication. +path pre_shared_key "@sysconfdir_x@/racoon/psk.txt"; + +# racoon will look for certificate file in the directory, +# if the certificate/certificate request payload is received. +path certificate "@sysconfdir_x@/cert"; + +# "log" specifies logging level. It is followed by either "notify", "debug" +# or "debug2". +#log debug; + +# "padding" defines some padding parameters. You should not touch these. +padding +{ + maximum_length 20; # maximum padding length. + randomize off; # enable randomize length. + strict_check off; # enable strict check. + exclusive_tail off; # extract last one octet. +} + +# if no listen directive is specified, racoon will listen on all +# available interface addresses. +listen +{ + #isakmp ::1 [7000]; + #isakmp 202.249.11.124 [500]; + #admin [7002]; # administrative port for racoonctl. + #strict_address; # requires that all addresses must be bound. +} + +# Specify various default timers. +timer +{ + # These value can be changed per remote node. + counter 5; # maximum trying count to send. + interval 20 sec; # maximum interval to resend. + persend 1; # the number of packets per send. + + # maximum time to wait for completing each phase. + phase1 30 sec; + phase2 15 sec; +} + +remote anonymous +{ + exchange_mode main,aggressive; + doi ipsec_doi; + situation identity_only; + + my_identifier asn1dn; + certificate_type x509 "my.cert.pem" "my.key.pem"; + + nonce_size 16; + initial_contact on; + proposal_check strict; # obey, strict, or claim + + proposal { + encryption_algorithm 3des; + hash_algorithm sha1; + authentication_method rsasig; + dh_group 2; + } +} + +remote ::1 [8000] +{ + #exchange_mode main,aggressive; + exchange_mode aggressive,main; + doi ipsec_doi; + situation identity_only; + + my_identifier user_fqdn "sakane@kame.net"; + peers_identifier user_fqdn "sakane@kame.net"; + #certificate_type x509 "mycert" "mypriv"; + + nonce_size 16; + lifetime time 1 min; # sec,min,hour + + proposal { + encryption_algorithm 3des; + hash_algorithm sha1; + authentication_method pre_shared_key; + dh_group 2; + } +} + +sainfo anonymous +{ + pfs_group 2; + encryption_algorithm 3des; + authentication_algorithm hmac_sha1; + compression_algorithm deflate; +} + +sainfo address 203.178.141.209 any address 203.178.141.218 any +{ + pfs_group 2; + lifetime time 30 sec; + encryption_algorithm des; + authentication_algorithm hmac_md5; + compression_algorithm deflate; +} + +sainfo address ::1 icmp6 address ::1 icmp6 +{ + pfs_group 3; + lifetime time 60 sec; + encryption_algorithm 3des, blowfish, aes; + authentication_algorithm hmac_sha1, hmac_md5; + compression_algorithm deflate; +} + diff --git a/ipsec-tools/src/racoon/samples/racoon.conf.sample b/ipsec-tools/src/racoon/samples/racoon.conf.sample new file mode 100644 index 00000000..631910f2 --- /dev/null +++ b/ipsec-tools/src/racoon/samples/racoon.conf.sample @@ -0,0 +1,61 @@ +# $KAME: racoon.conf.sample,v 1.28 2002/10/18 14:33:28 itojun Exp $ + +# "path" affects "include" directives. "path" must be specified before any +# "include" directive with relative file path. +# you can overwrite "path" directive afterwards, however, doing so may add +# more confusion. +#path include "/usr/local/v6/etc" ; +#include "remote.conf" ; + +# the file should contain key ID/key pairs, for pre-shared key authentication. +path pre_shared_key "/usr/local/v6/etc/psk.txt" ; + +# racoon will look for certificate file in the directory, +# if the certificate/certificate request payload is received. +#path certificate "/usr/local/openssl/certs" ; + +# "log" specifies logging level. It is followed by either "notify", "debug" +# or "debug2". +#log debug; + +remote anonymous +{ + #exchange_mode main,aggressive,base; + exchange_mode main,base; + + #my_identifier fqdn "server.kame.net"; + #certificate_type x509 "foo@kame.net.cert" "foo@kame.net.priv" ; + + lifetime time 24 hour ; # sec,min,hour + + #initial_contact off ; + #passive on ; + + # phase 1 proposal (for ISAKMP SA) + proposal { + encryption_algorithm 3des; + hash_algorithm sha1; + authentication_method pre_shared_key ; + dh_group 2 ; + } + + # the configuration could makes racoon (as a responder) + # to obey the initiator's lifetime and PFS group proposal, + # by setting proposal_check to obey. + # this would makes testing "so much easier", but is really + # *not* secure !!! + proposal_check strict; +} + +# phase 2 proposal (for IPsec SA). +# actual phase 2 proposal will obey the following items: +# - kernel IPsec policy configuration (like "esp/transport//use) +# - permutation of the crypto/hash/compression algorithms presented below +sainfo anonymous +{ + pfs_group 2; + lifetime time 12 hour ; + encryption_algorithm 3des, cast128, blowfish 448, des, rijndael ; + authentication_algorithm hmac_sha1, hmac_md5 ; + compression_algorithm deflate ; +} diff --git a/ipsec-tools/src/racoon/samples/racoon.conf.sample-gssapi b/ipsec-tools/src/racoon/samples/racoon.conf.sample-gssapi new file mode 100644 index 00000000..09c4df1d --- /dev/null +++ b/ipsec-tools/src/racoon/samples/racoon.conf.sample-gssapi @@ -0,0 +1,43 @@ +# $KAME: racoon.conf.sample-gssapi,v 1.5 2001/08/16 06:33:40 itojun Exp $ + +# sample configuration for GSSAPI authentication (basically, Kerberos). +# doc/README.gssapi gives some idea on how to configure it. +# TODO: more documentation. + +#listen { +# strict_address; +#} + +# Uncomment the following for GSS-API to work with older versions of +# racoon that (incorrectly) used ISO-Latin-1 encoding for the GSS-API +# identifier attribute. +#gss_id_enc latin1; + +remote anonymous { + exchange_mode main; + + lifetime time 24 hour; + + proposal { + encryption_algorithm 3des; + hash_algorithm sha1; + authentication_method gssapi_krb; + # The default GSS-API ID is "host/hostname", where + # hostname is the output of the hostname(1) command. + # You probably want this to match your system's host + # principal. ktutil(8)'s "list" command will list the + # principals in your system's keytab. If you need to, + # you can change the GSS-API ID here. + #gss_id "host/some.host.name"; + + dh_group 1; + } +} + +sainfo anonymous { + lifetime time 2 hour; + + encryption_algorithm rijndael, 3des; + authentication_algorithm hmac_sha1, hmac_md5; + compression_algorithm deflate; +} diff --git a/ipsec-tools/src/racoon/samples/racoon.conf.sample-inherit b/ipsec-tools/src/racoon/samples/racoon.conf.sample-inherit new file mode 100644 index 00000000..9e1185f1 --- /dev/null +++ b/ipsec-tools/src/racoon/samples/racoon.conf.sample-inherit @@ -0,0 +1,55 @@ +# Id: racoon.conf.sample-inherit,v 1.3 2005/12/13 16:41:07 vanhu Exp +# Contributed by: Michal Ludvig , SUSE Labs + +# This file shows the basic inheritance usage in 'remote' statements. + +path pre_shared_key "/etc/racoon/psk.txt"; +path certificate "/etc/racoon"; + +remote anonymous +{ + exchange_mode main,aggressive; + doi ipsec_doi; + situation identity_only; + + my_identifier asn1dn; + certificate_type x509 "my.cert.pem" "my.key.pem"; + + nonce_size 16; + initial_contact on; + proposal_check strict; # obey, strict or claim + + proposal { + encryption_algorithm 3des; + hash_algorithm sha1; + authentication_method rsasig; + dh_group 2; + } +} + +remote 3ffe:ffff::1 inherit anonymous +{ + exchange_mode aggressive; + nat_traversal force; +} + +remote 3ffe:ffff::1 [8000] inherit 3ffe:ffff::1 +{ + lifetime time 1 min; # sec,min,hour + + proposal { + encryption_algorithm 3des; + hash_algorithm sha1; + authentication_method pre_shared_key; + dh_group 2; + } +} + +sainfo anonymous +{ + pfs_group 2; + lifetime time 12 hour; + encryption_algorithm aes, 3des; + authentication_algorithm hmac_sha1, hmac_md5; + compression_algorithm deflate; +} diff --git a/ipsec-tools/src/racoon/samples/racoon.conf.sample-natt b/ipsec-tools/src/racoon/samples/racoon.conf.sample-natt new file mode 100644 index 00000000..645b4de7 --- /dev/null +++ b/ipsec-tools/src/racoon/samples/racoon.conf.sample-natt @@ -0,0 +1,97 @@ +# Id: racoon.conf.sample-natt,v 1.5 2005/12/13 16:41:07 vanhu Exp +# Contributed by: Michal Ludvig , SUSE Labs + +# This file can be used as a template for NAT-Traversal setups. +# Only NAT-T related options are explained here, refer to other +# sample files and manual pages for details about the rest. + +path include "/etc/racoon"; +path certificate "/etc/racoon/cert"; + +# Define addresses and ports where racoon will listen for an incoming +# traffic. Don't forget to open these ports on your firewall! +listen +{ + # First define an address where racoon will listen + # for "normal" IKE traffic. IANA allocated port 500. + isakmp 172.16.0.1[500]; + + # To use NAT-T you must also open port 4500 of + # the same address so that peers can do 'Port floating'. + # The same port will also be used for the UDP-Encapsulated + # ESP traffic. + isakmp_natt 172.16.0.1[4500]; +} + + +timer +{ + # To keep the NAT-mappings on your NAT gateway, there must be + # traffic between the peers. Normally the UDP-Encap traffic + # (i.e. the real data transported over the tunnel) would be + # enough, but to be safe racoon will send a short + # "Keep-alive packet" every few seconds to every peer with + # whom it does NAT-Traversal. + # The default is 20s. Set it to 0s to disable sending completely. + natt_keepalive 10 sec; +} + +# To trigger the SA negotiation there must be an appropriate +# policy in the kernel SPD. For example for traffic between +# networks 192.168.0.0/24 and 192.168.1.0/24 with gateways +# 172.16.0.1 and 172.16.1.1, where the first gateway is behind +# a NAT which translates its address to 172.16.1.3, you need the +# following rules: +# On 172.16.0.1 (e.g. behind the NAT): +# spdadd 192.168.0.0/24 192.168.1.0/24 any -P out ipsec \ +# esp/tunnel/172.16.0.1-172.16.1.1/require; +# spdadd 192.168.1.0/24 192.168.0.0/24 any -P in ipsec \ +# esp/tunnel/172.16.1.1-172.16.0.1/require; +# On the other side (172.16.1.1) either use a "generate_policy on" +# statement in the remote block, or in case that you know +# the translated address, use the following policy: +# spdadd 192.168.1.0/24 192.168.0.0/24 any -P out ipsec \ +# esp/tunnel/172.16.1.1-172.16.1.3/require; +# spdadd 192.168.0.0/24 192.168.1.0/24 any -P in ipsec \ +# esp/tunnel/172.16.1.3-172.16.1.1/require; + +# Phase 1 configuration (for ISAKMP SA) +remote anonymous +{ + # NAT-T is supported with all exchange_modes. + exchange_mode main,base,aggressive; + + # With NAT-T you shouldn't use PSK. Let's go on with certs. + my_identifier asn1dn; + certificate_type x509 "your-host.cert.pem" "your-host.key.pem"; + + # This is the main switch that enables NAT-T. + # Possible values are: + # off - NAT-T support is disabled, i.e. neither offered, + # nor accepted. This is the default. + # on - normal NAT-T support, i.e. if NAT is detected + # along the way, NAT-T is used. + # force - if NAT-T is supported by both peers, it is used + # regardless of whether there is a NAT gateway between them + # or not. This is useful for traversing some firewalls. + nat_traversal on; + + proposal { + authentication_method rsasig; + encryption_algorithm 3des; + hash_algorithm sha1; + dh_group 2; + } + + proposal_check strict; +} + +# Phase 2 proposal (for IPsec SA) +sainfo anonymous +{ + pfs_group 2; + lifetime time 12 hour; + encryption_algorithm 3des, rijndael; + authentication_algorithm hmac_sha1; + compression_algorithm deflate; +} diff --git a/ipsec-tools/src/racoon/samples/racoon.conf.sample-plainrsa b/ipsec-tools/src/racoon/samples/racoon.conf.sample-plainrsa new file mode 100644 index 00000000..8447eb30 --- /dev/null +++ b/ipsec-tools/src/racoon/samples/racoon.conf.sample-plainrsa @@ -0,0 +1,46 @@ +# Id: racoon.conf.sample-plainrsa,v 1.4 2005/12/13 16:41:07 vanhu Exp +# Contributed by: Michal Ludvig , SUSE Labs +# http://www.logix.cz/michal + +# This file shows the usage of PlainRSA keys, which are widely used +# by FreeSWAN/OpenSwan/StrongSwan/*Swan users. This functionality is +# here mainly for those who are moving from the *Swan world to Racoon. + +# Racoon will look for a keyfile in this directory. +path certificate "samples" ; + +remote anonymous +{ + # *Swan supports only 'main' mode. + exchange_mode main; + + # *Swan doesn't send identifiers by default. + my_identifier address; + peers_identifier address; + + # This is the trick - use PlainRSA certificates. + certificate_type plain_rsa "privatekey.rsa"; + + # Multiple certfiles are supported. + peers_certfile plain_rsa "pubkey1.rsa"; + peers_certfile plain_rsa "pubkey2.rsa"; + + # Standard setup follows... + proposal_check strict; + + proposal { + encryption_algorithm 3des; + hash_algorithm sha1; + authentication_method rsasig; + dh_group 2; + } +} + +sainfo anonymous +{ + pfs_group 2; + lifetime time 12 hour; + encryption_algorithm 3des, aes; + authentication_algorithm hmac_sha1, hmac_md5; + compression_algorithm deflate; +} diff --git a/ipsec-tools/src/racoon/samples/roadwarrior/README b/ipsec-tools/src/racoon/samples/roadwarrior/README new file mode 100644 index 00000000..aac9d431 --- /dev/null +++ b/ipsec-tools/src/racoon/samples/roadwarrior/README @@ -0,0 +1,67 @@ +This directory contains sample configurations files used for roadwarrior +remote access using hybrid authentication. In this setup, the VPN +gateway authenticates to the client using a certificate, and the client +authenticates to the VPN gateway using a login and a password. + +Moreover, this setup makes use of ISAKMP mode config to autoconfigure +the client. After a successful login, the client will receive an +internal address, netmask and DNS from the VPN gateway. + + +Server setups +============= +The server setups need racoon built with the following options: +configure --enable-natt --enable-frag --enable-hybrid --enable-dpd \ + --with-libradius --sysconfdir=/etc/racoon + +The first server setup, in server/racoon.conf, is for a VPN gateway +using authentication against the system password database, and using +a locally configured pool of addresses. + +The second setup, server/racoon.conf-radius, uses a RADIUS server for +authentication, IP allocation and accounting. The address and secret +to be used for the RADIUS server are configured in /etc/radius.conf, +see radius.conf(5). + +Both configurations can be used with the Cisco VPN client if it +is set up to use hybrid authentication (aka mutual group authentication, +available in Cisco VPN client version 4.0.5 and above). The group +password configured in the Cisco VPN client is not used by racoon. + +After you have installed /etc/racoon/racoon.conf, you will also have +to install a server certificate and key in /etc/openssl/certs/server.crt +and /etc/openssl/certs/server.key + + +Client setup +============ +The client setup needs racoon built with the following options: +configure --enable-natt --enable-frag --enable-hybrid --enable-dpd \ + --enable-adminport --sysconfdir=/etc/racoon --localstatedir=/var + +You need to copy client/racoon.conf, client/phase1-up.sh and +client/phase1-down.sh to /etc/racoon, and you need to copy the +certificate authority that signed the VPN gateway certificate in +/etc/openssl/certs/root-ca.crt + +Once this is done, you can run racoon, and then you can start +the VPN using racoonctl: +racoonctl vc -u username vpn-gateway.example.net + +Where username is your login, and vpn-gateway.example.net is +the DNS or IP address of the VPN gateway. racoonctl will prompt +you for the password. + +The password can be stored in the psk.txt file. In that situation, +add this directive to the remote section of racoon.conf: + xauth_login "username"; +where username is your login. + +Note that for now there is no feedback in racoonctl if the authentication +fails. Peek at the racoon logs to discover what goes wrong. + +In order to disconnect from the VPN, do this: +racoonctl vd vpn-gateway.example.net + +This configuration should be compatible with the Cisco VPN 3000 using +hybrid authentication, though this has not been tested. diff --git a/ipsec-tools/src/racoon/samples/roadwarrior/client/phase1-down.sh b/ipsec-tools/src/racoon/samples/roadwarrior/client/phase1-down.sh new file mode 100755 index 00000000..92f2ba80 --- /dev/null +++ b/ipsec-tools/src/racoon/samples/roadwarrior/client/phase1-down.sh @@ -0,0 +1,78 @@ +#!/bin/sh + +# +# sa-down.sh local configuration for a new SA +# + +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin + +case `uname -s` in +NetBSD) + DEFAULT_GW=`netstat -finet -rn | awk '($1 == "default"){print $2; exit}'` + ;; +Linux) + DEFAULT_GW=`netstat --inet -rn | awk '($1 == "0.0.0.0"){print $2; exit}'` + ;; +esac + +echo $@ +echo "LOCAL_ADDR = ${LOCAL_ADDR}" +echo "LOCAL_PORT = ${LOCAL_PORT}" +echo "REMOTE_ADDR = ${REMOTE_ADDR}" +echo "REMOTE_PORT = ${REMOTE_PORT}" +echo "DEFAULT_GW = ${DEFAULT_GW}" +echo "INTERNAL_NETMASK4 = ${INTERNAL_NETMASK4}" +echo "INTERNAL_ADDR4 = ${INTERNAL_ADDR4}" +echo "INTERNAL_DNS4 = ${INTERNAL_DNS4}" + +echo ${INTERNAL_ADDR4} | grep '[0-9]' > /dev/null || exit 0 +echo ${INTERNAL_NETMASK4} | grep '[0-9]' > /dev/null || exit 0 +echo ${DEFAULT_GW} | grep '[0-9]' > /dev/null || exit 0 + +if [ -f /etc/resolv.conf.bak ]; then + rm -f /etc/resolv.conf + mv /etc/resolv.conf.bak /etc/resolv.conf +fi + +case `uname -s` in +NetBSD) + if=`netstat -finet -rn|awk '($1 == "default"){print $7; exit}'` + route delete default + route delete ${REMOTE_ADDR} + ifconfig ${if} delete ${INTERNAL_ADDR4} + route add default ${DEFAULT_GW} -ifa ${LOCAL_ADDR} + ;; +Linux) + if=`netstat --inet -rn|awk '($1 == "0.0.0.0"){print $8; exit}'` + route delete default + route delete ${REMOTE_ADDR} + ifconfig ${if}:1 del ${INTERNAL_ADDR4} + route add default gw ${DEFAULT_GW} + + # + # XXX This is a workaround because Linux seems to ignore + # the deleteall commands below. This is bad because it flushes + # any SAD instead of flushing what needs to be flushed. + # Someone using Linux please fix it + # + setkey -F + ;; +esac + +LOCAL="${LOCAL_ADDR}" +REMOTE="${REMOTE_ADDR}" +if [ "x${LOCAL_PORT}" != "x500" ]; then + # NAT-T setup + LOCAL="${LOCAL}[${LOCAL_PORT}]" + REMOTE="${REMOTE}[${REMOTE_PORT}]" +fi + +echo " +deleteall ${REMOTE_ADDR} ${LOCAL_ADDR} esp; +deleteall ${LOCAL_ADDR} ${REMOTE_ADDR} esp; +spddelete ${INTERNAL_ADDR4}/32[any] 0.0.0.0/0[any] any + -P out ipsec esp/tunnel/${LOCAL}-${REMOTE}/require; +spddelete 0.0.0.0/0[any] ${INTERNAL_ADDR4}[any] any + -P in ipsec esp/tunnel/${REMOTE}-${LOCAL}/require; +" | setkey -c + diff --git a/ipsec-tools/src/racoon/samples/roadwarrior/client/phase1-up.sh b/ipsec-tools/src/racoon/samples/roadwarrior/client/phase1-up.sh new file mode 100755 index 00000000..9275811a --- /dev/null +++ b/ipsec-tools/src/racoon/samples/roadwarrior/client/phase1-up.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +# +# sa-up.sh local configuration for a new SA +# +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin + +case `uname -s` in +NetBSD) + DEFAULT_GW=`netstat -finet -rn | awk '($1 == "default"){print $2; exit}'` + ;; +Linux) + DEFAULT_GW=`netstat --inet -rn | awk '($1 == "0.0.0.0"){print $2; exit}'` + ;; +esac + +echo $@ +echo "LOCAL_ADDR = ${LOCAL_ADDR}" +echo "LOCAL_PORT = ${LOCAL_PORT}" +echo "REMOTE_ADDR = ${REMOTE_ADDR}" +echo "REMOTE_PORT = ${REMOTE_PORT}" +echo "DEFAULT_GW = ${DEFAULT_GW}" +echo "INTERNAL_ADDR4 = ${INTERNAL_ADDR4}" +echo "INTERNAL_NETMASK4 = ${INTERNAL_NETMASK4}" +echo "INTERNAL_DNS4 = ${INTERNAL_DNS4}" + +echo ${INTERNAL_ADDR4} | grep '[0-9]' > /dev/null || exit 0 +echo ${INTERNAL_NETMASK4} | grep '[0-9]' > /dev/null || exit 0 +echo ${DEFAULT_GW} | grep '[0-9]' > /dev/null || exit 0 + +mv /etc/resolv.conf /etc/resolv.conf.bak +( umask 22; touch /etc/resolv.conf ) +echo "# Generated by racoon on `date`" >> /etc/resolv.conf +echo "nameserver ${INTERNAL_DNS4}" >> /etc/resolv.conf + +case `uname -s` in +NetBSD) + if=`netstat -finet -rn|awk '($1 == "default"){print $7; exit}'` + ifconfig ${if} alias ${INTERNAL_ADDR4} netmask ${INTERNAL_NETMASK4} + route delete default + route add default ${DEFAULT_GW} -ifa ${INTERNAL_ADDR4} + route add ${REMOTE_ADDR} ${DEFAULT_GW} + ;; +Linux) + if=`netstat --inet -rn|awk '($1 == "0.0.0.0"){print $8; exit}'` + ifconfig ${if}:1 ${INTERNAL_ADDR4} + route delete default + route add ${REMOTE_ADDR} gw ${DEFAULT_GW} dev ${if} + route add default gw ${DEFAULT_GW} dev ${if}:1 + ;; +esac + +LOCAL="${LOCAL_ADDR}" +REMOTE="${REMOTE_ADDR}" +if [ "x${LOCAL_PORT}" != "x500" ]; then + # NAT-T setup + LOCAL="${LOCAL}[${LOCAL_PORT}]" + REMOTE="${REMOTE}[${REMOTE_PORT}]" +fi + + +echo " +spdadd ${INTERNAL_ADDR4}/32[any] 0.0.0.0/0[any] any + -P out ipsec esp/tunnel/${LOCAL}-${REMOTE}/require; +spdadd 0.0.0.0/0[any] ${INTERNAL_ADDR4}[any] any + -P in ipsec esp/tunnel/${REMOTE}-${LOCAL}/require; +" | setkey -c + +# +# XXX This is a workaround for Linux forward policies problem. +# Someone familiar with forward policies please fix this properly. +# +case `uname -s` in +Linux) + echo " + spddelete 0.0.0.0/0[any] ${INTERNAL_ADDR4}[any] any + -P fwd ipsec esp/tunnel/${REMOTE}-${LOCAL}/require; + " | setkey -c + ;; +esac diff --git a/ipsec-tools/src/racoon/samples/roadwarrior/client/racoon.conf b/ipsec-tools/src/racoon/samples/roadwarrior/client/racoon.conf new file mode 100644 index 00000000..669be362 --- /dev/null +++ b/ipsec-tools/src/racoon/samples/roadwarrior/client/racoon.conf @@ -0,0 +1,33 @@ +path certificate "/etc/openssl/certs"; +path pre_shared_key "/etc/racoon/psk.txt"; + +listen { + adminsock "/var/racoon/racoon.sock" "root" "operator" 0660; +} + +remote 192.0.2.50 { + exchange_mode aggressive; + ca_type x509 "root-ca.crt"; + proposal_check strict; + nat_traversal on; + ike_frag on; + mode_cfg on; + script "/etc/racoon/phase1-up.sh" phase1_up; + script "/etc/racoon/phase1-down.sh" phase1_down; + passive off; + proposal { + encryption_algorithm aes; + hash_algorithm sha1; + authentication_method hybrid_rsa_client; + dh_group 2; + } +} + + +sainfo anonymous { + pfs_group 2; + lifetime time 1 hour; + encryption_algorithm aes; + authentication_algorithm hmac_sha1; + compression_algorithm deflate ; +} diff --git a/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf b/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf new file mode 100644 index 00000000..ae7d603a --- /dev/null +++ b/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf @@ -0,0 +1,42 @@ +path certificate "/etc/openssl/certs"; + +listen { + adminsock disabled; +} + +remote anonymous { + exchange_mode aggressive; + certificate_type x509 "server.crt" "server.key"; + my_identifier asn1dn; + proposal_check strict; + generate_policy on; + nat_traversal on; + dpd_delay 20; + ike_frag on; + proposal { + encryption_algorithm aes; + hash_algorithm sha1; + authentication_method hybrid_rsa_server; + dh_group 2; + } +} + +mode_cfg { + network4 10.99.99.0; + pool_size 255; + netmask4 255.255.255.0; + auth_source system; + dns4 10.0.12.1; + wins4 10.0.12.1; + banner "/etc/racoon/motd"; + pfs_group 2; +} + +sainfo anonymous { + pfs_group 2; + lifetime time 1 hour; + encryption_algorithm aes; + authentication_algorithm hmac_sha1; + compression_algorithm deflate; +} + diff --git a/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf-radius b/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf-radius new file mode 100644 index 00000000..24e8d4e8 --- /dev/null +++ b/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf-radius @@ -0,0 +1,42 @@ +path certificate "/etc/openssl/certs"; + +listen { + adminsock disabled; +} + +remote anonymous { + exchange_mode aggressive; + certificate_type x509 "server.crt" "server.key"; + my_identifier asn1dn; + proposal_check strict; + generate_policy on; + nat_traversal on; + dpd_delay 20; + ike_frag on; + proposal { + encryption_algorithm aes; + hash_algorithm sha1; + authentication_method hybrid_rsa_server; + dh_group 2; + } +} + +mode_cfg { + pool_size 255; + auth_source radius; + conf_source radius; + accounting radius; + dns4 10.0.12.1; + wins4 10.0.12.1; + banner "/etc/racoon/motd"; + pfs_group 2; +} + +sainfo anonymous { + pfs_group 2; + lifetime time 1 hour; + encryption_algorithm aes; + authentication_algorithm hmac_sha1; + compression_algorithm deflate; +} + diff --git a/ipsec-tools/src/racoon/schedule.c b/ipsec-tools/src/racoon/schedule.c new file mode 100644 index 00000000..018f920b --- /dev/null +++ b/ipsec-tools/src/racoon/schedule.c @@ -0,0 +1,311 @@ +/* $NetBSD: schedule.c,v 1.7 2009/01/23 09:10:13 tteras Exp $ */ + +/* $KAME: schedule.c,v 1.19 2001/11/05 10:53:19 sakane Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * Copyright (C) 2008 Timo Teras. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "misc.h" +#include "plog.h" +#include "schedule.h" +#include "var.h" +#include "gcmalloc.h" + +#ifndef TAILQ_FOREACH +#define TAILQ_FOREACH(elm, head, field) \ + for (elm = TAILQ_FIRST(head); elm; elm = TAILQ_NEXT(elm, field)) +#endif + +static TAILQ_HEAD(_schedtree, sched) sctree; + +void +sched_get_monotonic_time(tv) + struct timeval *tv; +{ +#ifdef HAVE_CLOCK_MONOTONIC + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; +#else + gettimeofday(tv, NULL); +#endif +} + +time_t +sched_monotonic_to_time_t(tv, now) + struct timeval *tv, *now; +{ +#ifdef HAVE_CLOCK_MONOTONIC + struct timeval mynow, res; + + if (now == NULL) { + sched_get_monotonic_time(&mynow); + now = &mynow; + } + timersub(now, tv, &res); + + return time(NULL) + res.tv_sec; +#else + return tv->tv_sec; +#endif +} + +/* + * schedule handler + * OUT: + * time to block until next event. + * if no entry, NULL returned. + */ +struct timeval * +schedular() +{ + static struct timeval timeout; + struct timeval now; + struct sched *p; + + sched_get_monotonic_time(&now); + while (!TAILQ_EMPTY(&sctree) && + timercmp(&TAILQ_FIRST(&sctree)->xtime, &now, <=)) { + void (*func)(struct sched *); + + p = TAILQ_FIRST(&sctree); + func = p->func; + sched_cancel(p); + func(p); + } + + p = TAILQ_FIRST(&sctree); + if (p == NULL) + return NULL; + + timersub(&p->xtime, &now, &timeout); + + return &timeout; +} + +/* + * add new schedule to schedule table. + */ +void +sched_schedule(sc, tick, func) + struct sched *sc; + time_t tick; + void (*func) __P((struct sched *)); +{ + static long id = 1; + struct sched *p; + struct timeval now; + + sched_cancel(sc); + + sc->func = func; + sc->id = id++; + sc->tick.tv_sec = tick; + sc->tick.tv_usec = 0; + sched_get_monotonic_time(&now); + timeradd(&now, &sc->tick, &sc->xtime); + + /* add to schedule table */ + TAILQ_FOREACH(p, &sctree, chain) { + if (timercmp(&sc->xtime, &p->xtime, <)) + break; + } + if (p == NULL) + TAILQ_INSERT_TAIL(&sctree, sc, chain); + else + TAILQ_INSERT_BEFORE(p, sc, chain); +} + +/* + * cancel scheduled callback + */ +void +sched_cancel(sc) + struct sched *sc; +{ + if (sc->func != NULL) { + TAILQ_REMOVE(&sctree, sc, chain); + sc->func = NULL; + } +} + +/* + * for debug + */ +int +sched_dump(buf, len) + caddr_t *buf; + int *len; +{ + caddr_t new; + struct sched *p; + struct scheddump *dst; + struct timeval now, created; + int cnt = 0; + + /* initialize */ + *len = 0; + *buf = NULL; + + TAILQ_FOREACH(p, &sctree, chain) + cnt++; + + /* no entry */ + if (cnt == 0) + return -1; + + *len = cnt * sizeof(*dst); + + new = racoon_malloc(*len); + if (new == NULL) + return -1; + dst = (struct scheddump *)new; + + sched_get_monotonic_time(&now); + p = TAILQ_FIRST(&sctree); + while (p) { + timersub(&p->xtime, &p->tick, &created); + dst->xtime = p->xtime.tv_sec; + dst->id = p->id; + dst->created = sched_monotonic_to_time_t(&created, &now); + dst->tick = p->tick.tv_sec; + + p = TAILQ_NEXT(p, chain); + if (p == NULL) + break; + dst++; + } + + *buf = new; + + return 0; +} + +/* initialize schedule table */ +void +sched_init() +{ + TAILQ_INIT(&sctree); +} + +#ifdef STEST +#include +#include +#include +#include + +void +test(tick) + int *tick; +{ + printf("execute %d\n", *tick); + racoon_free(tick); +} + +void +getstdin() +{ + int *tick; + char buf[16]; + + read(0, buf, sizeof(buf)); + if (buf[0] == 'd') { + struct scheddump *scbuf, *p; + int len; + sched_dump((caddr_t *)&scbuf, &len); + if (scbuf == NULL) + return; + for (p = scbuf; len; p++) { + printf("xtime=%ld\n", p->xtime); + len -= sizeof(*p); + } + racoon_free(scbuf); + return; + } + + tick = (int *)racoon_malloc(sizeof(*tick)); + *tick = atoi(buf); + printf("new queue tick = %d\n", *tick); + sched_new(*tick, test, tick); +} + +int +main() +{ + static fd_set mask0; + int nfds = 0; + fd_set rfds; + struct timeval *timeout; + int error; + + FD_ZERO(&mask0); + FD_SET(0, &mask0); + nfds = 1; + + /* initialize */ + sched_init(); + + while (1) { + rfds = mask0; + + timeout = schedular(); + + error = select(nfds, &rfds, (fd_set *)0, (fd_set *)0, timeout); + if (error < 0) { + switch (errno) { + case EINTR: continue; + default: + err(1, "select"); + } + /*NOTREACHED*/ + } + + if (FD_ISSET(0, &rfds)) + getstdin(); + } +} +#endif diff --git a/ipsec-tools/src/racoon/schedule.h b/ipsec-tools/src/racoon/schedule.h new file mode 100644 index 00000000..228e6779 --- /dev/null +++ b/ipsec-tools/src/racoon/schedule.h @@ -0,0 +1,99 @@ +/* $NetBSD: schedule.h,v 1.8 2009/08/17 12:00:53 vanhu Exp $ */ + +/* Id: schedule.h,v 1.5 2006/05/03 21:53:42 vanhu Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * Copyright (C) 2008 Timo Teras. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SCHEDULE_H +#define _SCHEDULE_H + +#include + +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#include "gnuc.h" + +#ifndef offsetof +#ifdef __compiler_offsetof +#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER) +#else +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif +#endif + +#ifndef container_of +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) +#endif + + +/* scheduling table */ +/* the head is the nearest event. */ +struct sched { + void (*func) __P((struct sched *)); /* callback on timeout */ + struct timeval xtime; /* expiration time */ + struct timeval tick; /* relative timeout */ + TAILQ_ENTRY(sched) chain; + long id; /* for debug */ +}; + +#define SCHED_INITIALIZER() { NULL, } + +struct scheddump { + time_t xtime; + long id; + time_t created; + time_t tick; +}; + +time_t sched_monotonic_to_time_t __P((struct timeval *tv, + struct timeval *now)); +void sched_get_monotonic_time __P((struct timeval *tv)); + +struct timeval *schedular __P((void)); +void sched_schedule __P((struct sched *, time_t, + void (*func) __P((struct sched *)))); +void sched_cancel __P((struct sched *)); + +int sched_dump __P((caddr_t *, int *)); +void sched_init __P((void)); + +#endif /* _SCHEDULE_H */ diff --git a/ipsec-tools/src/racoon/security.c b/ipsec-tools/src/racoon/security.c new file mode 100644 index 00000000..e4b5a0d6 --- /dev/null +++ b/ipsec-tools/src/racoon/security.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2005 International Business Machines Corporation + * Copyright (c) 2005 by Trusted Computer Solutions, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "config.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "var.h" +#include "vmbuf.h" +#include "misc.h" +#include "plog.h" + +#include "isakmp_var.h" +#include "isakmp.h" +#include "ipsec_doi.h" +#include "policy.h" +#include "proposal.h" +#include "strnames.h" +#include "handler.h" + +/* + * Get the security context information from SA. + */ +int +get_security_context(sa, p) + vchar_t *sa; + struct policyindex *p; +{ + int len = 0; + int flag, type = 0; + u_int16_t lorv; + caddr_t bp; + vchar_t *pbuf = NULL; + vchar_t *tbuf = NULL; + struct isakmp_parse_t *pa; + struct isakmp_parse_t *ta; + struct isakmp_pl_p *prop; + struct isakmp_pl_t *trns; + struct isakmp_data *d; + struct ipsecdoi_sa_b *sab = (struct ipsecdoi_sa_b *)sa->v; + + /* check SA payload size */ + if (sa->l < sizeof(*sab)) { + plog(LLV_ERROR, LOCATION, NULL, + "Invalid SA length = %zu.\n", sa->l); + return -1; + } + + bp = (caddr_t)(sab + 1); /* here bp points to first proposal payload */ + len = sa->l - sizeof(*sab); + + pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_P, (struct isakmp_gen *)bp, len); + if (pbuf == NULL) + return -1; + + pa = (struct isakmp_parse_t *)pbuf->v; + /* check the value of next payload */ + if (pa->type != ISAKMP_NPTYPE_P) { + plog(LLV_ERROR, LOCATION, NULL, + "Invalid payload type=%u\n", pa->type); + vfree(pbuf); + return -1; + } + + if (pa->len == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid proposal with length %d\n", pa->len); + vfree(pbuf); + return -1; + } + + /* our first proposal */ + prop = (struct isakmp_pl_p *)pa->ptr; + + /* now get transform */ + bp = (caddr_t)prop + sizeof(struct isakmp_pl_p) + prop->spi_size; + len = ntohs(prop->h.len) - + (sizeof(struct isakmp_pl_p) + prop->spi_size); + tbuf = isakmp_parsewoh(ISAKMP_NPTYPE_T, (struct isakmp_gen *)bp, len); + if (tbuf == NULL) + return -1; + + ta = (struct isakmp_parse_t *)tbuf->v; + if (ta->type != ISAKMP_NPTYPE_T) { + plog(LLV_ERROR, LOCATION, NULL, + "Invalid payload type=%u\n", ta->type); + return -1; + } + + trns = (struct isakmp_pl_t *)ta->ptr; + + len = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t); + d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t)); + + while (len > 0) { + type = ntohs(d->type) & ~ISAKMP_GEN_MASK; + flag = ntohs(d->type) & ISAKMP_GEN_MASK; + lorv = ntohs(d->lorv); + + if (type != IPSECDOI_ATTR_SECCTX) { + if (flag) { + len -= sizeof(*d); + d = (struct isakmp_data *)((char *)d + + sizeof(*d)); + } else { + len -= (sizeof(*d) + lorv); + d = (struct isakmp_data *)((caddr_t)d + + sizeof(*d) + lorv); + } + } else { + flag = ntohs(d->type & ISAKMP_GEN_MASK); + if (flag) { + plog(LLV_ERROR, LOCATION, NULL, + "SECCTX must be in TLV.\n"); + return -1; + } + memcpy(&p->sec_ctx, d + 1, lorv); + p->sec_ctx.ctx_strlen = ntohs(p->sec_ctx.ctx_strlen); + return 0; + } + } + return 0; +} + +void +set_secctx_in_proposal(iph2, spidx) + struct ph2handle *iph2; + struct policyindex spidx; +{ + iph2->proposal->sctx.ctx_doi = spidx.sec_ctx.ctx_doi; + iph2->proposal->sctx.ctx_alg = spidx.sec_ctx.ctx_alg; + iph2->proposal->sctx.ctx_strlen = spidx.sec_ctx.ctx_strlen; + memcpy(iph2->proposal->sctx.ctx_str, spidx.sec_ctx.ctx_str, + spidx.sec_ctx.ctx_strlen); +} + + +/* + * function: init_avc + * description: function performs the steps necessary to initialize the + * userspace avc. + * input: void + * return: 0 if avc was successfully initialized + * 1 if the avc could not be initialized + */ + +static int mls_ready = 0; + +void +init_avc(void) +{ + if (!is_selinux_mls_enabled()) { + plog(LLV_ERROR, LOCATION, NULL, "racoon: MLS support is not" + " enabled.\n"); + return; + } + + if (avc_init("racoon", NULL, NULL, NULL, NULL) == 0) + mls_ready = 1; + else + plog(LLV_ERROR, LOCATION, NULL, + "racoon: could not initialize avc.\n"); +} + +/* + * function: within_range + * description: function determines if the specified sl is within the + * configured range for a policy rule. + * input: security_context *sl SL + * char *range Range + * return: 1 if the sl is within the range + * 0 if the sl is not within the range or an error + * occurred which prevented the determination + */ + +int +within_range(security_context_t sl, security_context_t range) +{ + int rtn = 1; + security_id_t slsid; + security_id_t rangesid; + struct av_decision avd; + security_class_t tclass; + access_vector_t av; + + if (!*range) /* This policy doesn't have security context */ + return 1; + + if (!mls_ready) /* mls may not be enabled */ + return 0; + + /* + * Get the sids for the sl and range contexts + */ + rtn = avc_context_to_sid(sl, &slsid); + if (rtn != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "within_range: Unable to retrieve " + "sid for sl context (%s).\n", sl); + return 0; + } + rtn = avc_context_to_sid(range, &rangesid); + if (rtn != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "within_range: Unable to retrieve " + "sid for range context (%s).\n", range); + sidput(slsid); + return 0; + } + + /* + * Straight up test between sl and range + */ + tclass = SECCLASS_ASSOCIATION; + av = ASSOCIATION__POLMATCH; + rtn = avc_has_perm(slsid, rangesid, tclass, av, NULL, &avd); + if (rtn != 0) { + plog(LLV_INFO, LOCATION, NULL, + "within_range: The sl is not within range\n"); + sidput(slsid); + sidput(rangesid); + return 0; + } + plog(LLV_DEBUG, LOCATION, NULL, + "within_range: The sl (%s) is within range (%s)\n", sl, range); + return 1; +} diff --git a/ipsec-tools/src/racoon/session.c b/ipsec-tools/src/racoon/session.c new file mode 100644 index 00000000..85e29a39 --- /dev/null +++ b/ipsec-tools/src/racoon/session.c @@ -0,0 +1,540 @@ +/* $NetBSD: session.c,v 1.32 2011/03/02 15:09:16 vanhu Exp $ */ + +/* $KAME: session.c,v 1.32 2003/09/24 02:01:17 jinmei Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include +#if HAVE_SYS_WAIT_H +# include +#endif +#ifndef WEXITSTATUS +# define WEXITSTATUS(s) ((unsigned)(s) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(s) (((s) & 255) == 0) +#endif + +#include PATH_IPSEC_H + +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include + +#include +#include + +#include "libpfkey.h" + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "debug.h" + +#include "schedule.h" +#include "session.h" +#include "grabmyaddr.h" +#include "evt.h" +#include "cfparse_proto.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "isakmp_var.h" +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#include "admin_var.h" +#include "admin.h" +#include "privsep.h" +#include "oakley.h" +#include "pfkey.h" +#include "handler.h" +#include "localconf.h" +#include "remoteconf.h" +#include "backupsa.h" +#include "remoteconf.h" +#ifdef ENABLE_NATT +#include "nattraversal.h" +#endif + +#include "algorithm.h" /* XXX ??? */ + +#include "sainfo.h" + +struct fd_monitor { + int (*callback)(void *ctx, int fd); + void *ctx; + int prio; + int fd; + TAILQ_ENTRY(fd_monitor) chain; +}; + +#define NUM_PRIORITIES 2 + +static void close_session __P((void)); +static void initfds __P((void)); +static void init_signal __P((void)); +static int set_signal __P((int sig, RETSIGTYPE (*func) __P((int)))); +static void check_sigreq __P((void)); +static void check_flushsa __P((void)); +static int close_sockets __P((void)); + +static fd_set preset_mask, active_mask; +static struct fd_monitor fd_monitors[FD_SETSIZE]; +static TAILQ_HEAD(fd_monitor_list, fd_monitor) fd_monitor_tree[NUM_PRIORITIES]; +static int nfds = 0; + +static volatile sig_atomic_t sigreq[NSIG + 1]; +static struct sched scflushsa = SCHED_INITIALIZER(); + +void +monitor_fd(int fd, int (*callback)(void *, int), void *ctx, int priority) +{ + if (fd < 0 || fd >= FD_SETSIZE) { + plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun"); + exit(1); + } + + FD_SET(fd, &preset_mask); + if (fd > nfds) + nfds = fd; + if (priority <= 0) + priority = 0; + if (priority >= NUM_PRIORITIES) + priority = NUM_PRIORITIES - 1; + + fd_monitors[fd].callback = callback; + fd_monitors[fd].ctx = ctx; + fd_monitors[fd].prio = priority; + fd_monitors[fd].fd = fd; + TAILQ_INSERT_TAIL(&fd_monitor_tree[priority], + &fd_monitors[fd], chain); +} + +void +unmonitor_fd(int fd) +{ + if (fd < 0 || fd >= FD_SETSIZE) { + plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun"); + exit(1); + } + + if (fd_monitors[fd].callback == NULL) + return; + + FD_CLR(fd, &preset_mask); + FD_CLR(fd, &active_mask); + fd_monitors[fd].callback = NULL; + fd_monitors[fd].ctx = NULL; + TAILQ_REMOVE(&fd_monitor_tree[fd_monitors[fd].prio], + &fd_monitors[fd], chain); +} + +int +session(void) +{ + struct timeval *timeout; + int error; + char pid_file[MAXPATHLEN]; + FILE *fp; + pid_t racoon_pid = 0; + int i, count; + struct fd_monitor *fdm; + + nfds = 0; + FD_ZERO(&preset_mask); + + for (i = 0; i < NUM_PRIORITIES; i++) + TAILQ_INIT(&fd_monitor_tree[i]); + + /* initialize schedular */ + sched_init(); + init_signal(); + + if (pfkey_init() < 0) + errx(1, "failed to initialize pfkey socket"); + + if (isakmp_init() < 0) + errx(1, "failed to initialize ISAKMP structures"); + +#ifdef ENABLE_HYBRID + if (isakmp_cfg_init(ISAKMP_CFG_INIT_COLD)) + errx(1, "could not initialize ISAKMP mode config structures"); +#endif + +#ifdef HAVE_LIBLDAP + if (xauth_ldap_init_conf() != 0) + errx(1, "could not initialize ldap config"); +#endif + +#ifdef HAVE_LIBRADIUS + if (xauth_radius_init_conf(0) != 0) + errx(1, "could not initialize radius config"); +#endif + + myaddr_init_lists(); + + /* + * in order to prefer the parameters by command line, + * saving some parameters before parsing configuration file. + */ + save_params(); + if (cfparse() != 0) + errx(1, "failed to parse configuration file."); + restore_params(); + +#ifdef ENABLE_ADMINPORT + if (admin_init() < 0) + errx(1, "failed to initialize admin port socket"); +#endif + + +#ifdef ENABLE_HYBRID + if(isakmp_cfg_config.network4 && isakmp_cfg_config.pool_size == 0) + if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0) + return error; +#endif + + if (dump_config) + dumprmconf(); + +#ifdef HAVE_LIBRADIUS + if (xauth_radius_init() != 0) + errx(1, "could not initialize libradius"); +#endif + + if (myaddr_init() != 0) + errx(1, "failed to listen to configured addresses"); + myaddr_sync(); + +#ifdef ENABLE_NATT + natt_keepalive_init (); +#endif + + /* write .pid file */ + if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE] == NULL) + strlcpy(pid_file, _PATH_VARRUN "racoon.pid", MAXPATHLEN); + else if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE][0] == '/') + strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN); + else { + strlcat(pid_file, _PATH_VARRUN, MAXPATHLEN); + strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN); + } + fp = fopen(pid_file, "w"); + if (fp) { + if (fchmod(fileno(fp), + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { + syslog(LOG_ERR, "%s", strerror(errno)); + fclose(fp); + exit(1); + } + } else { + plog(LLV_ERROR, LOCATION, NULL, + "cannot open %s", pid_file); + } + + if (privsep_init() != 0) + exit(1); + + /* + * The fork()'ed privileged side will close its copy of fp. We wait + * until here to get the correct child pid. + */ + racoon_pid = getpid(); + fprintf(fp, "%ld\n", (long)racoon_pid); + fclose(fp); + + for (i = 0; i <= NSIG; i++) + sigreq[i] = 0; + + while (1) { + /* + * asynchronous requests via signal. + * make sure to reset sigreq to 0. + */ + check_sigreq(); + + /* scheduling */ + timeout = schedular(); + + /* schedular can change select() mask, so we reset + * the working copy here */ + active_mask = preset_mask; + + error = select(nfds + 1, &active_mask, NULL, NULL, timeout); + if (error < 0) { + switch (errno) { + case EINTR: + continue; + default: + plog(LLV_ERROR, LOCATION, NULL, + "failed to select (%s)\n", + strerror(errno)); + return -1; + } + /*NOTREACHED*/ + } + + count = 0; + for (i = 0; i < NUM_PRIORITIES; i++) { + TAILQ_FOREACH(fdm, &fd_monitor_tree[i], chain) { + if (!FD_ISSET(fdm->fd, &active_mask)) + continue; + + FD_CLR(fdm->fd, &active_mask); + if (fdm->callback != NULL) { + fdm->callback(fdm->ctx, fdm->fd); + count++; + } else + plog(LLV_ERROR, LOCATION, NULL, + "fd %d set, but no active callback\n", i); + } + if (count != 0) + break; + } + + } +} + +/* clear all status and exit program. */ +static void +close_session() +{ + evt_generic(EVT_RACOON_QUIT, NULL); + pfkey_send_flush(lcconf->sock_pfkey, SADB_SATYPE_UNSPEC); + flushph2(); + flushph1(); + flushrmconf(); + flushsainfo(); + close_sockets(); + backupsa_clean(); + + plog(LLV_INFO, LOCATION, NULL, "racoon process %d shutdown\n", getpid()); + + exit(0); +} + +static int signals[] = { + SIGHUP, + SIGINT, + SIGTERM, + SIGUSR1, + SIGUSR2, + SIGCHLD, + 0 +}; + +/* + * asynchronous requests will actually dispatched in the + * main loop in session(). + */ +RETSIGTYPE +signal_handler(sig) + int sig; +{ + sigreq[sig] = 1; +} + + +/* XXX possible mem leaks and no way to go back for now !!! + */ +static void reload_conf(){ + int error; + +#ifdef ENABLE_HYBRID + if ((isakmp_cfg_init(ISAKMP_CFG_INIT_WARM)) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "ISAKMP mode config structure reset failed, " + "not reloading\n"); + return; + } +#endif + + sainfo_start_reload(); + + /* TODO: save / restore / flush old lcconf (?) / rmtree + */ + rmconf_start_reload(); + +#ifdef HAVE_LIBRADIUS + /* free and init radius configuration */ + xauth_radius_init_conf(1); +#endif + + pfkey_reload(); + + save_params(); + flushlcconf(); + error = cfparse(); + if (error != 0){ + plog(LLV_ERROR, LOCATION, NULL, "config reload failed\n"); + /* We are probably in an inconsistant state... */ + return; + } + restore_params(); + +#if 0 + if (dump_config) + dumprmconf (); +#endif + + myaddr_sync(); + +#ifdef HAVE_LIBRADIUS + /* re-initialize radius state */ + xauth_radius_init(); +#endif + + /* Revalidate ph1 / ph2tree !!! + * update ctdtree if removing some ph1 ! + */ + revalidate_ph12(); + /* Update ctdtree ? + */ + + sainfo_finish_reload(); + rmconf_finish_reload(); +} + +static void +check_sigreq() +{ + int sig, s; + + for (sig = 0; sig <= NSIG; sig++) { + if (sigreq[sig] == 0) + continue; + sigreq[sig] = 0; + + switch(sig) { + case 0: + return; + + case SIGCHLD: + /* Reap all pending children */ + while (waitpid(-1, &s, WNOHANG) > 0) + ; + break; + +#ifdef DEBUG_RECORD_MALLOCATION + /* + * XXX This operation is signal handler unsafe and may lead to + * crashes and security breaches: See Henning Brauer talk at + * EuroBSDCon 2005. Do not run in production with this option + * enabled. + */ + case SIGUSR2: + DRM_dump(); + break; +#endif + + case SIGHUP: + /* Save old configuration, load new one... */ + reload_conf(); + break; + + case SIGINT: + case SIGTERM: + plog(LLV_INFO, LOCATION, NULL, + "caught signal %d\n", sig); + close_session(); + break; + + default: + plog(LLV_INFO, LOCATION, NULL, + "caught signal %d\n", sig); + break; + } + } +} + +static void +init_signal() +{ + int i; + + /* + * Ignore SIGPIPE as we check the return value of system calls + * that write to pipe-like fds. + */ + signal(SIGPIPE, SIG_IGN); + + for (i = 0; signals[i] != 0; i++) + if (set_signal(signals[i], signal_handler) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set_signal (%s)\n", + strerror(errno)); + exit(1); + } +} + +static int +set_signal(sig, func) + int sig; + RETSIGTYPE (*func) __P((int)); +{ + struct sigaction sa; + + memset((caddr_t)&sa, 0, sizeof(sa)); + sa.sa_handler = func; + sa.sa_flags = SA_RESTART; + + if (sigemptyset(&sa.sa_mask) < 0) + return -1; + + if (sigaction(sig, &sa, (struct sigaction *)0) < 0) + return(-1); + + return 0; +} + +static int +close_sockets() +{ + myaddr_close(); + pfkey_close(lcconf->sock_pfkey); +#ifdef ENABLE_ADMINPORT + (void)admin_close(); +#endif + return 0; +} + diff --git a/ipsec-tools/src/racoon/session.h b/ipsec-tools/src/racoon/session.h new file mode 100644 index 00000000..7764c62a --- /dev/null +++ b/ipsec-tools/src/racoon/session.h @@ -0,0 +1,43 @@ +/* $NetBSD: session.h,v 1.9 2010/10/21 06:15:28 tteras Exp $ */ + +/* Id: session.h,v 1.3 2004/06/11 16:00:17 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SESSION_H +#define _SESSION_H + +extern int session __P((void)); +extern RETSIGTYPE signal_handler __P((int)); + +extern void monitor_fd __P((int fd, int (*callback)(void *, int), void *ctx, int priority)); +extern void unmonitor_fd __P((int fd)); + +#endif /* _SESSION_H */ diff --git a/ipsec-tools/src/racoon/sockmisc.c b/ipsec-tools/src/racoon/sockmisc.c new file mode 100644 index 00000000..4cfe7906 --- /dev/null +++ b/ipsec-tools/src/racoon/sockmisc.c @@ -0,0 +1,1006 @@ +/* $NetBSD: sockmisc.c,v 1.19 2011/03/14 17:18:13 tteras Exp $ */ + +/* Id: sockmisc.c,v 1.24 2006/05/07 21:32:59 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include PATH_IPSEC_H + +#if defined(INET6) && !defined(INET6_ADVAPI) && \ + defined(IP_RECVDSTADDR) && !defined(IPV6_RECVDSTADDR) +#define IPV6_RECVDSTADDR IP_RECVDSTADDR +#endif + +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "debug.h" +#include "gcmalloc.h" +#include "debugrm.h" +#include "libpfkey.h" +#include "isakmp_var.h" + +#ifdef NOUSE_PRIVSEP +#define BIND bind +#define SOCKET socket +#define SETSOCKOPT setsockopt +#else +#include "admin.h" +#include "privsep.h" +#define BIND privsep_bind +#define SOCKET privsep_socket +#define SETSOCKOPT privsep_setsockopt +#endif + +const int niflags = 0; + +/* + * compare two sockaddr with port, taking care wildcard. + * addr1 is a subject address, addr2 is in a database entry. + * OUT: 0: equal. + * 1: not equal. + */ +int +cmpsaddr(addr1, addr2) + const struct sockaddr *addr1; + const struct sockaddr *addr2; +{ + caddr_t sa1, sa2; + u_short port1 = IPSEC_PORT_ANY; + u_short port2 = IPSEC_PORT_ANY; + + if (addr1 == NULL && addr2 == NULL) + return CMPSADDR_MATCH; + + if (addr1 == NULL || addr2 == NULL) + return CMPSADDR_MISMATCH; + + if (addr1->sa_family != addr2->sa_family || + sysdep_sa_len(addr1) != sysdep_sa_len(addr2)) + return CMPSADDR_MISMATCH; + + switch (addr1->sa_family) { + case AF_UNSPEC: + break; + case AF_INET: + sa1 = (caddr_t)&((struct sockaddr_in *)addr1)->sin_addr; + sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr; + port1 = ((struct sockaddr_in *)addr1)->sin_port; + port2 = ((struct sockaddr_in *)addr2)->sin_port; + if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0) + return CMPSADDR_MISMATCH; + break; +#ifdef INET6 + case AF_INET6: + sa1 = (caddr_t)&((struct sockaddr_in6 *)addr1)->sin6_addr; + sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr; + port1 = ((struct sockaddr_in6 *)addr1)->sin6_port; + port2 = ((struct sockaddr_in6 *)addr2)->sin6_port; + if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0) + return CMPSADDR_MISMATCH; + if (((struct sockaddr_in6 *)addr1)->sin6_scope_id != + ((struct sockaddr_in6 *)addr2)->sin6_scope_id) + return CMPSADDR_MISMATCH; + break; +#endif + default: + return CMPSADDR_MISMATCH; + } + + if (port1 == port2) + return CMPSADDR_MATCH; + + if (port1 == IPSEC_PORT_ANY || + port2 == IPSEC_PORT_ANY) + return CMPSADDR_WILDPORT_MATCH; + + return CMPSADDR_WOP_MATCH; +} + +/* get local address against the destination. */ +struct sockaddr * +getlocaladdr(remote) + struct sockaddr *remote; +{ + struct sockaddr *local; + u_int local_len = sizeof(struct sockaddr_storage); + int s; /* for dummy connection */ + + /* allocate buffer */ + if ((local = racoon_calloc(1, local_len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get address buffer.\n"); + goto err; + } + + /* get real interface received packet */ + if ((s = SOCKET(remote->sa_family, SOCK_DGRAM, 0)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "socket (%s)\n", strerror(errno)); + goto err; + } + + setsockopt_bypass(s, remote->sa_family); + + if (connect(s, remote, sysdep_sa_len(remote)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "connect (%s)\n", strerror(errno)); + close(s); + goto err; + } + + if (getsockname(s, local, &local_len) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "getsockname (%s)\n", strerror(errno)); + close(s); + return NULL; + } + + close(s); + return local; + + err: + if (local != NULL) + racoon_free(local); + return NULL; +} + +/* + * Receive packet, with src/dst information. It is assumed that necessary + * setsockopt() have already performed on socket. + */ +int +recvfromto(s, buf, buflen, flags, from, fromlen, to, tolen) + int s; + void *buf; + size_t buflen; + int flags; + struct sockaddr *from; + socklen_t *fromlen; + struct sockaddr *to; + u_int *tolen; +{ + int otolen; + socklen_t slen; + int len; + union sockaddr_any sa; + struct msghdr m; + struct cmsghdr *cm; + struct iovec iov[2]; + u_char cmsgbuf[256]; +#if defined(INET6) && defined(INET6_ADVAPI) + struct in6_pktinfo *pi; +#endif /*INET6_ADVAPI*/ + struct sockaddr_in *sin; +#ifdef INET6 + struct sockaddr_in6 *sin6; +#endif + + slen = sizeof(sa); + if (getsockname(s, &sa.sa, &slen) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "getsockname (%s)\n", strerror(errno)); + return -1; + } + + m.msg_name = (caddr_t)from; + m.msg_namelen = *fromlen; + iov[0].iov_base = (caddr_t)buf; + iov[0].iov_len = buflen; + m.msg_iov = iov; + m.msg_iovlen = 1; + memset(cmsgbuf, 0, sizeof(cmsgbuf)); + cm = (struct cmsghdr *)cmsgbuf; + m.msg_control = (caddr_t)cm; + m.msg_controllen = sizeof(cmsgbuf); + if ((len = recvmsg(s, &m, flags)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "recvmsg (%s)\n", strerror(errno)); + return -1; + } + *fromlen = m.msg_namelen; + + otolen = *tolen; + *tolen = 0; + for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&m); + m.msg_controllen != 0 && cm; + cm = (struct cmsghdr *)CMSG_NXTHDR(&m, cm)) { +#if 0 + plog(LLV_ERROR, LOCATION, NULL, + "cmsg %d %d\n", cm->cmsg_level, cm->cmsg_type);) +#endif +#if defined(INET6) && defined(INET6_ADVAPI) + if (sa.sa.sa_family == AF_INET6 + && cm->cmsg_level == IPPROTO_IPV6 + && cm->cmsg_type == IPV6_PKTINFO + && otolen >= sizeof(*sin6)) { + pi = (struct in6_pktinfo *)(CMSG_DATA(cm)); + *tolen = sizeof(*sin6); + sin6 = (struct sockaddr_in6 *)to; + memset(sin6, 0, sizeof(*sin6)); + sin6->sin6_family = AF_INET6; +#ifndef __linux__ + sin6->sin6_len = sizeof(*sin6); +#endif + memcpy(&sin6->sin6_addr, &pi->ipi6_addr, + sizeof(sin6->sin6_addr)); + /* XXX other cases, such as site-local? */ + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + sin6->sin6_scope_id = pi->ipi6_ifindex; + else + sin6->sin6_scope_id = 0; + sin6->sin6_port = sa.sin6.sin6_port; + otolen = -1; /* "to" already set */ + continue; + } +#endif +#ifdef __linux__ + if (sa.sa.sa_family == AF_INET + && cm->cmsg_level == IPPROTO_IP + && cm->cmsg_type == IP_PKTINFO + && otolen >= sizeof(sin)) { + struct in_pktinfo *pi = (struct in_pktinfo *)(CMSG_DATA(cm)); + *tolen = sizeof(*sin); + sin = (struct sockaddr_in *)to; + memset(sin, 0, sizeof(*sin)); + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr, &pi->ipi_addr, + sizeof(sin->sin_addr)); + sin->sin_port = sa.sin.sin_port; + otolen = -1; /* "to" already set */ + continue; + } +#endif +#if defined(INET6) && defined(IPV6_RECVDSTADDR) + if (sa.sa.sa_family == AF_INET6 + && cm->cmsg_level == IPPROTO_IPV6 + && cm->cmsg_type == IPV6_RECVDSTADDR + && otolen >= sizeof(*sin6)) { + *tolen = sizeof(*sin6); + sin6 = (struct sockaddr_in6 *)to; + memset(sin6, 0, sizeof(*sin6)); + sin6->sin6_family = AF_INET6; + sin6->sin6_len = sizeof(*sin6); + memcpy(&sin6->sin6_addr, CMSG_DATA(cm), + sizeof(sin6->sin6_addr)); + sin6->sin6_port = sa.sin6.sin6_port; + otolen = -1; /* "to" already set */ + continue; + } +#endif +#ifndef __linux__ + if (sa.sa.sa_family == AF_INET + && cm->cmsg_level == IPPROTO_IP + && cm->cmsg_type == IP_RECVDSTADDR + && otolen >= sizeof(*sin)) { + *tolen = sizeof(*sin); + sin = (struct sockaddr_in *)to; + memset(sin, 0, sizeof(*sin)); + sin->sin_family = AF_INET; + sin->sin_len = sizeof(*sin); + memcpy(&sin->sin_addr, CMSG_DATA(cm), + sizeof(sin->sin_addr)); + sin->sin_port = sa.sin.sin_port; + otolen = -1; /* "to" already set */ + continue; + } +#endif + } + + return len; +} + +/* send packet, with fixing src/dst address pair. */ +int +sendfromto(s, buf, buflen, src, dst, cnt) + int s, cnt; + const void *buf; + size_t buflen; + struct sockaddr *src; + struct sockaddr *dst; +{ + struct sockaddr_storage ss; + socklen_t slen; + int len = 0; + int i; + + if (src->sa_family != dst->sa_family) { + plog(LLV_ERROR, LOCATION, NULL, + "address family mismatch\n"); + return -1; + } + + slen = sizeof(ss); + if (getsockname(s, (struct sockaddr *)&ss, &slen) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "getsockname (%s)\n", strerror(errno)); + return -1; + } + + plog(LLV_DEBUG, LOCATION, NULL, + "sockname %s\n", saddr2str((struct sockaddr *)&ss)); + plog(LLV_DEBUG, LOCATION, NULL, + "send packet from %s\n", saddr2str(src)); + plog(LLV_DEBUG, LOCATION, NULL, + "send packet to %s\n", saddr2str(dst)); + + if (src->sa_family != ss.ss_family) { + plog(LLV_ERROR, LOCATION, NULL, + "address family mismatch\n"); + return -1; + } + + switch (src->sa_family) { +#if defined(INET6) && defined(INET6_ADVAPI) +// XXX: This block wasn't compiled on Linux - does it work? + case AF_INET6: + { + struct msghdr m; + struct cmsghdr *cm; + struct iovec iov[2]; + u_char cmsgbuf[256]; + struct in6_pktinfo *pi; + int ifindex; + struct sockaddr_in6 src6, dst6; + + memcpy(&src6, src, sizeof(src6)); + memcpy(&dst6, dst, sizeof(dst6)); + + /* XXX take care of other cases, such as site-local */ + ifindex = 0; + if (IN6_IS_ADDR_LINKLOCAL(&src6.sin6_addr) + || IN6_IS_ADDR_MULTICAST(&src6.sin6_addr)) { + ifindex = src6.sin6_scope_id; /*???*/ + } + + /* XXX some sanity check on dst6.sin6_scope_id */ + + /* flowinfo for IKE? mmm, maybe useful but for now make it 0 */ + src6.sin6_flowinfo = dst6.sin6_flowinfo = 0; + + memset(&m, 0, sizeof(m)); + m.msg_name = (caddr_t)&dst6; + m.msg_namelen = sizeof(dst6); + iov[0].iov_base = (char *)buf; + iov[0].iov_len = buflen; + m.msg_iov = iov; + m.msg_iovlen = 1; + + memset(cmsgbuf, 0, sizeof(cmsgbuf)); + cm = (struct cmsghdr *)cmsgbuf; + m.msg_control = (caddr_t)cm; + m.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); + + cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); + cm->cmsg_level = IPPROTO_IPV6; + cm->cmsg_type = IPV6_PKTINFO; + pi = (struct in6_pktinfo *)CMSG_DATA(cm); + memcpy(&pi->ipi6_addr, &src6.sin6_addr, sizeof(src6.sin6_addr)); + pi->ipi6_ifindex = ifindex; + + plog(LLV_DEBUG, LOCATION, NULL, + "src6 %s %d\n", + saddr2str((struct sockaddr *)&src6), + src6.sin6_scope_id); + plog(LLV_DEBUG, LOCATION, NULL, + "dst6 %s %d\n", + saddr2str((struct sockaddr *)&dst6), + dst6.sin6_scope_id); + + for (i = 0; i < cnt; i++) { + len = sendmsg(s, &m, 0 /*MSG_DONTROUTE*/); + if (len < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "sendmsg (%s)\n", strerror(errno)); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, + "%d times of %d bytes message will be sent " + "to %s\n", + i + 1, len, saddr2str(dst)); + } + plogdump(LLV_DEBUG, (char *)buf, buflen); + + return len; + } +#endif +#ifdef __linux__ + case AF_INET: + { + struct msghdr m; + struct cmsghdr *cm; + struct iovec iov[2]; + u_char cmsgbuf[256]; + struct in_pktinfo *pi; + int ifindex = 0; + struct sockaddr_in src6, dst6; + + memcpy(&src6, src, sizeof(src6)); + memcpy(&dst6, dst, sizeof(dst6)); + + memset(&m, 0, sizeof(m)); + m.msg_name = (caddr_t)&dst6; + m.msg_namelen = sizeof(dst6); + iov[0].iov_base = (char *)buf; + iov[0].iov_len = buflen; + m.msg_iov = iov; + m.msg_iovlen = 1; + + memset(cmsgbuf, 0, sizeof(cmsgbuf)); + cm = (struct cmsghdr *)cmsgbuf; + m.msg_control = (caddr_t)cm; + m.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo)); + + cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); + cm->cmsg_level = IPPROTO_IP; + cm->cmsg_type = IP_PKTINFO; + pi = (struct in_pktinfo *)CMSG_DATA(cm); + memcpy(&pi->ipi_spec_dst, &src6.sin_addr, sizeof(src6.sin_addr)); + pi->ipi_ifindex = ifindex; + + plog(LLV_DEBUG, LOCATION, NULL, + "src4 %s\n", + saddr2str((struct sockaddr *)&src6)); + plog(LLV_DEBUG, LOCATION, NULL, + "dst4 %s\n", + saddr2str((struct sockaddr *)&dst6)); + + for (i = 0; i < cnt; i++) { + len = sendmsg(s, &m, 0 /*MSG_DONTROUTE*/); + if (len < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "sendmsg (%s)\n", strerror(errno)); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, + "%d times of %d bytes message will be sent " + "to %s\n", + i + 1, len, saddr2str(dst)); + } + plogdump(LLV_DEBUG, (char *)buf, buflen); + + return len; + } +#endif /* __linux__ */ + default: + { + int needclose = 0; + int sendsock; + + if (ss.ss_family == src->sa_family && memcmp(&ss, src, sysdep_sa_len(src)) == 0) { + sendsock = s; + needclose = 0; + } else { + int yes = 1; + /* + * Use newly opened socket for sending packets. + * NOTE: this is unsafe, because if the peer is quick enough + * the packet from the peer may be queued into sendsock. + * Better approach is to prepare bind'ed udp sockets for + * each of the interface addresses. + */ + sendsock = SOCKET(src->sa_family, SOCK_DGRAM, 0); + if (sendsock < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "socket (%s)\n", strerror(errno)); + return -1; + } + if (setsockopt(sendsock, SOL_SOCKET, +#ifdef __linux__ + SO_REUSEADDR, +#else + SO_REUSEPORT, +#endif + (void *)&yes, sizeof(yes)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "setsockopt SO_REUSEPORT (%s)\n", + strerror(errno)); + close(sendsock); + return -1; + } +#ifdef IPV6_USE_MIN_MTU + if (src->sa_family == AF_INET6 && + setsockopt(sendsock, IPPROTO_IPV6, IPV6_USE_MIN_MTU, + (void *)&yes, sizeof(yes)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "setsockopt IPV6_USE_MIN_MTU (%s)\n", + strerror(errno)); + close(sendsock); + return -1; + } +#endif + if (setsockopt_bypass(sendsock, src->sa_family) < 0) { + close(sendsock); + return -1; + } + + if (BIND(sendsock, (struct sockaddr *)src, + sysdep_sa_len(src)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "bind 1 (%s)\n", strerror(errno)); + close(sendsock); + return -1; + } + needclose = 1; + } + + for (i = 0; i < cnt; i++) { + len = sendto(sendsock, buf, buflen, 0, dst, sysdep_sa_len(dst)); + if (len < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "sendto (%s)\n", strerror(errno)); + if (needclose) + close(sendsock); + return len; + } + plog(LLV_DEBUG, LOCATION, NULL, + "%d times of %d bytes message will be sent " + "to %s\n", + i + 1, len, saddr2str(dst)); + } + plogdump(LLV_DEBUG, (char *)buf, buflen); + + if (needclose) + close(sendsock); + + return len; + } + } +} + +int +setsockopt_bypass(so, family) + int so, family; +{ + int level; + char *buf; + char *policy; + + switch (family) { + case AF_INET: + level = IPPROTO_IP; + break; +#ifdef INET6 + case AF_INET6: + level = IPPROTO_IPV6; + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "unsupported address family %d\n", family); + return -1; + } + + policy = "in bypass"; + buf = ipsec_set_policy(policy, strlen(policy)); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "ipsec_set_policy (%s)\n", + ipsec_strerror()); + return -1; + } + if (SETSOCKOPT(so, level, + (level == IPPROTO_IP ? + IP_IPSEC_POLICY : IPV6_IPSEC_POLICY), + buf, ipsec_get_policylen(buf)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "setsockopt IP_IPSEC_POLICY (%s)\n", + strerror(errno)); + return -1; + } + racoon_free(buf); + + policy = "out bypass"; + buf = ipsec_set_policy(policy, strlen(policy)); + if (buf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "ipsec_set_policy (%s)\n", + ipsec_strerror()); + return -1; + } + if (SETSOCKOPT(so, level, + (level == IPPROTO_IP ? + IP_IPSEC_POLICY : IPV6_IPSEC_POLICY), + buf, ipsec_get_policylen(buf)) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "setsockopt IP_IPSEC_POLICY (%s)\n", + strerror(errno)); + return -1; + } + racoon_free(buf); + + return 0; +} + +struct sockaddr * +newsaddr(len) + int len; +{ + struct sockaddr *new; + + if ((new = racoon_calloc(1, len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "%s\n", strerror(errno)); + goto out; + } + +#ifdef __linux__ + if (len == sizeof (struct sockaddr_in6)) + new->sa_family = AF_INET6; + else + new->sa_family = AF_INET; +#else + /* initial */ + new->sa_len = len; +#endif +out: + return new; +} + +struct sockaddr * +dupsaddr(src) + struct sockaddr *src; +{ + struct sockaddr *dst; + + dst = racoon_calloc(1, sysdep_sa_len(src)); + if (dst == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "%s\n", strerror(errno)); + return NULL; + } + + memcpy(dst, src, sysdep_sa_len(src)); + + return dst; +} + +char * +saddr2str(saddr) + const struct sockaddr *saddr; +{ + static char buf[NI_MAXHOST + NI_MAXSERV + 10]; + char addr[NI_MAXHOST], port[NI_MAXSERV]; + + if (saddr == NULL) + return NULL; + + if (saddr->sa_family == AF_UNSPEC) + snprintf (buf, sizeof(buf), "%s", "anonymous"); + else { + GETNAMEINFO(saddr, addr, port); + snprintf(buf, sizeof(buf), "%s[%s]", addr, port); + } + + return buf; +} + +char * +saddrwop2str(saddr) + const struct sockaddr *saddr; +{ + static char buf[NI_MAXHOST + NI_MAXSERV + 10]; + char addr[NI_MAXHOST]; + + if (saddr == NULL) + return NULL; + + GETNAMEINFO_NULL(saddr, addr); + snprintf(buf, sizeof(buf), "%s", addr); + + return buf; +} + +char * +naddrwop2str(const struct netaddr *naddr) +{ + static char buf[NI_MAXHOST + 10]; + static const struct sockaddr sa_any; /* this is initialized to all zeros */ + + if (naddr == NULL) + return NULL; + + if (memcmp(&naddr->sa, &sa_any, sizeof(sa_any)) == 0) + snprintf(buf, sizeof(buf), "%s", "any"); + else { + snprintf(buf, sizeof(buf), "%s", saddrwop2str(&naddr->sa.sa)); + snprintf(&buf[strlen(buf)], sizeof(buf) - strlen(buf), "/%ld", naddr->prefix); + } + return buf; +} + +char * +naddrwop2str_fromto(const char *format, const struct netaddr *saddr, + const struct netaddr *daddr) +{ + static char buf[2*(NI_MAXHOST + NI_MAXSERV + 10) + 100]; + char *src, *dst; + + src = racoon_strdup(naddrwop2str(saddr)); + dst = racoon_strdup(naddrwop2str(daddr)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + /* WARNING: Be careful about the format string! Don't + ever pass in something that a user can modify!!! */ + snprintf (buf, sizeof(buf), format, src, dst); + racoon_free (src); + racoon_free (dst); + + return buf; +} + +char * +saddr2str_fromto(format, saddr, daddr) + const char *format; + const struct sockaddr *saddr; + const struct sockaddr *daddr; +{ + static char buf[2*(NI_MAXHOST + NI_MAXSERV + 10) + 100]; + char *src, *dst; + + src = racoon_strdup(saddr2str(saddr)); + dst = racoon_strdup(saddr2str(daddr)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + /* WARNING: Be careful about the format string! Don't + ever pass in something that a user can modify!!! */ + snprintf (buf, sizeof(buf), format, src, dst); + racoon_free (src); + racoon_free (dst); + + return buf; +} + +struct sockaddr * +str2saddr(host, port) + char *host; + char *port; +{ + struct addrinfo hints, *res; + struct sockaddr *saddr; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_NUMERICHOST; + error = getaddrinfo(host, port, &hints, &res); + if (error != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "getaddrinfo(%s%s%s): %s\n", + host, port ? "," : "", port ? port : "", + gai_strerror(error)); + return NULL; + } + if (res->ai_next != NULL) { + plog(LLV_WARNING, LOCATION, NULL, + "getaddrinfo(%s%s%s): " + "resolved to multiple address, " + "taking the first one\n", + host, port ? "," : "", port ? port : ""); + } + saddr = racoon_malloc(res->ai_addrlen); + if (saddr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer.\n"); + freeaddrinfo(res); + return NULL; + } + memcpy(saddr, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + + return saddr; +} + +void +mask_sockaddr(a, b, l) + struct sockaddr *a; + const struct sockaddr *b; + size_t l; +{ + size_t i; + u_int8_t *p, alen; + + switch (b->sa_family) { + case AF_INET: + alen = sizeof(struct in_addr); + p = (u_int8_t *)&((struct sockaddr_in *)a)->sin_addr; + break; +#ifdef INET6 + case AF_INET6: + alen = sizeof(struct in6_addr); + p = (u_int8_t *)&((struct sockaddr_in6 *)a)->sin6_addr; + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid family: %d\n", b->sa_family); + exit(1); + } + + if ((alen << 3) < l) { + plog(LLV_ERROR, LOCATION, NULL, + "unexpected inconsistency: %d %zu\n", b->sa_family, l); + exit(1); + } + + memcpy(a, b, sysdep_sa_len(b)); + p[l / 8] &= (0xff00 >> (l % 8)) & 0xff; + for (i = l / 8 + 1; i < alen; i++) + p[i] = 0x00; +} + +/* Compute a score describing how "accurate" a netaddr is for a given sockaddr. + * Examples: + * Return values for address 10.20.30.40 [port 500] and given netaddresses... + * 10.10.0.0/16 => -1 ... doesn't match + * 0.0.0.0/0 => 0 ... matches, but only 0 bits. + * 10.20.0.0/16 => 16 ... 16 bits match + * 10.20.30.0/24 => 24 ... guess what ;-) + * 10.20.30.40/32 => 32 ... whole address match + * 10.20.30.40:500 => 33 ... both address and port match + * 10.20.30.40:501 => -1 ... port doesn't match and isn't 0 (=any) + */ +int +naddr_score(const struct netaddr *naddr, const struct sockaddr *saddr) +{ + static const struct netaddr naddr_any; /* initialized to all-zeros */ + struct sockaddr sa; + u_int16_t naddr_port, saddr_port; + int port_score; + + if (!naddr || !saddr) { + plog(LLV_ERROR, LOCATION, NULL, + "Call with null args: naddr=%p, saddr=%p\n", + naddr, saddr); + return -1; + } + + /* Wildcard address matches, but only 0 bits. */ + if (memcmp(naddr, &naddr_any, sizeof(naddr_any)) == 0) + return 0; + + /* If families don't match we really can't do much... */ + if (naddr->sa.sa.sa_family != saddr->sa_family) + return -1; + + /* If port check fail don't bother to check addresses. */ + naddr_port = extract_port(&naddr->sa.sa); + saddr_port = extract_port(saddr); + if (naddr_port == 0 || saddr_port == 0) /* wildcard match */ + port_score = 0; + else if (naddr_port == saddr_port) /* exact match */ + port_score = 1; + else /* mismatch :-) */ + return -1; + + /* Here it comes - compare network addresses. */ + mask_sockaddr(&sa, saddr, naddr->prefix); + if (loglevel >= LLV_DEBUG) { /* debug only */ + char *a1, *a2, *a3; + a1 = racoon_strdup(naddrwop2str(naddr)); + a2 = racoon_strdup(saddrwop2str(saddr)); + a3 = racoon_strdup(saddrwop2str(&sa)); + STRDUP_FATAL(a1); + STRDUP_FATAL(a2); + STRDUP_FATAL(a3); + plog(LLV_DEBUG, LOCATION, NULL, + "naddr=%s, saddr=%s (masked=%s)\n", + a1, a2, a3); + free(a1); + free(a2); + free(a3); + } + if (cmpsaddr(&sa, &naddr->sa.sa) <= CMPSADDR_WOP_MATCH) + return naddr->prefix + port_score; + + return -1; +} + +/* Some useful functions for sockaddr port manipulations. */ +u_int16_t +extract_port (const struct sockaddr *addr) +{ + u_int16_t port = 0; + + if (!addr) + return port; + + switch (addr->sa_family) { + case AF_UNSPEC: + break; + case AF_INET: + port = ((struct sockaddr_in *)addr)->sin_port; + break; + case AF_INET6: + port = ((struct sockaddr_in6 *)addr)->sin6_port; + break; + default: + plog(LLV_ERROR, LOCATION, NULL, "unknown AF: %u\n", addr->sa_family); + break; + } + + return ntohs(port); +} + +u_int16_t * +get_port_ptr (struct sockaddr *addr) +{ + u_int16_t *port_ptr; + + if (!addr) + return NULL; + + switch (addr->sa_family) { + case AF_INET: + port_ptr = &(((struct sockaddr_in *)addr)->sin_port); + break; + case AF_INET6: + port_ptr = &(((struct sockaddr_in6 *)addr)->sin6_port); + break; + default: + plog(LLV_ERROR, LOCATION, NULL, "unknown AF: %u\n", addr->sa_family); + return NULL; + break; + } + + return port_ptr; +} + +u_int16_t * +set_port (struct sockaddr *addr, u_int16_t new_port) +{ + u_int16_t *port_ptr; + + port_ptr = get_port_ptr (addr); + + if (port_ptr) + *port_ptr = htons(new_port); + + return port_ptr; +} diff --git a/ipsec-tools/src/racoon/sockmisc.h b/ipsec-tools/src/racoon/sockmisc.h new file mode 100644 index 00000000..67bfdaf5 --- /dev/null +++ b/ipsec-tools/src/racoon/sockmisc.h @@ -0,0 +1,97 @@ +/* $NetBSD: sockmisc.h,v 1.13 2011/03/14 17:18:13 tteras Exp $ */ + +/* Id: sockmisc.h,v 1.9 2005/10/05 16:55:41 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SOCKMISC_H +#define _SOCKMISC_H + +#ifndef IP_IPSEC_POLICY +#define IP_IPSEC_POLICY 16 /* XXX: from linux/in.h */ +#endif + +#ifndef IPV6_IPSEC_POLICY +#define IPV6_IPSEC_POLICY 34 /* XXX: from linux/???.h per + "Tom Lendacky" */ +#endif + +union sockaddr_any { + struct sockaddr sa; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; +}; + +struct netaddr { + union sockaddr_any sa; + unsigned long prefix; +}; + +extern const int niflags; + +#define CMPSADDR_MATCH 0 +#define CMPSADDR_WILDPORT_MATCH 1 +#define CMPSADDR_WOP_MATCH 2 +#define CMPSADDR_MISMATCH 3 + +extern int cmpsaddr __P((const struct sockaddr *, const struct sockaddr *)); + +extern struct sockaddr *getlocaladdr __P((struct sockaddr *)); + +extern int recvfromto __P((int, void *, size_t, int, + struct sockaddr *, socklen_t *, struct sockaddr *, unsigned int *)); +extern int sendfromto __P((int, const void *, size_t, + struct sockaddr *, struct sockaddr *, int)); + +extern int setsockopt_bypass __P((int, int)); + +extern struct sockaddr *newsaddr __P((int)); +extern struct sockaddr *dupsaddr __P((struct sockaddr *)); +extern char *saddr2str __P((const struct sockaddr *)); +extern char *saddrwop2str __P((const struct sockaddr *)); +extern char *saddr2str_fromto __P((const char *format, + const struct sockaddr *saddr, + const struct sockaddr *daddr)); +extern struct sockaddr *str2saddr __P((char *, char *)); +extern void mask_sockaddr __P((struct sockaddr *, const struct sockaddr *, + size_t)); + +/* struct netaddr functions */ +extern char *naddrwop2str __P((const struct netaddr *naddr)); +extern char *naddrwop2str_fromto __P((const char *format, const struct netaddr *saddr, + const struct netaddr *daddr)); +extern int naddr_score(const struct netaddr *naddr, const struct sockaddr *saddr); + +/* Some useful functions for sockaddr port manipulations. */ +extern u_int16_t extract_port __P((const struct sockaddr *addr)); +extern u_int16_t *set_port __P((struct sockaddr *addr, u_int16_t new_port)); +extern u_int16_t *get_port_ptr __P((struct sockaddr *addr)); + +#endif /* _SOCKMISC_H */ diff --git a/ipsec-tools/src/racoon/stats.pl b/ipsec-tools/src/racoon/stats.pl new file mode 100644 index 00000000..f509512e --- /dev/null +++ b/ipsec-tools/src/racoon/stats.pl @@ -0,0 +1,15 @@ +#!/usr/bin/perl +# usage: +# % cat /var/log/racoon-stats.log | perl stats.pl + +while() { + chomp; + ($a, $a, $a, $a, $a, $b) = split(/\s+/, $_, 6); + ($a, $c) = split(/:/, $b, 2); + $r{$a} += $c; + $t{$a}++; +} + +foreach (sort keys %t) { + printf "%s: total=%d avg=%8.6f\n", $_, $t{$_}, $r{$_}/$t{$_}; +} diff --git a/ipsec-tools/src/racoon/str2val.c b/ipsec-tools/src/racoon/str2val.c new file mode 100644 index 00000000..62d38a66 --- /dev/null +++ b/ipsec-tools/src/racoon/str2val.c @@ -0,0 +1,126 @@ +/* $NetBSD: str2val.c,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* $KAME: str2val.c,v 1.11 2001/08/16 14:37:29 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include + +#include "str2val.h" +#include "gcmalloc.h" + +/* + * exchange a value to a hex string. + * must free buffer allocated later. + */ +caddr_t +val2str(buf, mlen) + const char *buf; + size_t mlen; +{ + caddr_t new; + size_t len = (mlen * 2) + mlen / 8 + 10; + size_t i, j; + + if ((new = racoon_malloc(len)) == 0) return(0); + + for (i = 0, j = 0; i < mlen; i++) { + snprintf(&new[j], len - j, "%02x", (u_char)buf[i]); + j += 2; + if (i % 8 == 7) { + new[j++] = ' '; + new[j] = '\0'; + } + } + new[j] = '\0'; + + return(new); +} + +/* + * exchange a string based "base" to a value. + */ +char * +str2val(str, base, len) + const char *str; + int base; + size_t *len; +{ + int f; + size_t i; + char *dst; + char *rp; + const char *p; + char b[3]; + + i = 0; + for (p = str; *p != '\0'; p++) { + if (isxdigit((int)*p)) + i++; + else if (isspace((int)*p)) + ; + else + return NULL; + } + if (i == 0 || (i % 2) != 0) + return NULL; + i /= 2; + + if ((dst = racoon_malloc(i)) == NULL) + return NULL; + + i = 0; + f = 0; + for (rp = dst, p = str; *p != '\0'; p++) { + if (isxdigit((int)*p)) { + if (!f) { + b[0] = *p; + f = 1; + } else { + b[1] = *p; + b[2] = '\0'; + *rp++ = (char)strtol(b, NULL, base); + i++; + f = 0; + } + } + } + + *len = i; + + return(dst); +} diff --git a/ipsec-tools/src/racoon/str2val.h b/ipsec-tools/src/racoon/str2val.h new file mode 100644 index 00000000..4a7cec1d --- /dev/null +++ b/ipsec-tools/src/racoon/str2val.h @@ -0,0 +1,40 @@ +/* $NetBSD: str2val.h,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: str2val.h,v 1.3 2004/06/11 16:00:17 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _STR2VAL_H +#define _STR2VAL_H + +extern caddr_t val2str __P((const char *, size_t)); +extern char *str2val __P((const char *, int, size_t *)); + +#endif /* _STR2VAL_H */ diff --git a/ipsec-tools/src/racoon/strnames.c b/ipsec-tools/src/racoon/strnames.c new file mode 100644 index 00000000..4906b337 --- /dev/null +++ b/ipsec-tools/src/racoon/strnames.c @@ -0,0 +1,1036 @@ +/* $NetBSD: strnames.c,v 1.9 2008/07/14 05:40:13 tteras Exp $ */ + +/* $KAME: strnames.c,v 1.25 2003/11/13 10:53:26 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include PATH_IPSEC_H +#include + +#include +#include +#ifdef ENABLE_HYBRID +#include +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" + +#include "isakmp_var.h" +#include "isakmp.h" +#ifdef ENABLE_HYBRID +# include "isakmp_xauth.h" +# include "isakmp_unity.h" +# include "isakmp_cfg.h" +#endif +#include "ipsec_doi.h" +#include "oakley.h" +#include "handler.h" +#include "pfkey.h" +#include "strnames.h" +#include "algorithm.h" + +struct ksmap { + int key; + char *str; + char *(*f) __P((int)); +}; + +char * +num2str(n) + int n; +{ + static char buf[20]; + + snprintf(buf, sizeof(buf), "%d", n); + + return buf; +} + +/* isakmp.h */ +char * +s_isakmp_state(t, d, s) + int t, d, s; +{ + switch (t) { + case ISAKMP_ETYPE_AGG: + switch (d) { + case INITIATOR: + switch (s) { + case PHASE1ST_MSG1SENT: + return "agg I msg1"; + case PHASE1ST_ESTABLISHED: + return "agg I msg2"; + default: + break; + } + case RESPONDER: + switch (s) { + case PHASE1ST_MSG1SENT: + return "agg R msg1"; + default: + break; + } + } + break; + case ISAKMP_ETYPE_BASE: + switch (d) { + case INITIATOR: + switch (s) { + case PHASE1ST_MSG1SENT: + return "base I msg1"; + case PHASE1ST_MSG2SENT: + return "base I msg2"; + default: + break; + } + case RESPONDER: + switch (s) { + case PHASE1ST_MSG1SENT: + return "base R msg1"; + case PHASE1ST_ESTABLISHED: + return "base R msg2"; + default: + break; + } + } + break; + case ISAKMP_ETYPE_IDENT: + switch (d) { + case INITIATOR: + switch (s) { + case PHASE1ST_MSG1SENT: + return "ident I msg1"; + case PHASE1ST_MSG2SENT: + return "ident I msg2"; + case PHASE1ST_MSG3SENT: + return "ident I msg3"; + default: + break; + } + case RESPONDER: + switch (s) { + case PHASE1ST_MSG1SENT: + return "ident R msg1"; + case PHASE1ST_MSG2SENT: + return "ident R msg2"; + case PHASE1ST_ESTABLISHED: + return "ident R msg3"; + default: + break; + } + } + break; + case ISAKMP_ETYPE_QUICK: + switch (d) { + case INITIATOR: + switch (s) { + case PHASE2ST_MSG1SENT: + return "quick I msg1"; + case PHASE2ST_ADDSA: + return "quick I msg2"; + default: + break; + } + case RESPONDER: + switch (s) { + case PHASE2ST_MSG1SENT: + return "quick R msg1"; + case PHASE2ST_COMMIT: + return "quick R msg2"; + default: + break; + } + } + break; + default: + case ISAKMP_ETYPE_NONE: + case ISAKMP_ETYPE_AUTH: + case ISAKMP_ETYPE_INFO: + case ISAKMP_ETYPE_NEWGRP: + case ISAKMP_ETYPE_ACKINFO: + break; + } + /*NOTREACHED*/ + + return "???"; +} + +static struct ksmap name_isakmp_certtype[] = { +{ ISAKMP_CERT_NONE, "NONE", NULL }, +{ ISAKMP_CERT_PKCS7, "PKCS #7 wrapped X.509 certificate", NULL }, +{ ISAKMP_CERT_PGP, "PGP Certificate", NULL }, +{ ISAKMP_CERT_DNS, "DNS Signed Key", NULL }, +{ ISAKMP_CERT_X509SIGN, "X.509 Certificate Signature", NULL }, +{ ISAKMP_CERT_X509KE, "X.509 Certificate Key Exchange", NULL }, +{ ISAKMP_CERT_KERBEROS, "Kerberos Tokens", NULL }, +{ ISAKMP_CERT_CRL, "Certificate Revocation List (CRL)", NULL }, +{ ISAKMP_CERT_ARL, "Authority Revocation List (ARL)", NULL }, +{ ISAKMP_CERT_SPKI, "SPKI Certificate", NULL }, +{ ISAKMP_CERT_X509ATTR, "X.509 Certificate Attribute", NULL }, +}; + +char * +s_isakmp_certtype(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_isakmp_certtype); i++) + if (name_isakmp_certtype[i].key == k) + return name_isakmp_certtype[i].str; + return num2str(k); +} + +static struct ksmap name_isakmp_etype[] = { +{ ISAKMP_ETYPE_NONE, "None", NULL }, +{ ISAKMP_ETYPE_BASE, "Base", NULL }, +{ ISAKMP_ETYPE_IDENT, "Identity Protection", NULL }, +{ ISAKMP_ETYPE_AUTH, "Authentication Only", NULL }, +{ ISAKMP_ETYPE_AGG, "Aggressive", NULL }, +{ ISAKMP_ETYPE_INFO, "Informational", NULL }, +{ ISAKMP_ETYPE_CFG, "Mode config", NULL }, +{ ISAKMP_ETYPE_QUICK, "Quick", NULL }, +{ ISAKMP_ETYPE_NEWGRP, "New Group", NULL }, +{ ISAKMP_ETYPE_ACKINFO, "Acknowledged Informational", NULL }, +}; + +char * +s_isakmp_etype(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_isakmp_etype); i++) + if (name_isakmp_etype[i].key == k) + return name_isakmp_etype[i].str; + return num2str(k); +} + +static struct ksmap name_isakmp_notify_msg[] = { +{ ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, "INVALID-PAYLOAD-TYPE", NULL }, +{ ISAKMP_NTYPE_DOI_NOT_SUPPORTED, "DOI-NOT-SUPPORTED", NULL }, +{ ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED, "SITUATION-NOT-SUPPORTED", NULL }, +{ ISAKMP_NTYPE_INVALID_COOKIE, "INVALID-COOKIE", NULL }, +{ ISAKMP_NTYPE_INVALID_MAJOR_VERSION, "INVALID-MAJOR-VERSION", NULL }, +{ ISAKMP_NTYPE_INVALID_MINOR_VERSION, "INVALID-MINOR-VERSION", NULL }, +{ ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, "INVALID-EXCHANGE-TYPE", NULL }, +{ ISAKMP_NTYPE_INVALID_FLAGS, "INVALID-FLAGS", NULL }, +{ ISAKMP_NTYPE_INVALID_MESSAGE_ID, "INVALID-MESSAGE-ID", NULL }, +{ ISAKMP_NTYPE_INVALID_PROTOCOL_ID, "INVALID-PROTOCOL-ID", NULL }, +{ ISAKMP_NTYPE_INVALID_SPI, "INVALID-SPI", NULL }, +{ ISAKMP_NTYPE_INVALID_TRANSFORM_ID, "INVALID-TRANSFORM-ID", NULL }, +{ ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED, "ATTRIBUTES-NOT-SUPPORTED", NULL }, +{ ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN, "NO-PROPOSAL-CHOSEN", NULL }, +{ ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX, "BAD-PROPOSAL-SYNTAX", NULL }, +{ ISAKMP_NTYPE_PAYLOAD_MALFORMED, "PAYLOAD-MALFORMED", NULL }, +{ ISAKMP_NTYPE_INVALID_KEY_INFORMATION, "INVALID-KEY-INFORMATION", NULL }, +{ ISAKMP_NTYPE_INVALID_ID_INFORMATION, "INVALID-ID-INFORMATION", NULL }, +{ ISAKMP_NTYPE_INVALID_CERT_ENCODING, "INVALID-CERT-ENCODING", NULL }, +{ ISAKMP_NTYPE_INVALID_CERTIFICATE, "INVALID-CERTIFICATE", NULL }, +{ ISAKMP_NTYPE_BAD_CERT_REQUEST_SYNTAX, "BAD-CERT-REQUEST-SYNTAX", NULL }, +{ ISAKMP_NTYPE_INVALID_CERT_AUTHORITY, "INVALID-CERT-AUTHORITY", NULL }, +{ ISAKMP_NTYPE_INVALID_HASH_INFORMATION, "INVALID-HASH-INFORMATION", NULL }, +{ ISAKMP_NTYPE_AUTHENTICATION_FAILED, "AUTHENTICATION-FAILED", NULL }, +{ ISAKMP_NTYPE_INVALID_SIGNATURE, "INVALID-SIGNATURE", NULL }, +{ ISAKMP_NTYPE_ADDRESS_NOTIFICATION, "ADDRESS-NOTIFICATION", NULL }, +{ ISAKMP_NTYPE_NOTIFY_SA_LIFETIME, "NOTIFY-SA-LIFETIME", NULL }, +{ ISAKMP_NTYPE_CERTIFICATE_UNAVAILABLE, "CERTIFICATE-UNAVAILABLE", NULL }, +{ ISAKMP_NTYPE_UNSUPPORTED_EXCHANGE_TYPE, "UNSUPPORTED-EXCHANGE-TYPE", NULL }, +{ ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS, "UNEQUAL-PAYLOAD-LENGTHS", NULL }, +{ ISAKMP_NTYPE_CONNECTED, "CONNECTED", NULL }, +{ ISAKMP_NTYPE_RESPONDER_LIFETIME, "RESPONDER-LIFETIME", NULL }, +{ ISAKMP_NTYPE_REPLAY_STATUS, "REPLAY-STATUS", NULL }, +{ ISAKMP_NTYPE_INITIAL_CONTACT, "INITIAL-CONTACT", NULL }, +{ ISAKMP_NTYPE_R_U_THERE, "R-U-THERE", NULL }, +{ ISAKMP_NTYPE_R_U_THERE_ACK, "R-U-THERE-ACK", NULL }, +#ifdef ENABLE_HYBRID +{ ISAKMP_NTYPE_UNITY_HEARTBEAT, "HEARTBEAT (Unity)", NULL }, +#endif +{ ISAKMP_LOG_RETRY_LIMIT_REACHED, "RETRY-LIMIT-REACHED", NULL }, +}; + +char * +s_isakmp_notify_msg(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_isakmp_notify_msg); i++) + if (name_isakmp_notify_msg[i].key == k) + return name_isakmp_notify_msg[i].str; + + return num2str(k); +} + +static struct ksmap name_isakmp_nptype[] = { +{ ISAKMP_NPTYPE_NONE, "none", NULL }, +{ ISAKMP_NPTYPE_SA, "sa", NULL }, +{ ISAKMP_NPTYPE_P, "prop", NULL }, +{ ISAKMP_NPTYPE_T, "trns", NULL }, +{ ISAKMP_NPTYPE_KE, "ke", NULL }, +{ ISAKMP_NPTYPE_ID, "id", NULL }, +{ ISAKMP_NPTYPE_CERT, "cert", NULL }, +{ ISAKMP_NPTYPE_CR, "cr", NULL }, +{ ISAKMP_NPTYPE_HASH, "hash", NULL }, +{ ISAKMP_NPTYPE_SIG, "sig", NULL }, +{ ISAKMP_NPTYPE_NONCE, "nonce", NULL }, +{ ISAKMP_NPTYPE_N, "notify", NULL }, +{ ISAKMP_NPTYPE_D, "delete", NULL }, +{ ISAKMP_NPTYPE_VID, "vid", NULL }, +{ ISAKMP_NPTYPE_ATTR, "attr", NULL }, +{ ISAKMP_NPTYPE_GSS, "gss id", NULL }, +{ ISAKMP_NPTYPE_NATD_RFC, "nat-d", NULL }, +{ ISAKMP_NPTYPE_NATOA_RFC, "nat-oa", NULL }, +{ ISAKMP_NPTYPE_NATD_DRAFT, "nat-d", NULL }, +{ ISAKMP_NPTYPE_NATOA_DRAFT, "nat-oa", NULL }, +{ ISAKMP_NPTYPE_FRAG, "ike frag", NULL }, +}; + +char * +s_isakmp_nptype(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_isakmp_nptype); i++) + if (name_isakmp_nptype[i].key == k) + return name_isakmp_nptype[i].str; + return num2str(k); +} + +#ifdef ENABLE_HYBRID +/* isakmp_cfg.h / isakmp_unity.h / isakmp_xauth.h */ +static struct ksmap name_isakmp_cfg_type[] = { +{ INTERNAL_IP4_ADDRESS, "INTERNAL_IP4_ADDRESS", NULL }, +{ INTERNAL_IP4_NETMASK, "INTERNAL_IP4_NETMASK", NULL }, +{ INTERNAL_IP4_DNS, "INTERNAL_IP4_DNS", NULL }, +{ INTERNAL_IP4_NBNS, "INTERNAL_IP4_NBNS", NULL }, +{ INTERNAL_ADDRESS_EXPIRY, "INTERNAL_ADDRESS_EXPIRY", NULL }, +{ INTERNAL_IP4_DHCP, "INTERNAL_IP4_DHCP", NULL }, +{ APPLICATION_VERSION, "APPLICATION_VERSION", NULL }, +{ INTERNAL_IP6_ADDRESS, "INTERNAL_IP6_ADDRESS", NULL }, +{ INTERNAL_IP6_NETMASK, "INTERNAL_IP6_NETMASK", NULL }, +{ INTERNAL_IP6_DNS, "INTERNAL_IP6_DNS", NULL }, +{ INTERNAL_IP6_NBNS, "INTERNAL_IP6_NBNS", NULL }, +{ INTERNAL_IP6_DHCP, "INTERNAL_IP6_DHCP", NULL }, +{ INTERNAL_IP4_SUBNET, "INTERNAL_IP4_SUBNET", NULL }, +{ SUPPORTED_ATTRIBUTES, "SUPPORTED_ATTRIBUTES", NULL }, +{ INTERNAL_IP6_SUBNET, "INTERNAL_IP6_SUBNET", NULL }, +{ XAUTH_TYPE, "XAUTH_TYPE", NULL }, +{ XAUTH_USER_NAME, "XAUTH_USER_NAME", NULL }, +{ XAUTH_USER_PASSWORD, "XAUTH_USER_PASSWORD", NULL }, +{ XAUTH_PASSCODE, "XAUTH_PASSCODE", NULL }, +{ XAUTH_MESSAGE, "XAUTH_MESSAGE", NULL }, +{ XAUTH_CHALLENGE, "XAUTH_CHALLENGE", NULL }, +{ XAUTH_DOMAIN, "XAUTH_DOMAIN", NULL }, +{ XAUTH_STATUS, "XAUTH_STATUS", NULL }, +{ XAUTH_NEXT_PIN, "XAUTH_NEXT_PIN", NULL }, +{ XAUTH_ANSWER, "XAUTH_ANSWER", NULL }, +{ UNITY_BANNER, "UNITY_BANNER", NULL }, +{ UNITY_SAVE_PASSWD, "UNITY_SAVE_PASSWD", NULL }, +{ UNITY_DEF_DOMAIN, "UNITY_DEF_DOMAIN", NULL }, +{ UNITY_SPLITDNS_NAME, "UNITY_SPLITDNS_NAME", NULL }, +{ UNITY_SPLIT_INCLUDE, "UNITY_SPLIT_INCLUDE", NULL }, +{ UNITY_NATT_PORT, "UNITY_NATT_PORT", NULL }, +{ UNITY_LOCAL_LAN, "UNITY_LOCAL_LAN", NULL }, +{ UNITY_PFS, "UNITY_PFS", NULL }, +{ UNITY_FW_TYPE, "UNITY_FW_TYPE", NULL }, +{ UNITY_BACKUP_SERVERS, "UNITY_BACKUP_SERVERS", NULL }, +{ UNITY_DDNS_HOSTNAME, "UNITY_DDNS_HOSTNAME", NULL }, +}; + +char * +s_isakmp_cfg_type(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_isakmp_cfg_type); i++) + if (name_isakmp_cfg_type[i].key == k) + return name_isakmp_cfg_type[i].str; + return num2str(k); +} + +/* isakmp_cfg.h / isakmp_unity.h / isakmp_xauth.h */ +static struct ksmap name_isakmp_cfg_ptype[] = { +{ ISAKMP_CFG_ACK, "mode config ACK", NULL }, +{ ISAKMP_CFG_SET, "mode config SET", NULL }, +{ ISAKMP_CFG_REQUEST, "mode config REQUEST", NULL }, +{ ISAKMP_CFG_REPLY, "mode config REPLY", NULL }, +}; + +char * +s_isakmp_cfg_ptype(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_isakmp_cfg_ptype); i++) + if (name_isakmp_cfg_ptype[i].key == k) + return name_isakmp_cfg_ptype[i].str; + return num2str(k); +} + +#endif + +/* ipsec_doi.h */ +static struct ksmap name_ipsecdoi_proto[] = { +{ IPSECDOI_PROTO_ISAKMP, "ISAKMP", s_ipsecdoi_trns_isakmp }, +{ IPSECDOI_PROTO_IPSEC_AH, "AH", s_ipsecdoi_trns_ah }, +{ IPSECDOI_PROTO_IPSEC_ESP, "ESP", s_ipsecdoi_trns_esp }, +{ IPSECDOI_PROTO_IPCOMP, "IPCOMP", s_ipsecdoi_trns_ipcomp }, +}; + +char * +s_ipsecdoi_proto(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_ipsecdoi_proto); i++) + if (name_ipsecdoi_proto[i].key == k) + return name_ipsecdoi_proto[i].str; + return num2str(k); +} + +static struct ksmap name_ipsecdoi_trns_isakmp[] = { +{ IPSECDOI_KEY_IKE, "IKE", NULL }, +}; + +char * +s_ipsecdoi_trns_isakmp(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_ipsecdoi_trns_isakmp); i++) + if (name_ipsecdoi_trns_isakmp[i].key == k) + return name_ipsecdoi_trns_isakmp[i].str; + return num2str(k); +} + +static struct ksmap name_ipsecdoi_trns_ah[] = { +{ IPSECDOI_AH_MD5, "MD5", NULL }, +{ IPSECDOI_AH_SHA, "SHA", NULL }, +{ IPSECDOI_AH_DES, "DES", NULL }, +{ IPSECDOI_AH_SHA256, "SHA256", NULL }, +{ IPSECDOI_AH_SHA384, "SHA384", NULL }, +{ IPSECDOI_AH_SHA512, "SHA512", NULL }, +}; + +char * +s_ipsecdoi_trns_ah(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_ipsecdoi_trns_ah); i++) + if (name_ipsecdoi_trns_ah[i].key == k) + return name_ipsecdoi_trns_ah[i].str; + return num2str(k); +} + +static struct ksmap name_ipsecdoi_trns_esp[] = { +{ IPSECDOI_ESP_DES_IV64, "DES_IV64", NULL }, +{ IPSECDOI_ESP_DES, "DES", NULL }, +{ IPSECDOI_ESP_3DES, "3DES", NULL }, +{ IPSECDOI_ESP_RC5, "RC5", NULL }, +{ IPSECDOI_ESP_IDEA, "IDEA", NULL }, +{ IPSECDOI_ESP_CAST, "CAST", NULL }, +{ IPSECDOI_ESP_BLOWFISH, "BLOWFISH", NULL }, +{ IPSECDOI_ESP_3IDEA, "3IDEA", NULL }, +{ IPSECDOI_ESP_DES_IV32, "DES_IV32", NULL }, +{ IPSECDOI_ESP_RC4, "RC4", NULL }, +{ IPSECDOI_ESP_NULL, "NULL", NULL }, +{ IPSECDOI_ESP_AES, "AES", NULL }, +{ IPSECDOI_ESP_TWOFISH, "TWOFISH", NULL }, +{ IPSECDOI_ESP_CAMELLIA, "CAMELLIA", NULL }, +}; + +char * +s_ipsecdoi_trns_esp(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_ipsecdoi_trns_esp); i++) + if (name_ipsecdoi_trns_esp[i].key == k) + return name_ipsecdoi_trns_esp[i].str; + return num2str(k); +} + +static struct ksmap name_ipsecdoi_trns_ipcomp[] = { +{ IPSECDOI_IPCOMP_OUI, "OUI", NULL}, +{ IPSECDOI_IPCOMP_DEFLATE, "DEFLATE", NULL}, +{ IPSECDOI_IPCOMP_LZS, "LZS", NULL}, +}; + +char * +s_ipsecdoi_trns_ipcomp(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_ipsecdoi_trns_ipcomp); i++) + if (name_ipsecdoi_trns_ipcomp[i].key == k) + return name_ipsecdoi_trns_ipcomp[i].str; + return num2str(k); +} + +char * +s_ipsecdoi_trns(proto, trns) + int proto, trns; +{ + int i; + for (i = 0; i < ARRAYLEN(name_ipsecdoi_proto); i++) + if (name_ipsecdoi_proto[i].key == proto + && name_ipsecdoi_proto[i].f) + return (name_ipsecdoi_proto[i].f)(trns); + return num2str(trns); +} + +static struct ksmap name_attr_ipsec[] = { +{ IPSECDOI_ATTR_SA_LD_TYPE, "SA Life Type", s_ipsecdoi_ltype }, +{ IPSECDOI_ATTR_SA_LD, "SA Life Duration", NULL }, +{ IPSECDOI_ATTR_GRP_DESC, "Group Description", NULL }, +{ IPSECDOI_ATTR_ENC_MODE, "Encryption Mode", s_ipsecdoi_encmode }, +{ IPSECDOI_ATTR_AUTH, "Authentication Algorithm", s_ipsecdoi_auth }, +{ IPSECDOI_ATTR_KEY_LENGTH, "Key Length", NULL }, +{ IPSECDOI_ATTR_KEY_ROUNDS, "Key Rounds", NULL }, +{ IPSECDOI_ATTR_COMP_DICT_SIZE, "Compression Dictionary Size", NULL }, +{ IPSECDOI_ATTR_COMP_PRIVALG, "Compression Private Algorithm", NULL }, +}; + +char * +s_ipsecdoi_attr(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_attr_ipsec); i++) + if (name_attr_ipsec[i].key == k) + return name_attr_ipsec[i].str; + return num2str(k); +} + +static struct ksmap name_attr_ipsec_ltype[] = { +{ IPSECDOI_ATTR_SA_LD_TYPE_SEC, "seconds", NULL }, +{ IPSECDOI_ATTR_SA_LD_TYPE_KB, "kilobytes", NULL }, +}; + +char * +s_ipsecdoi_ltype(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_attr_ipsec_ltype); i++) + if (name_attr_ipsec_ltype[i].key == k) + return name_attr_ipsec_ltype[i].str; + return num2str(k); +} + +static struct ksmap name_attr_ipsec_encmode[] = { +{ IPSECDOI_ATTR_ENC_MODE_ANY, "Any", NULL }, +{ IPSECDOI_ATTR_ENC_MODE_TUNNEL, "Tunnel", NULL }, +{ IPSECDOI_ATTR_ENC_MODE_TRNS, "Transport", NULL }, +{ IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC, "UDP-Tunnel", NULL }, +{ IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC, "UDP-Transport", NULL }, +{ IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT, "UDP-Tunnel", NULL }, +{ IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT, "UDP-Transport", NULL }, +}; + +char * +s_ipsecdoi_encmode(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_attr_ipsec_encmode); i++) + if (name_attr_ipsec_encmode[i].key == k) + return name_attr_ipsec_encmode[i].str; + return num2str(k); +} + +static struct ksmap name_attr_ipsec_auth[] = { +{ IPSECDOI_ATTR_AUTH_HMAC_MD5, "hmac-md5", NULL }, +{ IPSECDOI_ATTR_AUTH_HMAC_SHA1, "hmac-sha", NULL }, +{ IPSECDOI_ATTR_AUTH_HMAC_SHA2_256, "hmac-sha256", NULL }, +{ IPSECDOI_ATTR_AUTH_HMAC_SHA2_384, "hmac-sha384", NULL }, +{ IPSECDOI_ATTR_AUTH_HMAC_SHA2_512, "hmac-sha512", NULL }, +{ IPSECDOI_ATTR_AUTH_DES_MAC, "des-mac", NULL }, +{ IPSECDOI_ATTR_AUTH_KPDK, "kpdk", NULL }, +}; + +char * +s_ipsecdoi_auth(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_attr_ipsec_auth); i++) + if (name_attr_ipsec_auth[i].key == k) + return name_attr_ipsec_auth[i].str; + return num2str(k); +} + +char * +s_ipsecdoi_attr_v(type, val) + int type, val; +{ + int i; + for (i = 0; i < ARRAYLEN(name_attr_ipsec); i++) + if (name_attr_ipsec[i].key == type + && name_attr_ipsec[i].f) + return (name_attr_ipsec[i].f)(val); + return num2str(val); +} + +static struct ksmap name_ipsecdoi_ident[] = { +{ IPSECDOI_ID_IPV4_ADDR, "IPv4_address", NULL }, +{ IPSECDOI_ID_FQDN, "FQDN", NULL }, +{ IPSECDOI_ID_USER_FQDN, "User_FQDN", NULL }, +{ IPSECDOI_ID_IPV4_ADDR_SUBNET, "IPv4_subnet", NULL }, +{ IPSECDOI_ID_IPV6_ADDR, "IPv6_address", NULL }, +{ IPSECDOI_ID_IPV6_ADDR_SUBNET, "IPv6_subnet", NULL }, +{ IPSECDOI_ID_IPV4_ADDR_RANGE, "IPv4_address_range", NULL }, +{ IPSECDOI_ID_IPV6_ADDR_RANGE, "IPv6_address_range", NULL }, +{ IPSECDOI_ID_DER_ASN1_DN, "DER_ASN1_DN", NULL }, +{ IPSECDOI_ID_DER_ASN1_GN, "DER_ASN1_GN", NULL }, +{ IPSECDOI_ID_KEY_ID, "KEY_ID", NULL }, +}; + +char * +s_ipsecdoi_ident(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_ipsecdoi_ident); i++) + if (name_ipsecdoi_ident[i].key == k) + return name_ipsecdoi_ident[i].str; + return num2str(k); +} + +/* oakley.h */ +static struct ksmap name_oakley_attr[] = { +{ OAKLEY_ATTR_ENC_ALG, "Encryption Algorithm", s_attr_isakmp_enc }, +{ OAKLEY_ATTR_HASH_ALG, "Hash Algorithm", s_attr_isakmp_hash }, +{ OAKLEY_ATTR_AUTH_METHOD, "Authentication Method", s_oakley_attr_method }, +{ OAKLEY_ATTR_GRP_DESC, "Group Description", s_attr_isakmp_desc }, +{ OAKLEY_ATTR_GRP_TYPE, "Group Type", s_attr_isakmp_group }, +{ OAKLEY_ATTR_GRP_PI, "Group Prime/Irreducible Polynomial", NULL }, +{ OAKLEY_ATTR_GRP_GEN_ONE, "Group Generator One", NULL }, +{ OAKLEY_ATTR_GRP_GEN_TWO, "Group Generator Two", NULL }, +{ OAKLEY_ATTR_GRP_CURVE_A, "Group Curve A", NULL }, +{ OAKLEY_ATTR_GRP_CURVE_B, "Group Curve B", NULL }, +{ OAKLEY_ATTR_SA_LD_TYPE, "Life Type", s_attr_isakmp_ltype }, +{ OAKLEY_ATTR_SA_LD, "Life Duration", NULL }, +{ OAKLEY_ATTR_PRF, "PRF", NULL }, +{ OAKLEY_ATTR_KEY_LEN, "Key Length", NULL }, +{ OAKLEY_ATTR_FIELD_SIZE, "Field Size", NULL }, +{ OAKLEY_ATTR_GRP_ORDER, "Group Order", NULL }, +{ OAKLEY_ATTR_BLOCK_SIZE, "Block Size", NULL }, +{ OAKLEY_ATTR_GSS_ID, "GSS-API endpoint name",NULL }, +}; + +char * +s_oakley_attr(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_oakley_attr); i++) + if (name_oakley_attr[i].key == k) + return name_oakley_attr[i].str; + return num2str(k); +} + +static struct ksmap name_attr_isakmp_enc[] = { +{ OAKLEY_ATTR_ENC_ALG_DES, "DES-CBC", NULL }, +{ OAKLEY_ATTR_ENC_ALG_IDEA, "IDEA-CBC", NULL }, +{ OAKLEY_ATTR_ENC_ALG_BLOWFISH, "Blowfish-CBC", NULL }, +{ OAKLEY_ATTR_ENC_ALG_RC5, "RC5-R16-B64-CBC", NULL }, +{ OAKLEY_ATTR_ENC_ALG_3DES, "3DES-CBC", NULL }, +{ OAKLEY_ATTR_ENC_ALG_CAST, "CAST-CBC", NULL }, +{ OAKLEY_ATTR_ENC_ALG_AES, "AES-CBC", NULL }, +}; + +char * +s_attr_isakmp_enc(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_attr_isakmp_enc); i++) + if (name_attr_isakmp_enc[i].key == k) + return name_attr_isakmp_enc[i].str; + return num2str(k); +} + +static struct ksmap name_attr_isakmp_hash[] = { +{ OAKLEY_ATTR_HASH_ALG_MD5, "MD5", NULL }, +{ OAKLEY_ATTR_HASH_ALG_SHA, "SHA", NULL }, +{ OAKLEY_ATTR_HASH_ALG_TIGER, "Tiger", NULL }, +{ OAKLEY_ATTR_HASH_ALG_SHA2_256,"SHA256", NULL }, +{ OAKLEY_ATTR_HASH_ALG_SHA2_384,"SHA384", NULL }, +{ OAKLEY_ATTR_HASH_ALG_SHA2_512,"SHA512", NULL }, +}; + +char * +s_attr_isakmp_hash(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_attr_isakmp_hash); i++) + if (name_attr_isakmp_hash[i].key == k) + return name_attr_isakmp_hash[i].str; + return num2str(k); +} + +static struct ksmap name_attr_isakmp_method[] = { +{ OAKLEY_ATTR_AUTH_METHOD_PSKEY, "pre-shared key", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_DSSSIG, "DSS signatures", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_RSASIG, "RSA signatures", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_RSAENC, "Encryption with RSA", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_RSAREV, "Revised encryption with RSA", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_EGENC, "Encryption with El-Gamal", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_EGREV, "Revised encryption with El-Gamal", NULL }, +#ifdef HAVE_GSSAPI +{ OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, "GSS-API on Kerberos 5", NULL }, +#endif +#ifdef ENABLE_HYBRID +{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, "Hybrid DSS server", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, "Hybrid RSA server", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I, "Hybrid DSS client", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I, "Hybrid RSA client", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I, "XAuth pskey client", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R, "XAuth pskey server", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I, "XAuth RSASIG client", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R, "XAuth RSASIG server", NULL }, +#endif +}; + +char * +s_oakley_attr_method(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_attr_isakmp_method); i++) + if (name_attr_isakmp_method[i].key == k) + return name_attr_isakmp_method[i].str; + return num2str(k); +} + +static struct ksmap name_attr_isakmp_desc[] = { +{ OAKLEY_ATTR_GRP_DESC_MODP768, "768-bit MODP group", NULL }, +{ OAKLEY_ATTR_GRP_DESC_MODP1024, "1024-bit MODP group", NULL }, +{ OAKLEY_ATTR_GRP_DESC_EC2N155, "EC2N group on GP[2^155]", NULL }, +{ OAKLEY_ATTR_GRP_DESC_EC2N185, "EC2N group on GP[2^185]", NULL }, +{ OAKLEY_ATTR_GRP_DESC_MODP1536, "1536-bit MODP group", NULL }, +{ OAKLEY_ATTR_GRP_DESC_MODP2048, "2048-bit MODP group", NULL }, +{ OAKLEY_ATTR_GRP_DESC_MODP3072, "3072-bit MODP group", NULL }, +{ OAKLEY_ATTR_GRP_DESC_MODP4096, "4096-bit MODP group", NULL }, +{ OAKLEY_ATTR_GRP_DESC_MODP6144, "6144-bit MODP group", NULL }, +{ OAKLEY_ATTR_GRP_DESC_MODP8192, "8192-bit MODP group", NULL }, +}; + +char * +s_attr_isakmp_desc(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_attr_isakmp_desc); i++) + if (name_attr_isakmp_desc[i].key == k) + return name_attr_isakmp_desc[i].str; + return num2str(k); +} + +static struct ksmap name_attr_isakmp_group[] = { +{ OAKLEY_ATTR_GRP_TYPE_MODP, "MODP", NULL }, +{ OAKLEY_ATTR_GRP_TYPE_ECP, "ECP", NULL }, +{ OAKLEY_ATTR_GRP_TYPE_EC2N, "EC2N", NULL }, +}; + +char * +s_attr_isakmp_group(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_attr_isakmp_group); i++) + if (name_attr_isakmp_group[i].key == k) + return name_attr_isakmp_group[i].str; + return num2str(k); +} + +static struct ksmap name_attr_isakmp_ltype[] = { +{ OAKLEY_ATTR_SA_LD_TYPE_SEC, "seconds", NULL }, +{ OAKLEY_ATTR_SA_LD_TYPE_KB, "kilobytes", NULL }, +}; + +char * +s_attr_isakmp_ltype(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_attr_isakmp_ltype); i++) + if (name_attr_isakmp_ltype[i].key == k) + return name_attr_isakmp_ltype[i].str; + return num2str(k); +} + +char * +s_oakley_attr_v(type, val) + int type, val; +{ + int i; + for (i = 0; i < ARRAYLEN(name_oakley_attr); i++) + if (name_oakley_attr[i].key == type + && name_oakley_attr[i].f) + return (name_oakley_attr[i].f)(val); + return num2str(val); +} + +/* netinet6/ipsec.h */ +static struct ksmap name_ipsec_level[] = { +{ IPSEC_LEVEL_USE, "use", NULL }, +{ IPSEC_LEVEL_REQUIRE, "require", NULL }, +{ IPSEC_LEVEL_UNIQUE, "unique", NULL }, +}; + +char * +s_ipsec_level(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_ipsec_level); i++) + if (name_ipsec_level[i].key == k) + return name_ipsec_level[i].str; + return num2str(k); +} + +static struct ksmap name_algclass[] = { +{ algclass_ipsec_enc, "ipsec enc", s_ipsecdoi_trns_esp }, +{ algclass_ipsec_auth, "ipsec auth", s_ipsecdoi_trns_ah }, +{ algclass_ipsec_comp, "ipsec comp", s_ipsecdoi_trns_ipcomp }, +{ algclass_isakmp_enc, "isakmp enc", s_attr_isakmp_enc }, +{ algclass_isakmp_hash, "isakmp hash", s_attr_isakmp_hash }, +{ algclass_isakmp_dh, "isakmp dh", s_attr_isakmp_desc }, +{ algclass_isakmp_ameth, "isakmp auth method", s_oakley_attr_method }, +}; + +char * +s_algclass(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_algclass); i++) + if (name_algclass[i].key == k) + return name_algclass[i].str; + return num2str(k); +} + +char * +s_algtype(class, n) + int class, n; +{ + int i; + for (i = 0; i < ARRAYLEN(name_algclass); i++) + if (name_algclass[i].key == class + && name_algclass[i].f) + return (name_algclass[i].f)(n); + return num2str(n); +} + +/* pfkey.h */ +static struct ksmap name_pfkey_type[] = { +{ SADB_GETSPI, "GETSPI", NULL }, +{ SADB_UPDATE, "UPDATE", NULL }, +{ SADB_ADD, "ADD", NULL }, +{ SADB_DELETE, "DELETE", NULL }, +{ SADB_GET, "GET", NULL }, +{ SADB_ACQUIRE, "ACQUIRE", NULL }, +{ SADB_REGISTER, "REGISTER", NULL }, +{ SADB_EXPIRE, "EXPIRE", NULL }, +{ SADB_FLUSH, "FLUSH", NULL }, +{ SADB_DUMP, "DUMP", NULL }, +{ SADB_X_PROMISC, "X_PROMISC", NULL }, +{ SADB_X_PCHANGE, "X_PCHANGE", NULL }, +{ SADB_X_SPDUPDATE, "X_SPDUPDATE", NULL }, +{ SADB_X_SPDADD, "X_SPDADD", NULL }, +{ SADB_X_SPDDELETE, "X_SPDDELETE", NULL }, +{ SADB_X_SPDGET, "X_SPDGET", NULL }, +{ SADB_X_SPDACQUIRE, "X_SPDACQUIRE", NULL }, +{ SADB_X_SPDDUMP, "X_SPDDUMP", NULL }, +{ SADB_X_SPDFLUSH, "X_SPDFLUSH", NULL }, +{ SADB_X_SPDSETIDX, "X_SPDSETIDX", NULL }, +{ SADB_X_SPDEXPIRE, "X_SPDEXPIRE", NULL }, +{ SADB_X_SPDDELETE2, "X_SPDDELETE2", NULL }, +#ifdef SADB_X_NAT_T_NEW_MAPPING +{ SADB_X_NAT_T_NEW_MAPPING, "X_NAT_T_NEW_MAPPING", NULL }, +#endif +#ifdef SADB_X_MIGRATE +{ SADB_X_MIGRATE, "X_MIGRATE", NULL }, +#endif +}; + +char * +s_pfkey_type(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_pfkey_type); i++) + if (name_pfkey_type[i].key == k) + return name_pfkey_type[i].str; + return num2str(k); +} + +static struct ksmap name_pfkey_satype[] = { +{ SADB_SATYPE_UNSPEC, "UNSPEC", NULL }, +{ SADB_SATYPE_AH, "AH", NULL }, +{ SADB_SATYPE_ESP, "ESP", NULL }, +{ SADB_SATYPE_RSVP, "RSVP", NULL }, +{ SADB_SATYPE_OSPFV2, "OSPFV2", NULL }, +{ SADB_SATYPE_RIPV2, "RIPV2", NULL }, +{ SADB_SATYPE_MIP, "MIP", NULL }, +{ SADB_X_SATYPE_IPCOMP, "IPCOMP", NULL }, +}; + +char * +s_pfkey_satype(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_pfkey_satype); i++) + if (name_pfkey_satype[i].key == k) + return name_pfkey_satype[i].str; + return num2str(k); +} + +static struct ksmap name_direction[] = { +{ IPSEC_DIR_INBOUND, "in", NULL }, +{ IPSEC_DIR_OUTBOUND, "out", NULL }, +#ifdef HAVE_POLICY_FWD +{ IPSEC_DIR_FWD, "fwd", NULL }, +#endif +}; + +char * +s_direction(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_direction); i++) + if (name_direction[i].key == k) + return name_direction[i].str; + return num2str(k); +} + +char * +s_proto(k) + int k; +{ + switch (k) { + case IPPROTO_ICMP: + return "icmp"; + case IPPROTO_TCP: + return "tcp"; + case IPPROTO_UDP: + return "udp"; + case IPPROTO_ICMPV6: + return "icmpv6"; + case IPSEC_ULPROTO_ANY: + return "any"; + } + + return num2str(k); +} + +char * +s_doi(int k) +{ + switch (k) { + case IPSEC_DOI: + return "ipsec_doi"; + default: + return num2str(k); + } +} + +char * +s_etype (int k) +{ + switch (k) { + case ISAKMP_ETYPE_NONE: + return "_none"; + case ISAKMP_ETYPE_BASE: + return "base"; + case ISAKMP_ETYPE_IDENT: + return "main"; + case ISAKMP_ETYPE_AUTH: + return "_auth"; + case ISAKMP_ETYPE_AGG: + return "aggressive"; + case ISAKMP_ETYPE_INFO: + return "_info"; + case ISAKMP_ETYPE_QUICK: + return "_quick"; + case ISAKMP_ETYPE_NEWGRP: + return "_newgrp"; + case ISAKMP_ETYPE_ACKINFO: + return "_ackinfo"; + default: + return num2str(k); + } +} + +char * +s_idtype (int k) +{ + switch (k) { + case IDTYPE_FQDN: + return "fqdn"; + case IDTYPE_USERFQDN: + return "user_fqdn"; + case IDTYPE_KEYID: + return "keyid"; + case IDTYPE_ADDRESS: + return "address"; + case IDTYPE_ASN1DN: + return "asn1dn"; + default: + return num2str(k); + } +} + +char * +s_switch (int k) +{ + switch (k) { + case FALSE: + return "off"; + case TRUE: + return "on"; + default: + return num2str(k); + } +} diff --git a/ipsec-tools/src/racoon/strnames.h b/ipsec-tools/src/racoon/strnames.h new file mode 100644 index 00000000..02ebbb5a --- /dev/null +++ b/ipsec-tools/src/racoon/strnames.h @@ -0,0 +1,80 @@ +/* $NetBSD: strnames.h,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: strnames.h,v 1.7 2005/04/18 10:04:26 manubsd Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _STRNAMES_H +#define _STRNAMES_H + +extern char *num2str __P((int n)); + +extern char *s_isakmp_state __P((int, int, int)); +extern char *s_isakmp_certtype __P((int)); +extern char *s_isakmp_etype __P((int)); +extern char *s_isakmp_notify_msg __P((int)); +extern char *s_isakmp_nptype __P((int)); +extern char *s_ipsecdoi_proto __P((int)); +extern char *s_ipsecdoi_trns_isakmp __P((int)); +extern char *s_ipsecdoi_trns_ah __P((int)); +extern char *s_ipsecdoi_trns_esp __P((int)); +extern char *s_ipsecdoi_trns_ipcomp __P((int)); +extern char *s_ipsecdoi_trns __P((int, int)); +extern char *s_ipsecdoi_attr __P((int)); +extern char *s_ipsecdoi_ltype __P((int)); +extern char *s_ipsecdoi_encmode __P((int)); +extern char *s_ipsecdoi_auth __P((int)); +extern char *s_ipsecdoi_attr_v __P((int, int)); +extern char *s_ipsecdoi_ident __P((int)); +extern char *s_oakley_attr __P((int)); +extern char *s_attr_isakmp_enc __P((int)); +extern char *s_attr_isakmp_hash __P((int)); +extern char *s_oakley_attr_method __P((int)); +extern char *s_attr_isakmp_desc __P((int)); +extern char *s_attr_isakmp_group __P((int)); +extern char *s_attr_isakmp_ltype __P((int)); +extern char *s_oakley_attr_v __P((int, int)); +extern char *s_ipsec_level __P((int)); +extern char *s_algclass __P((int)); +extern char *s_algtype __P((int, int)); +extern char *s_pfkey_type __P((int)); +extern char *s_pfkey_satype __P((int)); +extern char *s_direction __P((int)); +extern char *s_proto __P((int)); +extern char *s_doi __P((int)); +extern char *s_etype __P((int)); +extern char *s_idtype __P((int)); +extern char *s_switch __P((int)); +#ifdef ENABLE_HYBRID +extern char *s_isakmp_cfg_type __P((int)); +extern char *s_isakmp_cfg_ptype __P((int)); +#endif + +#endif /* _STRNAMES_H */ diff --git a/ipsec-tools/src/racoon/throttle.c b/ipsec-tools/src/racoon/throttle.c new file mode 100644 index 00000000..84a2d6b6 --- /dev/null +++ b/ipsec-tools/src/racoon/throttle.c @@ -0,0 +1,149 @@ +/* $NetBSD: throttle.c,v 1.7 2011/03/14 17:18:13 tteras Exp $ */ + +/* Id: throttle.c,v 1.5 2006/04/05 20:54:50 manubsd Exp */ + +/* + * Copyright (C) 2004 Emmanuel Dreyfus + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "vmbuf.h" +#include "misc.h" +#include "plog.h" +#include "throttle.h" +#include "sockmisc.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#include "gcmalloc.h" + +static struct throttle_list throttle_list = + TAILQ_HEAD_INITIALIZER(throttle_list); + +struct throttle_entry * +throttle_add(addr) + struct sockaddr *addr; +{ + struct throttle_entry *te; + struct timeval now, penalty; + size_t len; + + len = sizeof(*te) + - sizeof(struct sockaddr_storage) + + sysdep_sa_len(addr); + + if ((te = racoon_malloc(len)) == NULL) + return NULL; + + sched_get_monotonic_time(&now); + penalty.tv_sec = isakmp_cfg_config.auth_throttle; + penalty.tv_usec = 0; + timeradd(&now, &penalty, &te->penalty_ends); + + memcpy(&te->host, addr, sysdep_sa_len(addr)); + TAILQ_INSERT_HEAD(&throttle_list, te, next); + + return te; +} + +int +throttle_host(addr, authfail) + struct sockaddr *addr; + int authfail; +{ + struct throttle_entry *te; + struct timeval now, res; + int found = 0; + + if (isakmp_cfg_config.auth_throttle == 0) + return 0; + + sched_get_monotonic_time(&now); +restart: + RACOON_TAILQ_FOREACH_REVERSE(te, &throttle_list, throttle_list, next) { + /* + * Remove outdated entries + */ + if (timercmp(&te->penalty_ends, &now, <)) { + TAILQ_REMOVE(&throttle_list, te, next); + racoon_free(te); + goto restart; + } + + if (cmpsaddr(addr, (struct sockaddr *) &te->host) <= CMPSADDR_WOP_MATCH) { + found = 1; + break; + } + } + + /* + * No match, if auth failed, allocate a new throttle entry + * give no penalty even on error: this is the first time + * and we are indulgent. + */ + if (!found) { + if (authfail) { + if ((te = throttle_add(addr)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Throttle insertion failed\n"); + return isakmp_cfg_config.auth_throttle; + } + } + return 0; + } else { + /* + * We had a match and auth failed, increase penalty. + */ + if (authfail) { + struct timeval remaining, penalty; + + timersub(&te->penalty_ends, &now, &remaining); + penalty.tv_sec = isakmp_cfg_config.auth_throttle; + penalty.tv_usec = 0; + timeradd(&penalty, &remaining, &res); + if (res.tv_sec >= THROTTLE_PENALTY_MAX) { + res.tv_sec = THROTTLE_PENALTY_MAX; + res.tv_usec = 0; + } + timeradd(&now, &res, &te->penalty_ends); + } + } + + timersub(&te->penalty_ends, &now, &res); + return res.tv_sec; +} + diff --git a/ipsec-tools/src/racoon/throttle.h b/ipsec-tools/src/racoon/throttle.h new file mode 100644 index 00000000..54a8ed18 --- /dev/null +++ b/ipsec-tools/src/racoon/throttle.h @@ -0,0 +1,53 @@ +/* $NetBSD: throttle.h,v 1.5 2009/01/23 08:25:07 tteras Exp $ */ + +/* Id: throttle.h,v 1.1 2004/11/30 00:46:09 manubsd Exp */ + +/* + * Copyright (C) 2004 Emmanuel Dreyfus + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _THROTTLE_H +#define _THROTTLE_H + +#include "schedule.h" + +struct throttle_entry { + struct timeval penalty_ends; + TAILQ_ENTRY(throttle_entry) next; + struct sockaddr_storage host; +}; + +TAILQ_HEAD(throttle_list, throttle_entry); + +#define THROTTLE_PENALTY 1 +#define THROTTLE_PENALTY_MAX 10 + +struct throttle_entry *throttle_add(struct sockaddr *); +int throttle_host(struct sockaddr *, int); + +#endif /* _THROTTLE_H */ diff --git a/ipsec-tools/src/racoon/var.h b/ipsec-tools/src/racoon/var.h new file mode 100644 index 00000000..2946a9fa --- /dev/null +++ b/ipsec-tools/src/racoon/var.h @@ -0,0 +1,107 @@ +/* $NetBSD: var.h,v 1.5 2007/06/06 15:37:15 vanhu Exp $ */ + +/* Id: var.h,v 1.6 2004/11/20 16:16:59 monas Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _VAR_H +#define _VAR_H + +#if !defined(_VAR_H_) +#define _VAR_H_ + +#define MAX3(a, b, c) (a > b ? (a > c ? a : c) : (b > c ? b : c)) + +#define ISSET(exp, bit) (((exp) & (bit)) == (bit)) + +#define LALIGN(a) \ + ((a) > 0 ? ((a) &~ (sizeof(long) - 1)) : sizeof(long)) + +#define RNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) + +#define ARRAYLEN(a) (sizeof(a)/sizeof(a[0])) + +#define BUFSIZE 5120 + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#ifdef ENABLE_STATS +#include +#endif +#include + +/* + * use of GETNAMEINFO(x, y, NULL) is not politically correct, + * as sizeof(NULL) would be 4, not 0. Also, gcc-3.4.2+ bombs on it. + * In such cases, use GETNAMEINFO_NULL(x, y) + */ +#include +#include + +/* var.h is used from non-racoon code (like eaytest), so we can't use niflags */ +#define NIFLAGS (NI_NUMERICHOST | NI_NUMERICSERV) + +#define GETNAMEINFO(x, y, z) \ +do { \ + if (getnameinfo((x), sysdep_sa_len(x), (y), sizeof(y), (z), sizeof(z), \ + NIFLAGS) != 0) { \ + if (y != NULL) \ + strncpy((y), "(invalid)", sizeof(y)); \ + if (z != NULL) \ + strncpy((z), "(invalid)", sizeof(z)); \ + } \ +} while (0); + +#define GETNAMEINFO_NULL(x, y) \ +do { \ + if (getnameinfo((x), sysdep_sa_len(x), (y), sizeof(y), NULL, 0, \ + NIFLAGS) != 0) { \ + if (y != NULL) \ + strncpy((y), "(invalid)", sizeof(y)); \ + } \ +} while (0); + +#include +#ifndef LIST_FOREACH +#define LIST_FOREACH(elm, head, field) \ + for (elm = LIST_FIRST(head); elm; elm = LIST_NEXT(elm, field)) +#endif + +#include "gcmalloc.h" + +#endif /*!defined(_VAR_H_)*/ + +#endif /* _VAR_H */ diff --git a/ipsec-tools/src/racoon/vendorid.c b/ipsec-tools/src/racoon/vendorid.c new file mode 100644 index 00000000..81297bdd --- /dev/null +++ b/ipsec-tools/src/racoon/vendorid.c @@ -0,0 +1,320 @@ +/* $NetBSD: vendorid.c,v 1.8 2009/09/01 12:22:09 tteras Exp $ */ + +/* Id: vendorid.c,v 1.10 2006/02/22 16:10:21 vanhu Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "debug.h" + +#include "localconf.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "vendorid.h" +#include "crypto_openssl.h" +#include "handler.h" +#include "remoteconf.h" +#ifdef ENABLE_NATT +#include "nattraversal.h" +#endif +#ifdef ENABLE_HYBRID +#include +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif + +static struct vendor_id all_vendor_ids[] = { +{ VENDORID_IPSEC_TOOLS, "IPSec-Tools" }, +{ VENDORID_GSSAPI_LONG, "A GSS-API Authentication Method for IKE" }, +{ VENDORID_GSSAPI , "GSSAPI" }, +{ VENDORID_MS_NT5 , "MS NT5 ISAKMPOAKLEY" }, +{ VENDORID_NATT_00 , "draft-ietf-ipsec-nat-t-ike-00" }, +{ VENDORID_NATT_01 , "draft-ietf-ipsec-nat-t-ike-01" }, +{ VENDORID_NATT_02 , "draft-ietf-ipsec-nat-t-ike-02" }, +{ VENDORID_NATT_02_N , "draft-ietf-ipsec-nat-t-ike-02\n" }, +{ VENDORID_NATT_03 , "draft-ietf-ipsec-nat-t-ike-03" }, +{ VENDORID_NATT_04 , "draft-ietf-ipsec-nat-t-ike-04" }, +{ VENDORID_NATT_05 , "draft-ietf-ipsec-nat-t-ike-05" }, +{ VENDORID_NATT_06 , "draft-ietf-ipsec-nat-t-ike-06" }, +{ VENDORID_NATT_07 , "draft-ietf-ipsec-nat-t-ike-07" }, +{ VENDORID_NATT_08 , "draft-ietf-ipsec-nat-t-ike-08" }, +{ VENDORID_NATT_RFC , "RFC 3947" }, +{ VENDORID_XAUTH , "draft-ietf-ipsra-isakmp-xauth-06.txt" }, +{ VENDORID_UNITY , "CISCO-UNITY" }, +{ VENDORID_FRAG , "FRAGMENTATION" }, +/* Just a readable string for DPD ... */ +{ VENDORID_DPD , "DPD" }, +/* Other known Vendor IDs */ +{ VENDORID_KAME , "KAME/racoon" }, +}; + +#define NUMVENDORIDS (sizeof(all_vendor_ids)/sizeof(all_vendor_ids[0])) + +#define DPD_MAJOR_VERSION 0x01 +#define DPD_MINOR_VERSION 0x00 + +const char vendorid_dpd_hash[] = { + 0xAF, 0xCA, 0xD7, 0x13, + 0x68, 0xA1, 0xF1, 0xC9, + 0x6B, 0x86, 0x96, 0xFC, + 0x77, 0x57, DPD_MAJOR_VERSION, DPD_MINOR_VERSION +}; + + +static vchar_t *vendorid_fixup(int, vchar_t *t); + +static struct vendor_id * +lookup_vendor_id_by_id (int id) +{ + int i; + + for (i = 0; i < NUMVENDORIDS; i++) + if (all_vendor_ids[i].id == id) + return &all_vendor_ids[i]; + + return NULL; +} + +const char * +vid_string_by_id (int id) +{ + struct vendor_id *current; + + if (id == VENDORID_DPD) + return vendorid_dpd_hash; + + current = lookup_vendor_id_by_id(id); + + return current ? current->string : NULL; +} + +static struct vendor_id * +lookup_vendor_id_by_hash (const char *hash) +{ + int i; + unsigned char *h = (unsigned char *)hash; + + for (i = 0; i < NUMVENDORIDS; i++) + if (strncmp(all_vendor_ids[i].hash->v, hash, + all_vendor_ids[i].hash->l) == 0) + return &all_vendor_ids[i]; + + return NULL; +} + +void +compute_vendorids (void) +{ + int i; + vchar_t vid; + + for (i = 0; i < NUMVENDORIDS; i++) { + /* VENDORID_DPD is not a MD5 sum... */ + if(all_vendor_ids[i].id == VENDORID_DPD){ + all_vendor_ids[i].hash = vmalloc(sizeof(vendorid_dpd_hash)); + if (all_vendor_ids[i].hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to get memory for VID hash\n"); + exit(1); /* this really shouldn't happen */ + } + memcpy(all_vendor_ids[i].hash->v, vendorid_dpd_hash, + sizeof(vendorid_dpd_hash)); + continue; + } + + vid.v = (char *) all_vendor_ids[i].string; + vid.l = strlen(vid.v); + + all_vendor_ids[i].hash = eay_md5_one(&vid); + if (all_vendor_ids[i].hash == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "unable to hash vendor ID string\n"); + + /* Special cases */ + all_vendor_ids[i].hash = + vendorid_fixup(all_vendor_ids[i].id, + all_vendor_ids[i].hash); + } +} + +/* + * set hashed vendor id. + * hash function is always MD5. + */ +vchar_t * +set_vendorid(int vendorid) +{ + struct vendor_id *current; + vchar_t vid, *new; + + if (vendorid == VENDORID_UNKNOWN) { + /* + * The default unknown ID gets translated to + * KAME/racoon. + */ + vendorid = VENDORID_DEFAULT; + } + + current = lookup_vendor_id_by_id(vendorid); + if (current == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid vendor ID index: %d\n", vendorid); + return (NULL); + } + + /* The rest of racoon expects a private copy + * of the VID that could be free'd after use. + * That's why we don't return the original pointer. */ + return vdup(current->hash); +} + +/* + * Check the vendor ID payload -- return the vendor ID index + * if we find a recognized one, or UNKNOWN if we don't. + * + * gen ... points to Vendor ID payload. + */ +static int +check_vendorid(struct isakmp_gen *gen) +{ + vchar_t vid, *vidhash; + int i, vidlen; + struct vendor_id *current; + + if (gen == NULL) + return (VENDORID_UNKNOWN); + + vidlen = ntohs(gen->len) - sizeof(*gen); + + current = lookup_vendor_id_by_hash((char *)(gen + 1)); + if (!current) + goto unknown; + + if (current->hash->l < vidlen) + plog(LLV_INFO, LOCATION, NULL, + "received broken Microsoft ID: %s\n", + current->string); + else + plog(LLV_INFO, LOCATION, NULL, + "received Vendor ID: %s\n", + current->string); + + return current->id; + +unknown: + plog(LLV_DEBUG, LOCATION, NULL, "received unknown Vendor ID\n"); + plogdump(LLV_DEBUG, (char *)(gen + 1), vidlen); + return (VENDORID_UNKNOWN); +} + +int +handle_vendorid(struct ph1handle *iph1, struct isakmp_gen *gen) +{ + int vid_numeric; + + vid_numeric = check_vendorid(gen); + if (vid_numeric == VENDORID_UNKNOWN) + return vid_numeric; + + iph1->vendorid_mask |= BIT(vid_numeric); + +#ifdef ENABLE_NATT + if (natt_vendorid(vid_numeric)) + natt_handle_vendorid(iph1, vid_numeric); +#endif +#ifdef ENABLE_HYBRID + switch (vid_numeric) { + case VENDORID_XAUTH: + iph1->mode_cfg->flags |= ISAKMP_CFG_VENDORID_XAUTH; + break; + case VENDORID_UNITY: + iph1->mode_cfg->flags |= ISAKMP_CFG_VENDORID_UNITY; + break; + default: + break; + } +#endif +#ifdef ENABLE_DPD + if (vid_numeric == VENDORID_DPD && + (iph1->rmconf == NULL || iph1->rmconf->dpd)) { + iph1->dpd_support = 1; + plog(LLV_DEBUG, LOCATION, NULL, "remote supports DPD\n"); + } +#endif + + return vid_numeric; +} + +static vchar_t * +vendorid_fixup(vendorid, vidhash) + int vendorid; + vchar_t *vidhash; +{ + switch(vendorid) { + case VENDORID_XAUTH: { /* The vendor Id is truncated */ + vchar_t *tmp; + + if ((tmp = vmalloc(8)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to hash vendor ID string\n"); + return NULL; + } + + memcpy(tmp->v, vidhash->v, 8); + vfree(vidhash); + vidhash = tmp; + + break; + } + case VENDORID_UNITY: /* Two bytes tweak */ + vidhash->v[14] = 0x01; + vidhash->v[15] = 0x00; + break; + + default: + break; + } + + return vidhash; +} diff --git a/ipsec-tools/src/racoon/vendorid.h b/ipsec-tools/src/racoon/vendorid.h new file mode 100644 index 00000000..17745757 --- /dev/null +++ b/ipsec-tools/src/racoon/vendorid.h @@ -0,0 +1,105 @@ +/* $NetBSD: vendorid.h,v 1.6 2009/01/23 08:06:56 tteras Exp $ */ + +/* Id: vendorid.h,v 1.11 2006/02/17 14:09:10 vanhu Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _VENDORID_H +#define _VENDORID_H + +#ifndef BIT +#define BIT(x) (1 << (x)) +#endif + +/* The unknown vendor ID. */ +#define VENDORID_UNKNOWN -1 + +/* Our default vendor ID. */ +#define VENDORID_DEFAULT VENDORID_IPSEC_TOOLS + +#define VENDORID_IPSEC_TOOLS 0 + +/* Refer to draft-ietf-ipsec-isakmp-gss-auth-06.txt. */ +#define VENDORID_GSSAPI_LONG 1 +#define VENDORID_GSSAPI 2 +#define VENDORID_MS_NT5 3 + +#define VENDORID_GSSAPI_MASK (BIT(VENDORID_GSSAPI_LONG) | \ + BIT(VENDORID_GSSAPI) | \ + BIT(VENDORID_MS_NT5)) + +/* NAT-T support */ +#define VENDORID_NATT_00 4 +#define VENDORID_NATT_01 5 +#define VENDORID_NATT_02 6 +#define VENDORID_NATT_02_N 7 +#define VENDORID_NATT_03 8 +#define VENDORID_NATT_04 9 +#define VENDORID_NATT_05 10 +#define VENDORID_NATT_06 11 +#define VENDORID_NATT_07 12 +#define VENDORID_NATT_08 13 +#define VENDORID_NATT_RFC 14 + +#define VENDORID_NATT_FIRST VENDORID_NATT_00 +#define VENDORID_NATT_LAST VENDORID_NATT_RFC + +#define MAX_NATT_VID_COUNT (VENDORID_NATT_LAST - VENDORID_NATT_FIRST + 1) + +/* Hybrid auth */ +#define VENDORID_XAUTH 15 +#define VENDORID_UNITY 16 + +/* IKE fragmentation */ +#define VENDORID_FRAG 17 + +/* Dead Peer Detection */ +#define VENDORID_DPD 18 + + +/* Other Vendors... + * XXX: do some cleanup to have separate lists for "real" vendors (to complete) + * and "features" VendorIDs + */ +#define VENDORID_KAME 19 + +struct vendor_id { + int id; + const char *string; + vchar_t *hash; +}; + +vchar_t *set_vendorid __P((int)); +int handle_vendorid __P((struct ph1handle *, struct isakmp_gen *)); + +void compute_vendorids __P((void)); +const char *vid_string_by_id __P((int id)); + +#endif /* _VENDORID_H */ diff --git a/ipsec-tools/src/racoon/vmbuf.c b/ipsec-tools/src/racoon/vmbuf.c new file mode 100644 index 00000000..6c1aed1f --- /dev/null +++ b/ipsec-tools/src/racoon/vmbuf.c @@ -0,0 +1,137 @@ +/* $NetBSD: vmbuf.c,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* $KAME: vmbuf.c,v 1.11 2001/11/26 16:54:29 sakane Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#define NONEED_DRM + +#include +#include + +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "debug.h" +#include "plog.h" +#include "gcmalloc.h" + +vchar_t * +vmalloc(size) + size_t size; +{ + vchar_t *var; + + if ((var = (vchar_t *)racoon_malloc(sizeof(*var))) == NULL) + return NULL; + + var->l = size; + if (size == 0) { + var->v = NULL; + } else { + var->v = (caddr_t)racoon_calloc(1, size); + if (var->v == NULL) { + (void)racoon_free(var); + return NULL; + } + } + + return var; +} + +vchar_t * +vrealloc(ptr, size) + vchar_t *ptr; + size_t size; +{ + caddr_t v; + + if (ptr != NULL) { + if (ptr->l == 0) { + (void)vfree(ptr); + return vmalloc(size); /* zero-fill it? */ + } + + if ((v = (caddr_t)racoon_realloc(ptr->v, size)) == NULL) { + (void)vfree(ptr); + return NULL; + } + + if ( size > ptr->l) + memset(v + ptr->l, 0, size - ptr->l); + ptr->v = v; + ptr->l = size; + } else { + if ((ptr = vmalloc(size)) == NULL) + return NULL; + } + + return ptr; +} + +void +vfree(var) + vchar_t *var; +{ + if (var == NULL) + return; + + if (var->v) + (void)racoon_free(var->v); + + (void)racoon_free(var); + + return; +} + +vchar_t * +vdup(src) + vchar_t *src; +{ + vchar_t *new; + + if (src == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "vdup(NULL) called\n"); + return NULL; + } + + if ((new = vmalloc(src->l)) == NULL) + return NULL; + + memcpy(new->v, src->v, src->l); + + return new; +} diff --git a/ipsec-tools/src/racoon/vmbuf.h b/ipsec-tools/src/racoon/vmbuf.h new file mode 100644 index 00000000..3f2f4ea9 --- /dev/null +++ b/ipsec-tools/src/racoon/vmbuf.h @@ -0,0 +1,73 @@ +/* $NetBSD: vmbuf.h,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: vmbuf.h,v 1.4 2005/10/30 10:28:44 vanhu Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _VMBUF_H +#define _VMBUF_H + +/* + * bp v + * v v + * ........................ + * <--------------> l + * <----------------------> bl + */ +typedef struct _vchar_t_ { +#if notyet + u_int32_t t; /* type of the value */ + vchar_t *n; /* next vchar_t buffer */ + size_t bl; /* length of the buffer */ + caddr_t bp; /* pointer to the buffer */ +#endif + size_t l; /* length of the value */ + caddr_t v; /* place holder to the pointer to the value */ +} vchar_t; + +#define VPTRINIT(p) \ +do { \ + if (p) { \ + vfree(p); \ + (p) = NULL; \ + } \ +} while(0); + +#if defined(__APPLE__) && defined(__MACH__) +/* vfree is already defined in Apple's system libraries */ +#define vfree vmbuf_free +#endif + +extern vchar_t *vmalloc __P((size_t)); +extern vchar_t *vrealloc __P((vchar_t *, size_t)); +extern void vfree __P((vchar_t *)); +extern vchar_t *vdup __P((vchar_t *)); + +#endif /* _VMBUF_H */ diff --git a/ipsec-tools/src/setkey/Makefile.am b/ipsec-tools/src/setkey/Makefile.am new file mode 100644 index 00000000..746c1f17 --- /dev/null +++ b/ipsec-tools/src/setkey/Makefile.am @@ -0,0 +1,22 @@ + +sbin_PROGRAMS = setkey + +AM_CFLAGS = -I${top_srcdir}/src/libipsec @GLIBC_BUGS@ +AM_YFLAGS = -d + +BUILT_SOURCES = parse.h + +setkey_SOURCES = \ + setkey.c \ + parse.y \ + token.l + +setkey_LDFLAGS = ../libipsec/libipsec.la +setkey_DEPENDENCIES = ../libipsec/libipsec.la +setkey_LDADD = $(LEXLIB) + +noinst_HEADERS = vchar.h extern.h +man8_MANS = setkey.8 + +EXTRA_DIST = ${man8_MANS} sample-policy01.cf sample-policy02.cf sample.cf \ + scriptdump.pl test-pfkey.c diff --git a/ipsec-tools/src/setkey/Makefile.in b/ipsec-tools/src/setkey/Makefile.in new file mode 100644 index 00000000..4be0ec61 --- /dev/null +++ b/ipsec-tools/src/setkey/Makefile.in @@ -0,0 +1,760 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +sbin_PROGRAMS = setkey$(EXEEXT) +subdir = src/setkey +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am parse.h \ + parse.c token.c $(top_srcdir)/depcomp $(top_srcdir)/ylwrap \ + $(noinst_HEADERS) +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acracoon.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" +PROGRAMS = $(sbin_PROGRAMS) +am_setkey_OBJECTS = setkey.$(OBJEXT) parse.$(OBJEXT) token.$(OBJEXT) +setkey_OBJECTS = $(am_setkey_OBJECTS) +am__DEPENDENCIES_1 = +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +setkey_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(setkey_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) +LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) +AM_V_LEX = $(am__v_LEX_@AM_V@) +am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) +am__v_LEX_0 = @echo " LEX " $@; +am__v_LEX_1 = +YLWRAP = $(top_srcdir)/ylwrap +am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ + -e s/c++$$/h++/ -e s/c$$/h/ +YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) +LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) +AM_V_YACC = $(am__v_YACC_@AM_V@) +am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) +am__v_YACC_0 = @echo " YACC " $@; +am__v_YACC_1 = +SOURCES = $(setkey_SOURCES) +DIST_SOURCES = $(setkey_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(man8_MANS) +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGURE_AMFLAGS = @CONFIGURE_AMFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTOBJS = @CRYPTOBJS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_CRYPTO = @EXTRA_CRYPTO@ +FGREP = @FGREP@ +FRAG_OBJS = @FRAG_OBJS@ +GLIBC_BUGS = @GLIBC_BUGS@ +GREP = @GREP@ +HYBRID_OBJS = @HYBRID_OBJS@ +INCLUDE_GLIBC = @INCLUDE_GLIBC@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_OPTS = @INSTALL_OPTS@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KERNEL_INCLUDE = @KERNEL_INCLUDE@ +KRB5_CONFIG = @KRB5_CONFIG@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NATT_OBJS = @NATT_OBJS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RPM = @RPM@ +SECCTX_OBJS = @SECCTX_OBJS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +include_racoondir = @include_racoondir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CFLAGS = -I${top_srcdir}/src/libipsec @GLIBC_BUGS@ +AM_YFLAGS = -d +BUILT_SOURCES = parse.h +setkey_SOURCES = \ + setkey.c \ + parse.y \ + token.l + +setkey_LDFLAGS = ../libipsec/libipsec.la +setkey_DEPENDENCIES = ../libipsec/libipsec.la +setkey_LDADD = $(LEXLIB) +noinst_HEADERS = vchar.h extern.h +man8_MANS = setkey.8 +EXTRA_DIST = ${man8_MANS} sample-policy01.cf sample-policy02.cf sample.cf \ + scriptdump.pl test-pfkey.c + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .l .lo .o .obj .y +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/setkey/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/setkey/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +parse.h: parse.c + @if test ! -f $@; then rm -f parse.c; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) parse.c; else :; fi + +setkey$(EXEEXT): $(setkey_OBJECTS) $(setkey_DEPENDENCIES) $(EXTRA_setkey_DEPENDENCIES) + @rm -f setkey$(EXEEXT) + $(AM_V_CCLD)$(setkey_LINK) $(setkey_OBJECTS) $(setkey_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setkey.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/token.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +.l.c: + $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) + +.y.c: + $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man8: $(man8_MANS) + @$(NORMAL_INSTALL) + @list1='$(man8_MANS)'; \ + list2=''; \ + test -n "$(man8dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.8[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list='$(man8_MANS)'; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(PROGRAMS) $(MANS) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -rm -f parse.c + -rm -f parse.h + -rm -f token.c + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-sbinPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man8 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-man uninstall-sbinPROGRAMS + +uninstall-man: uninstall-man8 + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-man8 install-pdf \ + install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-man uninstall-man8 uninstall-sbinPROGRAMS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ipsec-tools/src/setkey/extern.h b/ipsec-tools/src/setkey/extern.h new file mode 100644 index 00000000..6f439faf --- /dev/null +++ b/ipsec-tools/src/setkey/extern.h @@ -0,0 +1,33 @@ +/* $NetBSD: extern.h,v 1.5 2009/03/06 11:45:03 tteras Exp $ */ + + + +void parse_init __P((void)); +int parse __P((FILE **)); +int parse_string __P((char *)); + +int setkeymsg __P((char *, size_t *)); +int sendkeymsg __P((char *, size_t)); + +int yylex __P((void)); +int yyparse __P((void)); +void yyfatal __P((const char *)); +void yyerror __P((const char *)); + +u_int32_t *sendkeymsg_spigrep __P((unsigned int, struct addrinfo *, + struct addrinfo *, int *)); + +extern int f_rfcmode; +extern int lineno; +extern int last_msg_type; +extern u_int32_t last_priority; +extern int exit_now; + +extern u_char m_buf[BUFSIZ]; +extern u_int m_len; +extern int f_debug; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY +extern int last_msg_type; +extern u_int32_t last_priority; +#endif diff --git a/ipsec-tools/src/setkey/parse.c b/ipsec-tools/src/setkey/parse.c new file mode 100644 index 00000000..2a9f8796 --- /dev/null +++ b/ipsec-tools/src/setkey/parse.c @@ -0,0 +1,3610 @@ +/* A Bison parser, made by GNU Bison 2.6.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + 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 3 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.6.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* Copy the first part of user declarations. */ +/* Line 336 of yacc.c */ +#line 34 "parse.y" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include PATH_IPSEC_H +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "libpfkey.h" +#include "vchar.h" +#include "extern.h" + +#define DEFAULT_NATT_PORT 4500 + +#ifndef UDP_ENCAP_ESPINUDP +#define UDP_ENCAP_ESPINUDP 2 +#endif + +#define ATOX(c) \ + (isdigit((int)c) ? (c - '0') : \ + (isupper((int)c) ? (c - 'A' + 10) : (c - 'a' + 10))) + +u_int32_t p_spi; +u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; +u_int32_t p_reqid; +u_int p_key_enc_len, p_key_auth_len; +const char *p_key_enc; +const char *p_key_auth; +time_t p_lt_hard, p_lt_soft; +size_t p_lb_hard, p_lb_soft; + +struct security_ctx { + u_int8_t doi; + u_int8_t alg; + u_int16_t len; + char *buf; +}; + +struct security_ctx sec_ctx; + +static u_int p_natt_type; +static struct addrinfo * p_natt_oa = NULL; + +static int p_aiflags = 0, p_aifamily = PF_UNSPEC; + +static struct addrinfo *parse_addr __P((char *, char *)); +static int fix_portstr __P((int, vchar_t *, vchar_t *, vchar_t *)); +static int setvarbuf __P((char *, int *, struct sadb_ext *, int, + const void *, int)); +void parse_init __P((void)); +void free_buffer __P((void)); + +int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t)); +static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *, + struct addrinfo *, int, struct addrinfo *, int)); +static int setkeymsg_spdaddr_tag __P((unsigned int, char *, vchar_t *)); +static int setkeymsg_addr __P((unsigned int, unsigned int, + struct addrinfo *, struct addrinfo *, int)); +static int setkeymsg_add __P((unsigned int, unsigned int, + struct addrinfo *, struct addrinfo *)); + +/* Line 336 of yacc.c */ +#line 144 "parse.c" + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "y.tab.h". */ +#ifndef YY_Y_TAB_H +# define YY_Y_TAB_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + EOT = 258, + SLASH = 259, + BLCL = 260, + ELCL = 261, + ADD = 262, + GET = 263, + DELETE = 264, + DELETEALL = 265, + FLUSH = 266, + DUMP = 267, + EXIT = 268, + PR_ESP = 269, + PR_AH = 270, + PR_IPCOMP = 271, + PR_ESPUDP = 272, + PR_TCP = 273, + F_PROTOCOL = 274, + F_AUTH = 275, + F_ENC = 276, + F_REPLAY = 277, + F_COMP = 278, + F_RAWCPI = 279, + F_MODE = 280, + MODE = 281, + F_REQID = 282, + F_EXT = 283, + EXTENSION = 284, + NOCYCLICSEQ = 285, + ALG_AUTH = 286, + ALG_AUTH_NOKEY = 287, + ALG_ENC = 288, + ALG_ENC_NOKEY = 289, + ALG_ENC_DESDERIV = 290, + ALG_ENC_DES32IV = 291, + ALG_ENC_OLD = 292, + ALG_COMP = 293, + F_LIFETIME_HARD = 294, + F_LIFETIME_SOFT = 295, + F_LIFEBYTE_HARD = 296, + F_LIFEBYTE_SOFT = 297, + DECSTRING = 298, + QUOTEDSTRING = 299, + HEXSTRING = 300, + STRING = 301, + ANY = 302, + SPDADD = 303, + SPDUPDATE = 304, + SPDDELETE = 305, + SPDDUMP = 306, + SPDFLUSH = 307, + F_POLICY = 308, + PL_REQUESTS = 309, + F_AIFLAGS = 310, + TAGGED = 311, + SECURITY_CTX = 312 + }; +#endif +/* Tokens. */ +#define EOT 258 +#define SLASH 259 +#define BLCL 260 +#define ELCL 261 +#define ADD 262 +#define GET 263 +#define DELETE 264 +#define DELETEALL 265 +#define FLUSH 266 +#define DUMP 267 +#define EXIT 268 +#define PR_ESP 269 +#define PR_AH 270 +#define PR_IPCOMP 271 +#define PR_ESPUDP 272 +#define PR_TCP 273 +#define F_PROTOCOL 274 +#define F_AUTH 275 +#define F_ENC 276 +#define F_REPLAY 277 +#define F_COMP 278 +#define F_RAWCPI 279 +#define F_MODE 280 +#define MODE 281 +#define F_REQID 282 +#define F_EXT 283 +#define EXTENSION 284 +#define NOCYCLICSEQ 285 +#define ALG_AUTH 286 +#define ALG_AUTH_NOKEY 287 +#define ALG_ENC 288 +#define ALG_ENC_NOKEY 289 +#define ALG_ENC_DESDERIV 290 +#define ALG_ENC_DES32IV 291 +#define ALG_ENC_OLD 292 +#define ALG_COMP 293 +#define F_LIFETIME_HARD 294 +#define F_LIFETIME_SOFT 295 +#define F_LIFEBYTE_HARD 296 +#define F_LIFEBYTE_SOFT 297 +#define DECSTRING 298 +#define QUOTEDSTRING 299 +#define HEXSTRING 300 +#define STRING 301 +#define ANY 302 +#define SPDADD 303 +#define SPDUPDATE 304 +#define SPDDELETE 305 +#define SPDDUMP 306 +#define SPDFLUSH 307 +#define F_POLICY 308 +#define PL_REQUESTS 309 +#define F_AIFLAGS 310 +#define TAGGED 311 +#define SECURITY_CTX 312 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 350 of yacc.c */ +#line 110 "parse.y" + + int num; + unsigned long ulnum; + vchar_t val; + struct addrinfo *res; + + +/* Line 350 of yacc.c */ +#line 309 "parse.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE yylval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !YY_Y_TAB_H */ + +/* Copy the second part of user declarations. */ + +/* Line 353 of yacc.c */ +#line 337 "parse.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 2 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 174 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 58 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 37 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 90 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 188 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 312 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 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, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 4, 7, 9, 11, 13, 15, 17, + 19, 21, 23, 25, 27, 29, 31, 41, 50, 57, + 66, 70, 74, 75, 77, 79, 81, 83, 86, 88, + 90, 92, 94, 96, 98, 103, 106, 109, 112, 116, + 118, 121, 123, 126, 129, 132, 134, 136, 138, 139, + 142, 145, 148, 151, 154, 157, 160, 163, 166, 169, + 172, 177, 191, 197, 211, 217, 231, 234, 237, 238, + 241, 243, 245, 247, 250, 251, 254, 255, 259, 263, + 267, 269, 271, 273, 275, 276, 278, 279, 284, 287, + 289 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 59, 0, -1, -1, 59, 60, -1, 61, -1, 64, + -1, 62, -1, 63, -1, 65, -1, 66, -1, 94, + -1, 78, -1, 79, -1, 80, -1, 81, -1, 82, + -1, 7, 83, 86, 86, 67, 68, 76, 69, 3, + -1, 9, 83, 86, 86, 67, 68, 76, 3, -1, + 10, 83, 85, 85, 67, 3, -1, 8, 83, 86, + 86, 67, 68, 76, 3, -1, 11, 67, 3, -1, + 12, 67, 3, -1, -1, 14, -1, 15, -1, 16, + -1, 17, -1, 17, 85, -1, 18, -1, 43, -1, + 45, -1, 70, -1, 71, -1, 72, -1, 21, 73, + 20, 74, -1, 21, 73, -1, 20, 74, -1, 23, + 38, -1, 23, 38, 24, -1, 34, -1, 33, 75, + -1, 37, -1, 35, 75, -1, 36, 75, -1, 31, + 75, -1, 32, -1, 44, -1, 45, -1, -1, 76, + 77, -1, 28, 29, -1, 28, 30, -1, 25, 26, + -1, 25, 47, -1, 27, 43, -1, 22, 43, -1, + 39, 43, -1, 40, 43, -1, 41, 43, -1, 42, + 43, -1, 57, 43, 43, 44, -1, 48, 83, 46, + 87, 88, 46, 87, 88, 89, 90, 91, 92, 3, + -1, 48, 56, 44, 92, 3, -1, 49, 83, 46, + 87, 88, 46, 87, 88, 89, 90, 91, 92, 3, + -1, 49, 56, 44, 92, 3, -1, 50, 83, 46, + 87, 88, 46, 87, 88, 89, 90, 91, 92, 3, + -1, 51, 3, -1, 52, 3, -1, -1, 83, 84, + -1, 55, -1, 46, -1, 46, -1, 46, 88, -1, + -1, 4, 43, -1, -1, 5, 47, 6, -1, 5, + 43, 6, -1, 5, 46, 6, -1, 43, -1, 47, + -1, 18, -1, 46, -1, -1, 46, -1, -1, 57, + 43, 43, 44, -1, 53, 93, -1, 54, -1, 13, + 3, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 151, 151, 153, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 178, 190, 209, 237, + 252, 262, 272, 275, 283, 291, 295, 302, 309, 318, + 319, 340, 341, 342, 346, 347, 351, 355, 363, 375, + 390, 405, 421, 442, 466, 491, 504, 508, 537, 539, + 543, 544, 545, 546, 547, 548, 557, 558, 559, 560, + 561, 573, 606, 619, 652, 664, 696, 707, 716, 718, + 722, 747, 758, 766, 777, 778, 783, 791, 800, 811, + 818, 819, 820, 823, 846, 850, 861, 863, 872, 896, + 901 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "EOT", "SLASH", "BLCL", "ELCL", "ADD", + "GET", "DELETE", "DELETEALL", "FLUSH", "DUMP", "EXIT", "PR_ESP", "PR_AH", + "PR_IPCOMP", "PR_ESPUDP", "PR_TCP", "F_PROTOCOL", "F_AUTH", "F_ENC", + "F_REPLAY", "F_COMP", "F_RAWCPI", "F_MODE", "MODE", "F_REQID", "F_EXT", + "EXTENSION", "NOCYCLICSEQ", "ALG_AUTH", "ALG_AUTH_NOKEY", "ALG_ENC", + "ALG_ENC_NOKEY", "ALG_ENC_DESDERIV", "ALG_ENC_DES32IV", "ALG_ENC_OLD", + "ALG_COMP", "F_LIFETIME_HARD", "F_LIFETIME_SOFT", "F_LIFEBYTE_HARD", + "F_LIFEBYTE_SOFT", "DECSTRING", "QUOTEDSTRING", "HEXSTRING", "STRING", + "ANY", "SPDADD", "SPDUPDATE", "SPDDELETE", "SPDDUMP", "SPDFLUSH", + "F_POLICY", "PL_REQUESTS", "F_AIFLAGS", "TAGGED", "SECURITY_CTX", + "$accept", "commands", "command", "add_command", "delete_command", + "deleteall_command", "get_command", "flush_command", "dump_command", + "protocol_spec", "spi", "algorithm_spec", "esp_spec", "ah_spec", + "ipcomp_spec", "enc_alg", "auth_alg", "key_string", "extension_spec", + "extension", "spdadd_command", "spdupdate_command", "spddelete_command", + "spddump_command", "spdflush_command", "ipaddropts", "ipaddropt", + "ipaddr", "ipandport", "prefix", "portstr", "upper_spec", + "upper_misc_spec", "context_spec", "policy_spec", "policy_requests", + "exit_command", YY_NULL +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 58, 59, 59, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 61, 62, 63, 64, + 65, 66, 67, 67, 67, 67, 67, 67, 67, 68, + 68, 69, 69, 69, 70, 70, 71, 72, 72, 73, + 73, 73, 73, 73, 74, 74, 75, 75, 76, 76, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 78, 78, 79, 79, 80, 81, 82, 83, 83, + 84, 85, 86, 86, 87, 87, 88, 88, 88, 88, + 89, 89, 89, 89, 90, 90, 91, 91, 92, 93, + 94 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 0, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 9, 8, 6, 8, + 3, 3, 0, 1, 1, 1, 1, 2, 1, 1, + 1, 1, 1, 1, 4, 2, 2, 2, 3, 1, + 2, 1, 2, 2, 2, 1, 1, 1, 0, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 4, 13, 5, 13, 5, 13, 2, 2, 0, 2, + 1, 1, 1, 2, 0, 2, 0, 3, 3, 3, + 1, 1, 1, 1, 0, 1, 0, 4, 2, 1, + 2 +}; + +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 2, 0, 1, 68, 68, 68, 68, 22, 22, 0, + 68, 68, 68, 0, 0, 3, 4, 6, 7, 5, + 8, 9, 11, 12, 13, 14, 15, 10, 0, 0, + 0, 0, 23, 24, 25, 26, 28, 0, 0, 90, + 0, 0, 0, 0, 0, 66, 67, 72, 70, 69, + 0, 0, 0, 71, 0, 27, 20, 21, 0, 74, + 0, 74, 74, 0, 73, 22, 22, 22, 22, 0, + 0, 0, 76, 0, 76, 76, 0, 0, 0, 0, + 0, 0, 0, 89, 88, 62, 75, 0, 64, 0, + 0, 78, 79, 77, 29, 30, 48, 48, 48, 18, + 74, 74, 74, 0, 0, 0, 76, 76, 76, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 31, 32, 33, 49, 19, 17, 0, 0, + 0, 0, 45, 36, 0, 39, 0, 0, 41, 35, + 55, 37, 52, 53, 54, 50, 51, 56, 57, 58, + 59, 0, 16, 82, 80, 83, 81, 84, 84, 84, + 46, 47, 44, 40, 42, 43, 0, 38, 0, 85, + 86, 86, 86, 34, 60, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 61, 63, 65, 87 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 1, 15, 16, 17, 18, 19, 20, 21, 37, + 96, 121, 122, 123, 124, 139, 133, 162, 103, 125, + 22, 23, 24, 25, 26, 28, 49, 54, 50, 72, + 64, 157, 170, 176, 70, 84, 27 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -61 +static const yytype_int16 yypact[] = +{ + -61, 3, -61, -61, -61, -61, -61, 96, 96, 17, + -12, 1, -61, 78, 106, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -38, -38, + -38, 29, -61, -61, -61, 69, -61, 122, 130, -61, + 92, 31, 93, 39, 49, -61, -61, 133, -61, -61, + 94, 94, 94, -61, 69, -61, -61, -61, 88, 135, + 88, 135, 135, -24, -61, 96, 96, 96, 96, 89, + 139, 101, 133, 142, 133, 133, 140, 141, 143, 81, + 81, 81, 145, -61, -61, -61, -61, 104, -61, 105, + 107, -61, -61, -61, -61, -61, -61, -61, -61, -61, + 135, 135, 135, 51, -1, 6, 133, 133, 133, -26, + 86, 109, 116, -22, 112, 13, 113, 114, 115, 117, + 118, 156, -61, -61, -61, -61, -61, -61, -11, -11, + -11, 5, -61, -61, 5, -61, 5, 5, -61, 144, + -61, 138, -61, -61, -61, -61, -61, -61, -61, -61, + -61, 120, -61, -61, -61, -61, -61, 119, 119, 119, + -61, -61, -61, -61, -61, -61, -26, -61, 123, -61, + 111, 111, 111, -61, -61, 126, 88, 88, 88, 127, + 163, 168, 169, 129, -61, -61, -61, -61 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -61, -61, -61, -61, -61, -61, -61, -61, -61, -7, + 22, -61, -61, -61, -61, -61, 8, -54, 30, -61, + -61, -61, -61, -61, -61, 95, -61, -17, 37, -32, + -10, 0, -27, -37, -60, -61, -61 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 73, 38, 126, 2, 142, 131, 132, 153, 47, 127, + 3, 4, 5, 6, 7, 8, 9, 48, 55, 76, + 39, 111, 77, 78, 113, 143, 114, 115, 111, 74, + 75, 113, 154, 114, 115, 155, 156, 68, 116, 117, + 118, 119, 145, 146, 40, 116, 117, 118, 119, 160, + 161, 10, 11, 12, 13, 14, 120, 42, 79, 80, + 81, 82, 87, 120, 89, 90, 51, 52, 106, 107, + 108, 109, 110, 111, 112, 53, 113, 59, 114, 115, + 163, 45, 164, 165, 48, 61, 48, 65, 66, 67, + 116, 117, 118, 119, 48, 62, 128, 129, 130, 29, + 30, 31, 97, 98, 48, 41, 43, 44, 120, 46, + 32, 33, 34, 35, 36, 53, 180, 181, 182, 134, + 135, 136, 137, 138, 94, 56, 95, 104, 105, 158, + 159, 171, 172, 57, 177, 178, 58, 60, 63, 71, + 47, 69, 85, 83, 86, 88, 91, 92, 99, 93, + 100, 101, 140, 102, 141, 144, 147, 148, 149, 152, + 150, 151, 167, 168, 166, 169, 184, 174, 175, 179, + 183, 185, 186, 187, 173 +}; + +#define yypact_value_is_default(yystate) \ + ((yystate) == (-61)) + +#define yytable_value_is_error(yytable_value) \ + YYID (0) + +static const yytype_uint8 yycheck[] = +{ + 60, 8, 3, 0, 26, 31, 32, 18, 46, 3, + 7, 8, 9, 10, 11, 12, 13, 55, 35, 43, + 3, 22, 46, 47, 25, 47, 27, 28, 22, 61, + 62, 25, 43, 27, 28, 46, 47, 54, 39, 40, + 41, 42, 29, 30, 56, 39, 40, 41, 42, 44, + 45, 48, 49, 50, 51, 52, 57, 56, 65, 66, + 67, 68, 72, 57, 74, 75, 29, 30, 100, 101, + 102, 20, 21, 22, 23, 46, 25, 46, 27, 28, + 134, 3, 136, 137, 55, 46, 55, 50, 51, 52, + 39, 40, 41, 42, 55, 46, 106, 107, 108, 4, + 5, 6, 80, 81, 55, 10, 11, 12, 57, 3, + 14, 15, 16, 17, 18, 46, 176, 177, 178, 33, + 34, 35, 36, 37, 43, 3, 45, 97, 98, 129, + 130, 158, 159, 3, 171, 172, 44, 44, 5, 4, + 46, 53, 3, 54, 43, 3, 6, 6, 3, 6, + 46, 46, 43, 46, 38, 43, 43, 43, 43, 3, + 43, 43, 24, 43, 20, 46, 3, 44, 57, 43, + 43, 3, 3, 44, 166 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 59, 0, 7, 8, 9, 10, 11, 12, 13, + 48, 49, 50, 51, 52, 60, 61, 62, 63, 64, + 65, 66, 78, 79, 80, 81, 82, 94, 83, 83, + 83, 83, 14, 15, 16, 17, 18, 67, 67, 3, + 56, 83, 56, 83, 83, 3, 3, 46, 55, 84, + 86, 86, 86, 46, 85, 85, 3, 3, 44, 46, + 44, 46, 46, 5, 88, 86, 86, 86, 85, 53, + 92, 4, 87, 92, 87, 87, 43, 46, 47, 67, + 67, 67, 67, 54, 93, 3, 43, 88, 3, 88, + 88, 6, 6, 6, 43, 45, 68, 68, 68, 3, + 46, 46, 46, 76, 76, 76, 87, 87, 87, 20, + 21, 22, 23, 25, 27, 28, 39, 40, 41, 42, + 57, 69, 70, 71, 72, 77, 3, 3, 88, 88, + 88, 31, 32, 74, 33, 34, 35, 36, 37, 73, + 43, 38, 26, 47, 43, 29, 30, 43, 43, 43, + 43, 43, 3, 18, 43, 46, 47, 89, 89, 89, + 44, 45, 75, 75, 75, 75, 20, 24, 43, 46, + 90, 90, 90, 74, 44, 57, 91, 91, 91, 43, + 92, 92, 92, 43, 3, 3, 3, 44 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + + + +/* This macro is provided for backward compatibility. */ + +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULL; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 3: +/* Line 1787 of yacc.c */ +#line 154 "parse.y" + { + free_buffer(); + parse_init(); + } + break; + + case 16: +/* Line 1787 of yacc.c */ +#line 179 "parse.y" + { + int status; + + status = setkeymsg_add(SADB_ADD, (yyvsp[(5) - (9)].num), (yyvsp[(3) - (9)].res), (yyvsp[(4) - (9)].res)); + if (status < 0) + return -1; + } + break; + + case 17: +/* Line 1787 of yacc.c */ +#line 191 "parse.y" + { + int status; + + if ((yyvsp[(3) - (8)].res)->ai_next || (yyvsp[(4) - (8)].res)->ai_next) { + yyerror("multiple address specified"); + return -1; + } + if (p_mode != IPSEC_MODE_ANY) + yyerror("WARNING: mode is obsolete"); + + status = setkeymsg_addr(SADB_DELETE, (yyvsp[(5) - (8)].num), (yyvsp[(3) - (8)].res), (yyvsp[(4) - (8)].res), 0); + if (status < 0) + return -1; + } + break; + + case 18: +/* Line 1787 of yacc.c */ +#line 210 "parse.y" + { +#ifndef __linux__ + if (setkeymsg_addr(SADB_DELETE, (yyvsp[(5) - (6)].num), (yyvsp[(3) - (6)].res), (yyvsp[(4) - (6)].res), 1) < 0) + return -1; +#else /* __linux__ */ + /* linux strictly adheres to RFC2367, and returns + * an error if we send an SADB_DELETE request without + * an SPI. Therefore, we must first retrieve a list + * of SPIs for all matching SADB entries, and then + * delete each one separately. */ + u_int32_t *spi; + int i, n; + + spi = sendkeymsg_spigrep((yyvsp[(5) - (6)].num), (yyvsp[(3) - (6)].res), (yyvsp[(4) - (6)].res), &n); + for (i = 0; i < n; i++) { + p_spi = spi[i]; + if (setkeymsg_addr(SADB_DELETE, + (yyvsp[(5) - (6)].num), (yyvsp[(3) - (6)].res), (yyvsp[(4) - (6)].res), 0) < 0) + return -1; + } + free(spi); +#endif /* __linux__ */ + } + break; + + case 19: +/* Line 1787 of yacc.c */ +#line 238 "parse.y" + { + int status; + + if (p_mode != IPSEC_MODE_ANY) + yyerror("WARNING: mode is obsolete"); + + status = setkeymsg_addr(SADB_GET, (yyvsp[(5) - (8)].num), (yyvsp[(3) - (8)].res), (yyvsp[(4) - (8)].res), 0); + if (status < 0) + return -1; + } + break; + + case 20: +/* Line 1787 of yacc.c */ +#line 253 "parse.y" + { + struct sadb_msg msg; + setkeymsg0(&msg, SADB_FLUSH, (yyvsp[(2) - (3)].num), sizeof(msg)); + sendkeymsg((char *)&msg, sizeof(msg)); + } + break; + + case 21: +/* Line 1787 of yacc.c */ +#line 263 "parse.y" + { + struct sadb_msg msg; + setkeymsg0(&msg, SADB_DUMP, (yyvsp[(2) - (3)].num), sizeof(msg)); + sendkeymsg((char *)&msg, sizeof(msg)); + } + break; + + case 22: +/* Line 1787 of yacc.c */ +#line 272 "parse.y" + { + (yyval.num) = SADB_SATYPE_UNSPEC; + } + break; + + case 23: +/* Line 1787 of yacc.c */ +#line 276 "parse.y" + { + (yyval.num) = SADB_SATYPE_ESP; + if ((yyvsp[(1) - (1)].num) == 1) + p_ext |= SADB_X_EXT_OLD; + else + p_ext &= ~SADB_X_EXT_OLD; + } + break; + + case 24: +/* Line 1787 of yacc.c */ +#line 284 "parse.y" + { + (yyval.num) = SADB_SATYPE_AH; + if ((yyvsp[(1) - (1)].num) == 1) + p_ext |= SADB_X_EXT_OLD; + else + p_ext &= ~SADB_X_EXT_OLD; + } + break; + + case 25: +/* Line 1787 of yacc.c */ +#line 292 "parse.y" + { + (yyval.num) = SADB_X_SATYPE_IPCOMP; + } + break; + + case 26: +/* Line 1787 of yacc.c */ +#line 296 "parse.y" + { + (yyval.num) = SADB_SATYPE_ESP; + p_ext &= ~SADB_X_EXT_OLD; + p_natt_oa = 0; + p_natt_type = UDP_ENCAP_ESPINUDP; + } + break; + + case 27: +/* Line 1787 of yacc.c */ +#line 303 "parse.y" + { + (yyval.num) = SADB_SATYPE_ESP; + p_ext &= ~SADB_X_EXT_OLD; + p_natt_oa = (yyvsp[(2) - (2)].res); + p_natt_type = UDP_ENCAP_ESPINUDP; + } + break; + + case 28: +/* Line 1787 of yacc.c */ +#line 310 "parse.y" + { +#ifdef SADB_X_SATYPE_TCPSIGNATURE + (yyval.num) = SADB_X_SATYPE_TCPSIGNATURE; +#endif + } + break; + + case 29: +/* Line 1787 of yacc.c */ +#line 318 "parse.y" + { p_spi = (yyvsp[(1) - (1)].ulnum); } + break; + + case 30: +/* Line 1787 of yacc.c */ +#line 320 "parse.y" + { + char *ep; + unsigned long v; + + ep = NULL; + v = strtoul((yyvsp[(1) - (1)].val).buf, &ep, 16); + if (!ep || *ep) { + yyerror("invalid SPI"); + return -1; + } + if (v & ~0xffffffff) { + yyerror("SPI too big."); + return -1; + } + + p_spi = v; + } + break; + + case 37: +/* Line 1787 of yacc.c */ +#line 356 "parse.y" + { + if ((yyvsp[(2) - (2)].num) < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = (yyvsp[(2) - (2)].num); + } + break; + + case 38: +/* Line 1787 of yacc.c */ +#line 364 "parse.y" + { + if ((yyvsp[(2) - (3)].num) < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = (yyvsp[(2) - (3)].num); + p_ext |= SADB_X_EXT_RAWCPI; + } + break; + + case 39: +/* Line 1787 of yacc.c */ +#line 375 "parse.y" + { + if ((yyvsp[(1) - (1)].num) < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = (yyvsp[(1) - (1)].num); + + p_key_enc_len = 0; + p_key_enc = ""; + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } + break; + + case 40: +/* Line 1787 of yacc.c */ +#line 390 "parse.y" + { + if ((yyvsp[(1) - (2)].num) < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = (yyvsp[(1) - (2)].num); + + p_key_enc_len = (yyvsp[(2) - (2)].val).len; + p_key_enc = (yyvsp[(2) - (2)].val).buf; + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } + break; + + case 41: +/* Line 1787 of yacc.c */ +#line 405 "parse.y" + { + if ((yyvsp[(1) - (1)].num) < 0) { + yyerror("unsupported algorithm"); + return -1; + } + yyerror("WARNING: obsolete algorithm"); + p_alg_enc = (yyvsp[(1) - (1)].num); + + p_key_enc_len = 0; + p_key_enc = ""; + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } + break; + + case 42: +/* Line 1787 of yacc.c */ +#line 422 "parse.y" + { + if ((yyvsp[(1) - (2)].num) < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = (yyvsp[(1) - (2)].num); + if (p_ext & SADB_X_EXT_OLD) { + yyerror("algorithm mismatched"); + return -1; + } + p_ext |= SADB_X_EXT_DERIV; + + p_key_enc_len = (yyvsp[(2) - (2)].val).len; + p_key_enc = (yyvsp[(2) - (2)].val).buf; + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } + break; + + case 43: +/* Line 1787 of yacc.c */ +#line 443 "parse.y" + { + if ((yyvsp[(1) - (2)].num) < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = (yyvsp[(1) - (2)].num); + if (!(p_ext & SADB_X_EXT_OLD)) { + yyerror("algorithm mismatched"); + return -1; + } + p_ext |= SADB_X_EXT_IV4B; + + p_key_enc_len = (yyvsp[(2) - (2)].val).len; + p_key_enc = (yyvsp[(2) - (2)].val).buf; + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } + break; + + case 44: +/* Line 1787 of yacc.c */ +#line 466 "parse.y" + { + if ((yyvsp[(1) - (2)].num) < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_auth = (yyvsp[(1) - (2)].num); + + p_key_auth_len = (yyvsp[(2) - (2)].val).len; + p_key_auth = (yyvsp[(2) - (2)].val).buf; +#ifdef SADB_X_AALG_TCP_MD5 + if (p_alg_auth == SADB_X_AALG_TCP_MD5) { + if ((p_key_auth_len < 1) || + (p_key_auth_len > 80)) + return -1; + } else +#endif + { + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, + p_alg_auth, + PFKEY_UNUNIT64(p_key_auth_len)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } + } + break; + + case 45: +/* Line 1787 of yacc.c */ +#line 491 "parse.y" + { + if ((yyvsp[(1) - (1)].num) < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_auth = (yyvsp[(1) - (1)].num); + + p_key_auth_len = 0; + p_key_auth = NULL; + } + break; + + case 46: +/* Line 1787 of yacc.c */ +#line 505 "parse.y" + { + (yyval.val) = (yyvsp[(1) - (1)].val); + } + break; + + case 47: +/* Line 1787 of yacc.c */ +#line 509 "parse.y" + { + caddr_t pp_key; + caddr_t bp; + caddr_t yp = (yyvsp[(1) - (1)].val).buf; + int l; + + l = strlen(yp) % 2 + strlen(yp) / 2; + if ((pp_key = malloc(l)) == 0) { + yyerror("not enough core"); + return -1; + } + memset(pp_key, 0, l); + + bp = pp_key; + if (strlen(yp) % 2) { + *bp = ATOX(yp[0]); + yp++, bp++; + } + while (*yp) { + *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); + yp += 2, bp++; + } + + (yyval.val).len = l; + (yyval.val).buf = pp_key; + } + break; + + case 50: +/* Line 1787 of yacc.c */ +#line 543 "parse.y" + { p_ext |= (yyvsp[(2) - (2)].num); } + break; + + case 51: +/* Line 1787 of yacc.c */ +#line 544 "parse.y" + { p_ext &= ~SADB_X_EXT_CYCSEQ; } + break; + + case 52: +/* Line 1787 of yacc.c */ +#line 545 "parse.y" + { p_mode = (yyvsp[(2) - (2)].num); } + break; + + case 53: +/* Line 1787 of yacc.c */ +#line 546 "parse.y" + { p_mode = IPSEC_MODE_ANY; } + break; + + case 54: +/* Line 1787 of yacc.c */ +#line 547 "parse.y" + { p_reqid = (yyvsp[(2) - (2)].ulnum); } + break; + + case 55: +/* Line 1787 of yacc.c */ +#line 549 "parse.y" + { + if ((p_ext & SADB_X_EXT_OLD) != 0) { + yyerror("replay prevention cannot be used with " + "ah/esp-old"); + return -1; + } + p_replay = (yyvsp[(2) - (2)].ulnum); + } + break; + + case 56: +/* Line 1787 of yacc.c */ +#line 557 "parse.y" + { p_lt_hard = (yyvsp[(2) - (2)].ulnum); } + break; + + case 57: +/* Line 1787 of yacc.c */ +#line 558 "parse.y" + { p_lt_soft = (yyvsp[(2) - (2)].ulnum); } + break; + + case 58: +/* Line 1787 of yacc.c */ +#line 559 "parse.y" + { p_lb_hard = (yyvsp[(2) - (2)].ulnum); } + break; + + case 59: +/* Line 1787 of yacc.c */ +#line 560 "parse.y" + { p_lb_soft = (yyvsp[(2) - (2)].ulnum); } + break; + + case 60: +/* Line 1787 of yacc.c */ +#line 561 "parse.y" + { + sec_ctx.doi = (yyvsp[(2) - (4)].ulnum); + sec_ctx.alg = (yyvsp[(3) - (4)].ulnum); + sec_ctx.len = (yyvsp[(4) - (4)].val).len+1; + sec_ctx.buf = (yyvsp[(4) - (4)].val).buf; + } + break; + + case 61: +/* Line 1787 of yacc.c */ +#line 574 "parse.y" + { + int status; + struct addrinfo *src, *dst; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + last_msg_type = SADB_X_SPDADD; +#endif + + /* fixed port fields if ulp is icmp */ + if (fix_portstr((yyvsp[(9) - (13)].num), &(yyvsp[(10) - (13)].val), &(yyvsp[(5) - (13)].val), &(yyvsp[(8) - (13)].val))) + return -1; + + src = parse_addr((yyvsp[(3) - (13)].val).buf, (yyvsp[(5) - (13)].val).buf); + dst = parse_addr((yyvsp[(6) - (13)].val).buf, (yyvsp[(8) - (13)].val).buf); + if (!src || !dst) { + /* yyerror is already called */ + return -1; + } + if (src->ai_next || dst->ai_next) { + yyerror("multiple address specified"); + freeaddrinfo(src); + freeaddrinfo(dst); + return -1; + } + + status = setkeymsg_spdaddr(SADB_X_SPDADD, (yyvsp[(9) - (13)].num), &(yyvsp[(12) - (13)].val), + src, (yyvsp[(4) - (13)].num), dst, (yyvsp[(7) - (13)].num)); + freeaddrinfo(src); + freeaddrinfo(dst); + if (status < 0) + return -1; + } + break; + + case 62: +/* Line 1787 of yacc.c */ +#line 607 "parse.y" + { + int status; + + status = setkeymsg_spdaddr_tag(SADB_X_SPDADD, + (yyvsp[(3) - (5)].val).buf, &(yyvsp[(4) - (5)].val)); + if (status < 0) + return -1; + } + break; + + case 63: +/* Line 1787 of yacc.c */ +#line 620 "parse.y" + { + int status; + struct addrinfo *src, *dst; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + last_msg_type = SADB_X_SPDUPDATE; +#endif + + /* fixed port fields if ulp is icmp */ + if (fix_portstr((yyvsp[(9) - (13)].num), &(yyvsp[(10) - (13)].val), &(yyvsp[(5) - (13)].val), &(yyvsp[(8) - (13)].val))) + return -1; + + src = parse_addr((yyvsp[(3) - (13)].val).buf, (yyvsp[(5) - (13)].val).buf); + dst = parse_addr((yyvsp[(6) - (13)].val).buf, (yyvsp[(8) - (13)].val).buf); + if (!src || !dst) { + /* yyerror is already called */ + return -1; + } + if (src->ai_next || dst->ai_next) { + yyerror("multiple address specified"); + freeaddrinfo(src); + freeaddrinfo(dst); + return -1; + } + + status = setkeymsg_spdaddr(SADB_X_SPDUPDATE, (yyvsp[(9) - (13)].num), &(yyvsp[(12) - (13)].val), + src, (yyvsp[(4) - (13)].num), dst, (yyvsp[(7) - (13)].num)); + freeaddrinfo(src); + freeaddrinfo(dst); + if (status < 0) + return -1; + } + break; + + case 64: +/* Line 1787 of yacc.c */ +#line 653 "parse.y" + { + int status; + + status = setkeymsg_spdaddr_tag(SADB_X_SPDUPDATE, + (yyvsp[(3) - (5)].val).buf, &(yyvsp[(4) - (5)].val)); + if (status < 0) + return -1; + } + break; + + case 65: +/* Line 1787 of yacc.c */ +#line 665 "parse.y" + { + int status; + struct addrinfo *src, *dst; + + /* fixed port fields if ulp is icmp */ + if (fix_portstr((yyvsp[(9) - (13)].num), &(yyvsp[(10) - (13)].val), &(yyvsp[(5) - (13)].val), &(yyvsp[(8) - (13)].val))) + return -1; + + src = parse_addr((yyvsp[(3) - (13)].val).buf, (yyvsp[(5) - (13)].val).buf); + dst = parse_addr((yyvsp[(6) - (13)].val).buf, (yyvsp[(8) - (13)].val).buf); + if (!src || !dst) { + /* yyerror is already called */ + return -1; + } + if (src->ai_next || dst->ai_next) { + yyerror("multiple address specified"); + freeaddrinfo(src); + freeaddrinfo(dst); + return -1; + } + + status = setkeymsg_spdaddr(SADB_X_SPDDELETE, (yyvsp[(9) - (13)].num), &(yyvsp[(12) - (13)].val), + src, (yyvsp[(4) - (13)].num), dst, (yyvsp[(7) - (13)].num)); + freeaddrinfo(src); + freeaddrinfo(dst); + if (status < 0) + return -1; + } + break; + + case 66: +/* Line 1787 of yacc.c */ +#line 697 "parse.y" + { + struct sadb_msg msg; + setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC, + sizeof(msg)); + sendkeymsg((char *)&msg, sizeof(msg)); + } + break; + + case 67: +/* Line 1787 of yacc.c */ +#line 708 "parse.y" + { + struct sadb_msg msg; + setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC, + sizeof(msg)); + sendkeymsg((char *)&msg, sizeof(msg)); + } + break; + + case 70: +/* Line 1787 of yacc.c */ +#line 723 "parse.y" + { + char *p; + + for (p = (yyvsp[(1) - (1)].val).buf + 1; *p; p++) + switch (*p) { + case '4': + p_aifamily = AF_INET; + break; +#ifdef INET6 + case '6': + p_aifamily = AF_INET6; + break; +#endif + case 'n': + p_aiflags = AI_NUMERICHOST; + break; + default: + yyerror("invalid flag"); + return -1; + } + } + break; + + case 71: +/* Line 1787 of yacc.c */ +#line 748 "parse.y" + { + (yyval.res) = parse_addr((yyvsp[(1) - (1)].val).buf, NULL); + if ((yyval.res) == NULL) { + /* yyerror already called by parse_addr */ + return -1; + } + } + break; + + case 72: +/* Line 1787 of yacc.c */ +#line 759 "parse.y" + { + (yyval.res) = parse_addr((yyvsp[(1) - (1)].val).buf, NULL); + if ((yyval.res) == NULL) { + /* yyerror already called by parse_addr */ + return -1; + } + } + break; + + case 73: +/* Line 1787 of yacc.c */ +#line 767 "parse.y" + { + (yyval.res) = parse_addr((yyvsp[(1) - (2)].val).buf, (yyvsp[(2) - (2)].val).buf); + if ((yyval.res) == NULL) { + /* yyerror already called by parse_addr */ + return -1; + } + } + break; + + case 74: +/* Line 1787 of yacc.c */ +#line 777 "parse.y" + { (yyval.num) = -1; } + break; + + case 75: +/* Line 1787 of yacc.c */ +#line 778 "parse.y" + { (yyval.num) = (yyvsp[(2) - (2)].ulnum); } + break; + + case 76: +/* Line 1787 of yacc.c */ +#line 783 "parse.y" + { + (yyval.val).buf = strdup("0"); + if (!(yyval.val).buf) { + yyerror("insufficient memory"); + return -1; + } + (yyval.val).len = strlen((yyval.val).buf); + } + break; + + case 77: +/* Line 1787 of yacc.c */ +#line 792 "parse.y" + { + (yyval.val).buf = strdup("0"); + if (!(yyval.val).buf) { + yyerror("insufficient memory"); + return -1; + } + (yyval.val).len = strlen((yyval.val).buf); + } + break; + + case 78: +/* Line 1787 of yacc.c */ +#line 801 "parse.y" + { + char buf[20]; + snprintf(buf, sizeof(buf), "%lu", (yyvsp[(2) - (3)].ulnum)); + (yyval.val).buf = strdup(buf); + if (!(yyval.val).buf) { + yyerror("insufficient memory"); + return -1; + } + (yyval.val).len = strlen((yyval.val).buf); + } + break; + + case 79: +/* Line 1787 of yacc.c */ +#line 812 "parse.y" + { + (yyval.val) = (yyvsp[(2) - (3)].val); + } + break; + + case 80: +/* Line 1787 of yacc.c */ +#line 818 "parse.y" + { (yyval.num) = (yyvsp[(1) - (1)].ulnum); } + break; + + case 81: +/* Line 1787 of yacc.c */ +#line 819 "parse.y" + { (yyval.num) = IPSEC_ULPROTO_ANY; } + break; + + case 82: +/* Line 1787 of yacc.c */ +#line 820 "parse.y" + { + (yyval.num) = IPPROTO_TCP; + } + break; + + case 83: +/* Line 1787 of yacc.c */ +#line 824 "parse.y" + { + struct protoent *ent; + + ent = getprotobyname((yyvsp[(1) - (1)].val).buf); + if (ent) + (yyval.num) = ent->p_proto; + else { + if (strcmp("icmp6", (yyvsp[(1) - (1)].val).buf) == 0) { + (yyval.num) = IPPROTO_ICMPV6; + } else if(strcmp("ip4", (yyvsp[(1) - (1)].val).buf) == 0) { + (yyval.num) = IPPROTO_IPV4; + } else { + yyerror("invalid upper layer protocol"); + return -1; + } + } + endprotoent(); + } + break; + + case 84: +/* Line 1787 of yacc.c */ +#line 846 "parse.y" + { + (yyval.val).buf = NULL; + (yyval.val).len = 0; + } + break; + + case 85: +/* Line 1787 of yacc.c */ +#line 851 "parse.y" + { + (yyval.val).buf = strdup((yyvsp[(1) - (1)].val).buf); + if (!(yyval.val).buf) { + yyerror("insufficient memory"); + return -1; + } + (yyval.val).len = strlen((yyval.val).buf); + } + break; + + case 87: +/* Line 1787 of yacc.c */ +#line 863 "parse.y" + { + sec_ctx.doi = (yyvsp[(2) - (4)].ulnum); + sec_ctx.alg = (yyvsp[(3) - (4)].ulnum); + sec_ctx.len = (yyvsp[(4) - (4)].val).len+1; + sec_ctx.buf = (yyvsp[(4) - (4)].val).buf; + } + break; + + case 88: +/* Line 1787 of yacc.c */ +#line 873 "parse.y" + { + char *policy; +#ifdef HAVE_PFKEY_POLICY_PRIORITY + struct sadb_x_policy *xpl; +#endif + + policy = ipsec_set_policy((yyvsp[(2) - (2)].val).buf, (yyvsp[(2) - (2)].val).len); + if (policy == NULL) { + yyerror(ipsec_strerror()); + return -1; + } + + (yyval.val).buf = policy; + (yyval.val).len = ipsec_get_policylen(policy); + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + xpl = (struct sadb_x_policy *) (yyval.val).buf; + last_priority = xpl->sadb_x_policy_priority; +#endif + } + break; + + case 89: +/* Line 1787 of yacc.c */ +#line 896 "parse.y" + { (yyval.val) = (yyvsp[(1) - (1)].val); } + break; + + case 90: +/* Line 1787 of yacc.c */ +#line 902 "parse.y" + { + exit_now = 1; + YYACCEPT; + } + break; + + +/* Line 1787 of yacc.c */ +#line 2617 "parse.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +/* Line 2048 of yacc.c */ +#line 907 "parse.y" + + +int +setkeymsg0(msg, type, satype, l) + struct sadb_msg *msg; + unsigned int type; + unsigned int satype; + size_t l; +{ + + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = type; + msg->sadb_msg_errno = 0; + msg->sadb_msg_satype = satype; + msg->sadb_msg_reserved = 0; + msg->sadb_msg_seq = 0; + msg->sadb_msg_pid = getpid(); + msg->sadb_msg_len = PFKEY_UNIT64(l); + return 0; +} + +/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ +static int +setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) + unsigned int type; + unsigned int upper; + vchar_t *policy; + struct addrinfo *srcs; + int splen; + struct addrinfo *dsts; + int dplen; +{ + struct sadb_msg *msg; + char buf[BUFSIZ]; + int l, l0; + struct sadb_address m_addr; + struct addrinfo *s, *d; + int n; + int plen; + struct sockaddr *sa; + int salen; + struct sadb_x_policy *sp; +#ifdef HAVE_POLICY_FWD + struct sadb_x_ipsecrequest *ps = NULL; + int saved_level, saved_id = 0; +#endif + + msg = (struct sadb_msg *)buf; + + if (!srcs || !dsts) + return -1; + + /* fix up length afterwards */ + setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); + l = sizeof(struct sadb_msg); + + sp = (struct sadb_x_policy*) (buf + l); + memcpy(buf + l, policy->buf, policy->len); + l += policy->len; + + l0 = l; + n = 0; + + /* do it for all src/dst pairs */ + for (s = srcs; s; s = s->ai_next) { + for (d = dsts; d; d = d->ai_next) { + /* rewind pointer */ + l = l0; + + if (s->ai_addr->sa_family != d->ai_addr->sa_family) + continue; + switch (s->ai_addr->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + continue; + } + + /* set src */ + sa = s->ai_addr; + salen = sysdep_sa_len(s->ai_addr); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + m_addr.sadb_address_proto = upper; + m_addr.sadb_address_prefixlen = + (splen >= 0 ? splen : plen); + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), (caddr_t)sa, salen); + + /* set dst */ + sa = d->ai_addr; + salen = sysdep_sa_len(d->ai_addr); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; + m_addr.sadb_address_proto = upper; + m_addr.sadb_address_prefixlen = + (dplen >= 0 ? dplen : plen); + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), sa, salen); +#ifdef SADB_X_EXT_SEC_CTX + /* Add security context label */ + if (sec_ctx.doi) { + struct sadb_x_sec_ctx m_sec_ctx; + u_int slen = sizeof(struct sadb_x_sec_ctx); + + memset(&m_sec_ctx, 0, slen); + + m_sec_ctx.sadb_x_sec_len = + PFKEY_UNIT64(slen + PFKEY_ALIGN8(sec_ctx.len)); + + m_sec_ctx.sadb_x_sec_exttype = + SADB_X_EXT_SEC_CTX; + m_sec_ctx.sadb_x_ctx_len = sec_ctx.len;/*bytes*/ + m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi; + m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg; + setvarbuf(buf, &l, + (struct sadb_ext *)&m_sec_ctx, slen, + (caddr_t)sec_ctx.buf, sec_ctx.len); + } +#endif + msg->sadb_msg_len = PFKEY_UNIT64(l); + + sendkeymsg(buf, l); + +#ifdef HAVE_POLICY_FWD + /* create extra call for FWD policy */ + if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) { + sp->sadb_x_policy_dir = IPSEC_DIR_FWD; + ps = (struct sadb_x_ipsecrequest*) (sp+1); + + /* if request level is unique, change it to + * require for fwd policy */ + /* XXX: currently, only first policy is updated + * only. Update following too... */ + saved_level = ps->sadb_x_ipsecrequest_level; + if (saved_level == IPSEC_LEVEL_UNIQUE) { + saved_id = ps->sadb_x_ipsecrequest_reqid; + ps->sadb_x_ipsecrequest_reqid=0; + ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE; + } + + sendkeymsg(buf, l); + /* restoring for next message */ + sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND; + if (saved_level == IPSEC_LEVEL_UNIQUE) { + ps->sadb_x_ipsecrequest_reqid = saved_id; + ps->sadb_x_ipsecrequest_level = saved_level; + } + } +#endif + + n++; + } + } + + if (n == 0) + return -1; + else + return 0; +} + +static int +setkeymsg_spdaddr_tag(type, tag, policy) + unsigned int type; + char *tag; + vchar_t *policy; +{ + struct sadb_msg *msg; + char buf[BUFSIZ]; + int l, l0; +#ifdef SADB_X_EXT_TAG + struct sadb_x_tag m_tag; +#endif + int n; + + msg = (struct sadb_msg *)buf; + + /* fix up length afterwards */ + setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); + l = sizeof(struct sadb_msg); + + memcpy(buf + l, policy->buf, policy->len); + l += policy->len; + + l0 = l; + n = 0; + +#ifdef SADB_X_EXT_TAG + memset(&m_tag, 0, sizeof(m_tag)); + m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag)); + m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG; + if (strlcpy(m_tag.sadb_x_tag_name, tag, + sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name)) + return -1; + memcpy(buf + l, &m_tag, sizeof(m_tag)); + l += sizeof(m_tag); +#endif + + msg->sadb_msg_len = PFKEY_UNIT64(l); + + sendkeymsg(buf, l); + + return 0; +} + +/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ +static int +setkeymsg_addr(type, satype, srcs, dsts, no_spi) + unsigned int type; + unsigned int satype; + struct addrinfo *srcs; + struct addrinfo *dsts; + int no_spi; +{ + struct sadb_msg *msg; + char buf[BUFSIZ]; + int l, l0, len; + struct sadb_sa m_sa; + struct sadb_x_sa2 m_sa2; + struct sadb_address m_addr; + struct addrinfo *s, *d; + int n; + int plen; + struct sockaddr *sa; + int salen; + + msg = (struct sadb_msg *)buf; + + if (!srcs || !dsts) + return -1; + + /* fix up length afterwards */ + setkeymsg0(msg, type, satype, 0); + l = sizeof(struct sadb_msg); + + if (!no_spi) { + len = sizeof(struct sadb_sa); + m_sa.sadb_sa_len = PFKEY_UNIT64(len); + m_sa.sadb_sa_exttype = SADB_EXT_SA; + m_sa.sadb_sa_spi = htonl(p_spi); + m_sa.sadb_sa_replay = p_replay; + m_sa.sadb_sa_state = 0; + m_sa.sadb_sa_auth = p_alg_auth; + m_sa.sadb_sa_encrypt = p_alg_enc; + m_sa.sadb_sa_flags = p_ext; + + memcpy(buf + l, &m_sa, len); + l += len; + + len = sizeof(struct sadb_x_sa2); + m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); + m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; + m_sa2.sadb_x_sa2_mode = p_mode; + m_sa2.sadb_x_sa2_reqid = p_reqid; + + memcpy(buf + l, &m_sa2, len); + l += len; + } + + l0 = l; + n = 0; + + /* do it for all src/dst pairs */ + for (s = srcs; s; s = s->ai_next) { + for (d = dsts; d; d = d->ai_next) { + /* rewind pointer */ + l = l0; + + if (s->ai_addr->sa_family != d->ai_addr->sa_family) + continue; + switch (s->ai_addr->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + continue; + } + + /* set src */ + sa = s->ai_addr; + salen = sysdep_sa_len(s->ai_addr); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), sa, salen); + + /* set dst */ + sa = d->ai_addr; + salen = sysdep_sa_len(d->ai_addr); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), sa, salen); + + msg->sadb_msg_len = PFKEY_UNIT64(l); + + sendkeymsg(buf, l); + + n++; + } + } + + if (n == 0) + return -1; + else + return 0; +} + +#ifdef SADB_X_EXT_NAT_T_TYPE +static u_int16_t get_port (struct addrinfo *addr) +{ + struct sockaddr *s = addr->ai_addr; + u_int16_t port = 0; + + switch (s->sa_family) { + case AF_INET: + { + struct sockaddr_in *sin4 = (struct sockaddr_in *)s; + port = ntohs(sin4->sin_port); + break; + } + case AF_INET6: + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s; + port = ntohs(sin6->sin6_port); + break; + } + } + + if (port == 0) + port = DEFAULT_NATT_PORT; + + return port; +} +#endif + +/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ +static int +setkeymsg_add(type, satype, srcs, dsts) + unsigned int type; + unsigned int satype; + struct addrinfo *srcs; + struct addrinfo *dsts; +{ + struct sadb_msg *msg; + char buf[BUFSIZ]; + int l, l0, len; + struct sadb_sa m_sa; + struct sadb_x_sa2 m_sa2; + struct sadb_address m_addr; + struct addrinfo *s, *d; + int n; + int plen; + struct sockaddr *sa; + int salen; + + msg = (struct sadb_msg *)buf; + + if (!srcs || !dsts) + return -1; + + /* fix up length afterwards */ + setkeymsg0(msg, type, satype, 0); + l = sizeof(struct sadb_msg); + + /* set encryption algorithm, if present. */ + if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) { + union { + struct sadb_key key; + struct sadb_ext ext; + } m; + + m.key.sadb_key_len = + PFKEY_UNIT64(sizeof(m.key) + + PFKEY_ALIGN8(p_key_enc_len)); + m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; + m.key.sadb_key_bits = p_key_enc_len * 8; + m.key.sadb_key_reserved = 0; + + setvarbuf(buf, &l, &m.ext, sizeof(m.key), + p_key_enc, p_key_enc_len); + } + + /* set authentication algorithm, if present. */ + if (p_key_auth) { + union { + struct sadb_key key; + struct sadb_ext ext; + } m; + + m.key.sadb_key_len = + PFKEY_UNIT64(sizeof(m.key) + + PFKEY_ALIGN8(p_key_auth_len)); + m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH; + m.key.sadb_key_bits = p_key_auth_len * 8; + m.key.sadb_key_reserved = 0; + + setvarbuf(buf, &l, &m.ext, sizeof(m.key), + p_key_auth, p_key_auth_len); + } + + /* set lifetime for HARD */ + if (p_lt_hard != 0 || p_lb_hard != 0) { + struct sadb_lifetime m_lt; + u_int slen = sizeof(struct sadb_lifetime); + + m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); + m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; + m_lt.sadb_lifetime_allocations = 0; + m_lt.sadb_lifetime_bytes = p_lb_hard; + m_lt.sadb_lifetime_addtime = p_lt_hard; + m_lt.sadb_lifetime_usetime = 0; + + memcpy(buf + l, &m_lt, slen); + l += slen; + } + + /* set lifetime for SOFT */ + if (p_lt_soft != 0 || p_lb_soft != 0) { + struct sadb_lifetime m_lt; + u_int slen = sizeof(struct sadb_lifetime); + + m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); + m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; + m_lt.sadb_lifetime_allocations = 0; + m_lt.sadb_lifetime_bytes = p_lb_soft; + m_lt.sadb_lifetime_addtime = p_lt_soft; + m_lt.sadb_lifetime_usetime = 0; + + memcpy(buf + l, &m_lt, slen); + l += slen; + } + +#ifdef SADB_X_EXT_SEC_CTX + /* Add security context label */ + if (sec_ctx.doi) { + struct sadb_x_sec_ctx m_sec_ctx; + u_int slen = sizeof(struct sadb_x_sec_ctx); + + memset(&m_sec_ctx, 0, slen); + + m_sec_ctx.sadb_x_sec_len = PFKEY_UNIT64(slen + + PFKEY_ALIGN8(sec_ctx.len)); + m_sec_ctx.sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX; + m_sec_ctx.sadb_x_ctx_len = sec_ctx.len; /* bytes */ + m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi; + m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg; + setvarbuf(buf, &l, (struct sadb_ext *)&m_sec_ctx, slen, + (caddr_t)sec_ctx.buf, sec_ctx.len); + } +#endif + + len = sizeof(struct sadb_sa); + m_sa.sadb_sa_len = PFKEY_UNIT64(len); + m_sa.sadb_sa_exttype = SADB_EXT_SA; + m_sa.sadb_sa_spi = htonl(p_spi); + m_sa.sadb_sa_replay = p_replay; + m_sa.sadb_sa_state = 0; + m_sa.sadb_sa_auth = p_alg_auth; + m_sa.sadb_sa_encrypt = p_alg_enc; + m_sa.sadb_sa_flags = p_ext; + + memcpy(buf + l, &m_sa, len); + l += len; + + len = sizeof(struct sadb_x_sa2); + m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); + m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; + m_sa2.sadb_x_sa2_mode = p_mode; + m_sa2.sadb_x_sa2_reqid = p_reqid; + + memcpy(buf + l, &m_sa2, len); + l += len; + +#ifdef SADB_X_EXT_NAT_T_TYPE + if (p_natt_type) { + struct sadb_x_nat_t_type natt_type; + + len = sizeof(struct sadb_x_nat_t_type); + memset(&natt_type, 0, len); + natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len); + natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; + natt_type.sadb_x_nat_t_type_type = p_natt_type; + + memcpy(buf + l, &natt_type, len); + l += len; + + if (p_natt_oa) { + sa = p_natt_oa->ai_addr; + switch (sa->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + return -1; + } + salen = sysdep_sa_len(sa); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), sa, salen); + } + } +#endif + + l0 = l; + n = 0; + + /* do it for all src/dst pairs */ + for (s = srcs; s; s = s->ai_next) { + for (d = dsts; d; d = d->ai_next) { + /* rewind pointer */ + l = l0; + + if (s->ai_addr->sa_family != d->ai_addr->sa_family) + continue; + switch (s->ai_addr->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + continue; + } + + /* set src */ + sa = s->ai_addr; + salen = sysdep_sa_len(s->ai_addr); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), sa, salen); + + /* set dst */ + sa = d->ai_addr; + salen = sysdep_sa_len(d->ai_addr); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), sa, salen); + +#ifdef SADB_X_EXT_NAT_T_TYPE + if (p_natt_type) { + struct sadb_x_nat_t_port natt_port; + + /* NATT_SPORT */ + len = sizeof(struct sadb_x_nat_t_port); + memset(&natt_port, 0, len); + natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len); + natt_port.sadb_x_nat_t_port_exttype = + SADB_X_EXT_NAT_T_SPORT; + natt_port.sadb_x_nat_t_port_port = htons(get_port(s)); + + memcpy(buf + l, &natt_port, len); + l += len; + + /* NATT_DPORT */ + natt_port.sadb_x_nat_t_port_exttype = + SADB_X_EXT_NAT_T_DPORT; + natt_port.sadb_x_nat_t_port_port = htons(get_port(d)); + + memcpy(buf + l, &natt_port, len); + l += len; + } +#endif + msg->sadb_msg_len = PFKEY_UNIT64(l); + + sendkeymsg(buf, l); + + n++; + } + } + + if (n == 0) + return -1; + else + return 0; +} + +static struct addrinfo * +parse_addr(host, port) + char *host; + char *port; +{ + struct addrinfo hints, *res = NULL; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = p_aifamily; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_protocol = IPPROTO_UDP; /*dummy*/ + hints.ai_flags = p_aiflags; + error = getaddrinfo(host, port, &hints, &res); + if (error != 0) { + yyerror(gai_strerror(error)); + return NULL; + } + return res; +} + +static int +fix_portstr(ulproto, spec, sport, dport) + int ulproto; + vchar_t *spec, *sport, *dport; +{ + char sp[16], dp[16]; + int a, b, c, d; + unsigned long u; + + if (spec->buf == NULL) + return 0; + + switch (ulproto) { + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + case IPPROTO_MH: + if (sscanf(spec->buf, "%d,%d", &a, &b) == 2) { + sprintf(sp, "%d", a); + sprintf(dp, "%d", b); + } else if (sscanf(spec->buf, "%d", &a) == 1) { + sprintf(sp, "%d", a); + } else { + yyerror("invalid an upper layer protocol spec"); + return -1; + } + break; + case IPPROTO_GRE: + if (sscanf(spec->buf, "%d.%d.%d.%d", &a, &b, &c, &d) == 4) { + sprintf(sp, "%d", (a << 8) + b); + sprintf(dp, "%d", (c << 8) + d); + } else if (sscanf(spec->buf, "%lu", &u) == 1) { + sprintf(sp, "%d", (int) (u >> 16)); + sprintf(dp, "%d", (int) (u & 0xffff)); + } else { + yyerror("invalid an upper layer protocol spec"); + return -1; + } + break; + } + + free(sport->buf); + sport->buf = strdup(sp); + if (!sport->buf) { + yyerror("insufficient memory"); + return -1; + } + sport->len = strlen(sport->buf); + + free(dport->buf); + dport->buf = strdup(dp); + if (!dport->buf) { + yyerror("insufficient memory"); + return -1; + } + dport->len = strlen(dport->buf); + + return 0; +} + +static int +setvarbuf(buf, off, ebuf, elen, vbuf, vlen) + char *buf; + int *off; + struct sadb_ext *ebuf; + int elen; + const void *vbuf; + int vlen; +{ + memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); + memcpy(buf + *off, (caddr_t)ebuf, elen); + memcpy(buf + *off + elen, vbuf, vlen); + (*off) += PFKEY_ALIGN8(elen + vlen); + + return 0; +} + +void +parse_init() +{ + p_spi = 0; + + p_ext = SADB_X_EXT_CYCSEQ; + p_alg_enc = SADB_EALG_NONE; + p_alg_auth = SADB_AALG_NONE; + p_mode = IPSEC_MODE_ANY; + p_reqid = 0; + p_replay = 0; + p_key_enc_len = p_key_auth_len = 0; + p_key_enc = p_key_auth = 0; + p_lt_hard = p_lt_soft = 0; + p_lb_hard = p_lb_soft = 0; + + memset(&sec_ctx, 0, sizeof(struct security_ctx)); + + p_aiflags = 0; + p_aifamily = PF_UNSPEC; + + /* Clear out any natt OA information */ + if (p_natt_oa) + freeaddrinfo (p_natt_oa); + p_natt_oa = NULL; + p_natt_type = 0; + + return; +} + +void +free_buffer() +{ + /* we got tons of memory leaks in the parser anyways, leave them */ + + return; +} diff --git a/ipsec-tools/src/setkey/parse.h b/ipsec-tools/src/setkey/parse.h new file mode 100644 index 00000000..8f93574d --- /dev/null +++ b/ipsec-tools/src/setkey/parse.h @@ -0,0 +1,201 @@ +/* A Bison parser, made by GNU Bison 2.6.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + 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 3 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef YY_PARSE_H +# define YY_PARSE_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + EOT = 258, + SLASH = 259, + BLCL = 260, + ELCL = 261, + ADD = 262, + GET = 263, + DELETE = 264, + DELETEALL = 265, + FLUSH = 266, + DUMP = 267, + EXIT = 268, + PR_ESP = 269, + PR_AH = 270, + PR_IPCOMP = 271, + PR_ESPUDP = 272, + PR_TCP = 273, + F_PROTOCOL = 274, + F_AUTH = 275, + F_ENC = 276, + F_REPLAY = 277, + F_COMP = 278, + F_RAWCPI = 279, + F_MODE = 280, + MODE = 281, + F_REQID = 282, + F_EXT = 283, + EXTENSION = 284, + NOCYCLICSEQ = 285, + ALG_AUTH = 286, + ALG_AUTH_NOKEY = 287, + ALG_ENC = 288, + ALG_ENC_NOKEY = 289, + ALG_ENC_DESDERIV = 290, + ALG_ENC_DES32IV = 291, + ALG_ENC_OLD = 292, + ALG_COMP = 293, + F_LIFETIME_HARD = 294, + F_LIFETIME_SOFT = 295, + F_LIFEBYTE_HARD = 296, + F_LIFEBYTE_SOFT = 297, + DECSTRING = 298, + QUOTEDSTRING = 299, + HEXSTRING = 300, + STRING = 301, + ANY = 302, + SPDADD = 303, + SPDUPDATE = 304, + SPDDELETE = 305, + SPDDUMP = 306, + SPDFLUSH = 307, + F_POLICY = 308, + PL_REQUESTS = 309, + F_AIFLAGS = 310, + TAGGED = 311, + SECURITY_CTX = 312 + }; +#endif +/* Tokens. */ +#define EOT 258 +#define SLASH 259 +#define BLCL 260 +#define ELCL 261 +#define ADD 262 +#define GET 263 +#define DELETE 264 +#define DELETEALL 265 +#define FLUSH 266 +#define DUMP 267 +#define EXIT 268 +#define PR_ESP 269 +#define PR_AH 270 +#define PR_IPCOMP 271 +#define PR_ESPUDP 272 +#define PR_TCP 273 +#define F_PROTOCOL 274 +#define F_AUTH 275 +#define F_ENC 276 +#define F_REPLAY 277 +#define F_COMP 278 +#define F_RAWCPI 279 +#define F_MODE 280 +#define MODE 281 +#define F_REQID 282 +#define F_EXT 283 +#define EXTENSION 284 +#define NOCYCLICSEQ 285 +#define ALG_AUTH 286 +#define ALG_AUTH_NOKEY 287 +#define ALG_ENC 288 +#define ALG_ENC_NOKEY 289 +#define ALG_ENC_DESDERIV 290 +#define ALG_ENC_DES32IV 291 +#define ALG_ENC_OLD 292 +#define ALG_COMP 293 +#define F_LIFETIME_HARD 294 +#define F_LIFETIME_SOFT 295 +#define F_LIFEBYTE_HARD 296 +#define F_LIFEBYTE_SOFT 297 +#define DECSTRING 298 +#define QUOTEDSTRING 299 +#define HEXSTRING 300 +#define STRING 301 +#define ANY 302 +#define SPDADD 303 +#define SPDUPDATE 304 +#define SPDDELETE 305 +#define SPDDUMP 306 +#define SPDFLUSH 307 +#define F_POLICY 308 +#define PL_REQUESTS 309 +#define F_AIFLAGS 310 +#define TAGGED 311 +#define SECURITY_CTX 312 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 2049 of yacc.c */ +#line 110 "parse.y" + + int num; + unsigned long ulnum; + vchar_t val; + struct addrinfo *res; + + +/* Line 2049 of yacc.c */ +#line 179 "parse.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE yylval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !YY_PARSE_H */ diff --git a/ipsec-tools/src/setkey/parse.y b/ipsec-tools/src/setkey/parse.y new file mode 100644 index 00000000..fa3c45d3 --- /dev/null +++ b/ipsec-tools/src/setkey/parse.y @@ -0,0 +1,1670 @@ +/* $NetBSD: parse.y,v 1.14 2010/12/03 14:32:52 tteras Exp $ */ + +/* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +%{ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include PATH_IPSEC_H +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "libpfkey.h" +#include "vchar.h" +#include "extern.h" + +#define DEFAULT_NATT_PORT 4500 + +#ifndef UDP_ENCAP_ESPINUDP +#define UDP_ENCAP_ESPINUDP 2 +#endif + +#define ATOX(c) \ + (isdigit((int)c) ? (c - '0') : \ + (isupper((int)c) ? (c - 'A' + 10) : (c - 'a' + 10))) + +u_int32_t p_spi; +u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; +u_int32_t p_reqid; +u_int p_key_enc_len, p_key_auth_len; +const char *p_key_enc; +const char *p_key_auth; +time_t p_lt_hard, p_lt_soft; +size_t p_lb_hard, p_lb_soft; + +struct security_ctx { + u_int8_t doi; + u_int8_t alg; + u_int16_t len; + char *buf; +}; + +struct security_ctx sec_ctx; + +static u_int p_natt_type; +static struct addrinfo * p_natt_oa = NULL; + +static int p_aiflags = 0, p_aifamily = PF_UNSPEC; + +static struct addrinfo *parse_addr __P((char *, char *)); +static int fix_portstr __P((int, vchar_t *, vchar_t *, vchar_t *)); +static int setvarbuf __P((char *, int *, struct sadb_ext *, int, + const void *, int)); +void parse_init __P((void)); +void free_buffer __P((void)); + +int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t)); +static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *, + struct addrinfo *, int, struct addrinfo *, int)); +static int setkeymsg_spdaddr_tag __P((unsigned int, char *, vchar_t *)); +static int setkeymsg_addr __P((unsigned int, unsigned int, + struct addrinfo *, struct addrinfo *, int)); +static int setkeymsg_add __P((unsigned int, unsigned int, + struct addrinfo *, struct addrinfo *)); +%} + +%union { + int num; + unsigned long ulnum; + vchar_t val; + struct addrinfo *res; +} + +%token EOT SLASH BLCL ELCL +%token ADD GET DELETE DELETEALL FLUSH DUMP EXIT +%token PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP +%token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI +%token F_MODE MODE F_REQID +%token F_EXT EXTENSION NOCYCLICSEQ +%token ALG_AUTH ALG_AUTH_NOKEY +%token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD +%token ALG_COMP +%token F_LIFETIME_HARD F_LIFETIME_SOFT +%token F_LIFEBYTE_HARD F_LIFEBYTE_SOFT +%token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY + /* SPD management */ +%token SPDADD SPDUPDATE SPDDELETE SPDDUMP SPDFLUSH +%token F_POLICY PL_REQUESTS +%token F_AIFLAGS +%token TAGGED +%token SECURITY_CTX + +%type prefix protocol_spec upper_spec +%type ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY +%type ALG_AUTH ALG_AUTH_NOKEY +%type ALG_COMP +%type PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP +%type EXTENSION MODE +%type DECSTRING +%type PL_REQUESTS portstr key_string +%type policy_requests +%type QUOTEDSTRING HEXSTRING STRING +%type F_AIFLAGS +%type upper_misc_spec policy_spec +%type ipaddr ipandport + +%% +commands + : /*NOTHING*/ + | commands command + { + free_buffer(); + parse_init(); + } + ; + +command + : add_command + | get_command + | delete_command + | deleteall_command + | flush_command + | dump_command + | exit_command + | spdadd_command + | spdupdate_command + | spddelete_command + | spddump_command + | spdflush_command + ; + /* commands concerned with management, there is in tail of this file. */ + + /* add command */ +add_command + : ADD ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT + { + int status; + + status = setkeymsg_add(SADB_ADD, $5, $3, $4); + if (status < 0) + return -1; + } + ; + + /* delete */ +delete_command + : DELETE ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT + { + int status; + + if ($3->ai_next || $4->ai_next) { + yyerror("multiple address specified"); + return -1; + } + if (p_mode != IPSEC_MODE_ANY) + yyerror("WARNING: mode is obsolete"); + + status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0); + if (status < 0) + return -1; + } + ; + + /* deleteall command */ +deleteall_command + : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT + { +#ifndef __linux__ + if (setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1) < 0) + return -1; +#else /* __linux__ */ + /* linux strictly adheres to RFC2367, and returns + * an error if we send an SADB_DELETE request without + * an SPI. Therefore, we must first retrieve a list + * of SPIs for all matching SADB entries, and then + * delete each one separately. */ + u_int32_t *spi; + int i, n; + + spi = sendkeymsg_spigrep($5, $3, $4, &n); + for (i = 0; i < n; i++) { + p_spi = spi[i]; + if (setkeymsg_addr(SADB_DELETE, + $5, $3, $4, 0) < 0) + return -1; + } + free(spi); +#endif /* __linux__ */ + } + ; + + /* get command */ +get_command + : GET ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT + { + int status; + + if (p_mode != IPSEC_MODE_ANY) + yyerror("WARNING: mode is obsolete"); + + status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0); + if (status < 0) + return -1; + } + ; + + /* flush */ +flush_command + : FLUSH protocol_spec EOT + { + struct sadb_msg msg; + setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg)); + sendkeymsg((char *)&msg, sizeof(msg)); + } + ; + + /* dump */ +dump_command + : DUMP protocol_spec EOT + { + struct sadb_msg msg; + setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg)); + sendkeymsg((char *)&msg, sizeof(msg)); + } + ; + +protocol_spec + : /*NOTHING*/ + { + $$ = SADB_SATYPE_UNSPEC; + } + | PR_ESP + { + $$ = SADB_SATYPE_ESP; + if ($1 == 1) + p_ext |= SADB_X_EXT_OLD; + else + p_ext &= ~SADB_X_EXT_OLD; + } + | PR_AH + { + $$ = SADB_SATYPE_AH; + if ($1 == 1) + p_ext |= SADB_X_EXT_OLD; + else + p_ext &= ~SADB_X_EXT_OLD; + } + | PR_IPCOMP + { + $$ = SADB_X_SATYPE_IPCOMP; + } + | PR_ESPUDP + { + $$ = SADB_SATYPE_ESP; + p_ext &= ~SADB_X_EXT_OLD; + p_natt_oa = 0; + p_natt_type = UDP_ENCAP_ESPINUDP; + } + | PR_ESPUDP ipaddr + { + $$ = SADB_SATYPE_ESP; + p_ext &= ~SADB_X_EXT_OLD; + p_natt_oa = $2; + p_natt_type = UDP_ENCAP_ESPINUDP; + } + | PR_TCP + { +#ifdef SADB_X_SATYPE_TCPSIGNATURE + $$ = SADB_X_SATYPE_TCPSIGNATURE; +#endif + } + ; + +spi + : DECSTRING { p_spi = $1; } + | HEXSTRING + { + char *ep; + unsigned long v; + + ep = NULL; + v = strtoul($1.buf, &ep, 16); + if (!ep || *ep) { + yyerror("invalid SPI"); + return -1; + } + if (v & ~0xffffffff) { + yyerror("SPI too big."); + return -1; + } + + p_spi = v; + } + ; + +algorithm_spec + : esp_spec + | ah_spec + | ipcomp_spec + ; + +esp_spec + : F_ENC enc_alg F_AUTH auth_alg + | F_ENC enc_alg + ; + +ah_spec + : F_AUTH auth_alg + ; + +ipcomp_spec + : F_COMP ALG_COMP + { + if ($2 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = $2; + } + | F_COMP ALG_COMP F_RAWCPI + { + if ($2 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = $2; + p_ext |= SADB_X_EXT_RAWCPI; + } + ; + +enc_alg + : ALG_ENC_NOKEY { + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = $1; + + p_key_enc_len = 0; + p_key_enc = ""; + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } + | ALG_ENC key_string { + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = $1; + + p_key_enc_len = $2.len; + p_key_enc = $2.buf; + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } + | ALG_ENC_OLD { + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + yyerror("WARNING: obsolete algorithm"); + p_alg_enc = $1; + + p_key_enc_len = 0; + p_key_enc = ""; + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } + | ALG_ENC_DESDERIV key_string + { + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = $1; + if (p_ext & SADB_X_EXT_OLD) { + yyerror("algorithm mismatched"); + return -1; + } + p_ext |= SADB_X_EXT_DERIV; + + p_key_enc_len = $2.len; + p_key_enc = $2.buf; + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } + | ALG_ENC_DES32IV key_string + { + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = $1; + if (!(p_ext & SADB_X_EXT_OLD)) { + yyerror("algorithm mismatched"); + return -1; + } + p_ext |= SADB_X_EXT_IV4B; + + p_key_enc_len = $2.len; + p_key_enc = $2.buf; + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } + ; + +auth_alg + : ALG_AUTH key_string { + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_auth = $1; + + p_key_auth_len = $2.len; + p_key_auth = $2.buf; +#ifdef SADB_X_AALG_TCP_MD5 + if (p_alg_auth == SADB_X_AALG_TCP_MD5) { + if ((p_key_auth_len < 1) || + (p_key_auth_len > 80)) + return -1; + } else +#endif + { + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, + p_alg_auth, + PFKEY_UNUNIT64(p_key_auth_len)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } + } + | ALG_AUTH_NOKEY { + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_auth = $1; + + p_key_auth_len = 0; + p_key_auth = NULL; + } + ; + +key_string + : QUOTEDSTRING + { + $$ = $1; + } + | HEXSTRING + { + caddr_t pp_key; + caddr_t bp; + caddr_t yp = $1.buf; + int l; + + l = strlen(yp) % 2 + strlen(yp) / 2; + if ((pp_key = malloc(l)) == 0) { + yyerror("not enough core"); + return -1; + } + memset(pp_key, 0, l); + + bp = pp_key; + if (strlen(yp) % 2) { + *bp = ATOX(yp[0]); + yp++, bp++; + } + while (*yp) { + *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); + yp += 2, bp++; + } + + $$.len = l; + $$.buf = pp_key; + } + ; + +extension_spec + : /*NOTHING*/ + | extension_spec extension + ; + +extension + : F_EXT EXTENSION { p_ext |= $2; } + | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } + | F_MODE MODE { p_mode = $2; } + | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } + | F_REQID DECSTRING { p_reqid = $2; } + | F_REPLAY DECSTRING + { + if ((p_ext & SADB_X_EXT_OLD) != 0) { + yyerror("replay prevention cannot be used with " + "ah/esp-old"); + return -1; + } + p_replay = $2; + } + | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } + | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } + | F_LIFEBYTE_HARD DECSTRING { p_lb_hard = $2; } + | F_LIFEBYTE_SOFT DECSTRING { p_lb_soft = $2; } + | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING { + sec_ctx.doi = $2; + sec_ctx.alg = $3; + sec_ctx.len = $4.len+1; + sec_ctx.buf = $4.buf; + } + ; + + /* definition about command for SPD management */ + /* spdadd */ +spdadd_command + /* XXX merge with spdupdate ??? */ + : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT + { + int status; + struct addrinfo *src, *dst; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + last_msg_type = SADB_X_SPDADD; +#endif + + /* fixed port fields if ulp is icmp */ + if (fix_portstr($9, &$10, &$5, &$8)) + return -1; + + src = parse_addr($3.buf, $5.buf); + dst = parse_addr($6.buf, $8.buf); + if (!src || !dst) { + /* yyerror is already called */ + return -1; + } + if (src->ai_next || dst->ai_next) { + yyerror("multiple address specified"); + freeaddrinfo(src); + freeaddrinfo(dst); + return -1; + } + + status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$12, + src, $4, dst, $7); + freeaddrinfo(src); + freeaddrinfo(dst); + if (status < 0) + return -1; + } + | SPDADD TAGGED QUOTEDSTRING policy_spec EOT + { + int status; + + status = setkeymsg_spdaddr_tag(SADB_X_SPDADD, + $3.buf, &$4); + if (status < 0) + return -1; + } + ; + +spdupdate_command + /* XXX merge with spdadd ??? */ + : SPDUPDATE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT + { + int status; + struct addrinfo *src, *dst; + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + last_msg_type = SADB_X_SPDUPDATE; +#endif + + /* fixed port fields if ulp is icmp */ + if (fix_portstr($9, &$10, &$5, &$8)) + return -1; + + src = parse_addr($3.buf, $5.buf); + dst = parse_addr($6.buf, $8.buf); + if (!src || !dst) { + /* yyerror is already called */ + return -1; + } + if (src->ai_next || dst->ai_next) { + yyerror("multiple address specified"); + freeaddrinfo(src); + freeaddrinfo(dst); + return -1; + } + + status = setkeymsg_spdaddr(SADB_X_SPDUPDATE, $9, &$12, + src, $4, dst, $7); + freeaddrinfo(src); + freeaddrinfo(dst); + if (status < 0) + return -1; + } + | SPDUPDATE TAGGED QUOTEDSTRING policy_spec EOT + { + int status; + + status = setkeymsg_spdaddr_tag(SADB_X_SPDUPDATE, + $3.buf, &$4); + if (status < 0) + return -1; + } + ; + +spddelete_command + : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT + { + int status; + struct addrinfo *src, *dst; + + /* fixed port fields if ulp is icmp */ + if (fix_portstr($9, &$10, &$5, &$8)) + return -1; + + src = parse_addr($3.buf, $5.buf); + dst = parse_addr($6.buf, $8.buf); + if (!src || !dst) { + /* yyerror is already called */ + return -1; + } + if (src->ai_next || dst->ai_next) { + yyerror("multiple address specified"); + freeaddrinfo(src); + freeaddrinfo(dst); + return -1; + } + + status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$12, + src, $4, dst, $7); + freeaddrinfo(src); + freeaddrinfo(dst); + if (status < 0) + return -1; + } + ; + +spddump_command: + SPDDUMP EOT + { + struct sadb_msg msg; + setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC, + sizeof(msg)); + sendkeymsg((char *)&msg, sizeof(msg)); + } + ; + +spdflush_command + : + SPDFLUSH EOT + { + struct sadb_msg msg; + setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC, + sizeof(msg)); + sendkeymsg((char *)&msg, sizeof(msg)); + } + ; + +ipaddropts + : /* nothing */ + | ipaddropts ipaddropt + ; + +ipaddropt + : F_AIFLAGS + { + char *p; + + for (p = $1.buf + 1; *p; p++) + switch (*p) { + case '4': + p_aifamily = AF_INET; + break; +#ifdef INET6 + case '6': + p_aifamily = AF_INET6; + break; +#endif + case 'n': + p_aiflags = AI_NUMERICHOST; + break; + default: + yyerror("invalid flag"); + return -1; + } + } + ; + +ipaddr + : STRING + { + $$ = parse_addr($1.buf, NULL); + if ($$ == NULL) { + /* yyerror already called by parse_addr */ + return -1; + } + } + ; + +ipandport + : STRING + { + $$ = parse_addr($1.buf, NULL); + if ($$ == NULL) { + /* yyerror already called by parse_addr */ + return -1; + } + } + | STRING portstr + { + $$ = parse_addr($1.buf, $2.buf); + if ($$ == NULL) { + /* yyerror already called by parse_addr */ + return -1; + } + } + ; + +prefix + : /*NOTHING*/ { $$ = -1; } + | SLASH DECSTRING { $$ = $2; } + ; + +portstr + : /*NOTHING*/ + { + $$.buf = strdup("0"); + if (!$$.buf) { + yyerror("insufficient memory"); + return -1; + } + $$.len = strlen($$.buf); + } + | BLCL ANY ELCL + { + $$.buf = strdup("0"); + if (!$$.buf) { + yyerror("insufficient memory"); + return -1; + } + $$.len = strlen($$.buf); + } + | BLCL DECSTRING ELCL + { + char buf[20]; + snprintf(buf, sizeof(buf), "%lu", $2); + $$.buf = strdup(buf); + if (!$$.buf) { + yyerror("insufficient memory"); + return -1; + } + $$.len = strlen($$.buf); + } + | BLCL STRING ELCL + { + $$ = $2; + } + ; + +upper_spec + : DECSTRING { $$ = $1; } + | ANY { $$ = IPSEC_ULPROTO_ANY; } + | PR_TCP { + $$ = IPPROTO_TCP; + } + | STRING + { + struct protoent *ent; + + ent = getprotobyname($1.buf); + if (ent) + $$ = ent->p_proto; + else { + if (strcmp("icmp6", $1.buf) == 0) { + $$ = IPPROTO_ICMPV6; + } else if(strcmp("ip4", $1.buf) == 0) { + $$ = IPPROTO_IPV4; + } else { + yyerror("invalid upper layer protocol"); + return -1; + } + } + endprotoent(); + } + ; + +upper_misc_spec + : /*NOTHING*/ + { + $$.buf = NULL; + $$.len = 0; + } + | STRING + { + $$.buf = strdup($1.buf); + if (!$$.buf) { + yyerror("insufficient memory"); + return -1; + } + $$.len = strlen($$.buf); + } + ; + +context_spec + : /* NOTHING */ + | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING { + sec_ctx.doi = $2; + sec_ctx.alg = $3; + sec_ctx.len = $4.len+1; + sec_ctx.buf = $4.buf; + } + ; + +policy_spec + : F_POLICY policy_requests + { + char *policy; +#ifdef HAVE_PFKEY_POLICY_PRIORITY + struct sadb_x_policy *xpl; +#endif + + policy = ipsec_set_policy($2.buf, $2.len); + if (policy == NULL) { + yyerror(ipsec_strerror()); + return -1; + } + + $$.buf = policy; + $$.len = ipsec_get_policylen(policy); + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + xpl = (struct sadb_x_policy *) $$.buf; + last_priority = xpl->sadb_x_policy_priority; +#endif + } + ; + +policy_requests + : PL_REQUESTS { $$ = $1; } + ; + + /* exit */ +exit_command + : EXIT EOT + { + exit_now = 1; + YYACCEPT; + } + ; +%% + +int +setkeymsg0(msg, type, satype, l) + struct sadb_msg *msg; + unsigned int type; + unsigned int satype; + size_t l; +{ + + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = type; + msg->sadb_msg_errno = 0; + msg->sadb_msg_satype = satype; + msg->sadb_msg_reserved = 0; + msg->sadb_msg_seq = 0; + msg->sadb_msg_pid = getpid(); + msg->sadb_msg_len = PFKEY_UNIT64(l); + return 0; +} + +/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ +static int +setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) + unsigned int type; + unsigned int upper; + vchar_t *policy; + struct addrinfo *srcs; + int splen; + struct addrinfo *dsts; + int dplen; +{ + struct sadb_msg *msg; + char buf[BUFSIZ]; + int l, l0; + struct sadb_address m_addr; + struct addrinfo *s, *d; + int n; + int plen; + struct sockaddr *sa; + int salen; + struct sadb_x_policy *sp; +#ifdef HAVE_POLICY_FWD + struct sadb_x_ipsecrequest *ps = NULL; + int saved_level, saved_id = 0; +#endif + + msg = (struct sadb_msg *)buf; + + if (!srcs || !dsts) + return -1; + + /* fix up length afterwards */ + setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); + l = sizeof(struct sadb_msg); + + sp = (struct sadb_x_policy*) (buf + l); + memcpy(buf + l, policy->buf, policy->len); + l += policy->len; + + l0 = l; + n = 0; + + /* do it for all src/dst pairs */ + for (s = srcs; s; s = s->ai_next) { + for (d = dsts; d; d = d->ai_next) { + /* rewind pointer */ + l = l0; + + if (s->ai_addr->sa_family != d->ai_addr->sa_family) + continue; + switch (s->ai_addr->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + continue; + } + + /* set src */ + sa = s->ai_addr; + salen = sysdep_sa_len(s->ai_addr); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + m_addr.sadb_address_proto = upper; + m_addr.sadb_address_prefixlen = + (splen >= 0 ? splen : plen); + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), (caddr_t)sa, salen); + + /* set dst */ + sa = d->ai_addr; + salen = sysdep_sa_len(d->ai_addr); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; + m_addr.sadb_address_proto = upper; + m_addr.sadb_address_prefixlen = + (dplen >= 0 ? dplen : plen); + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), sa, salen); +#ifdef SADB_X_EXT_SEC_CTX + /* Add security context label */ + if (sec_ctx.doi) { + struct sadb_x_sec_ctx m_sec_ctx; + u_int slen = sizeof(struct sadb_x_sec_ctx); + + memset(&m_sec_ctx, 0, slen); + + m_sec_ctx.sadb_x_sec_len = + PFKEY_UNIT64(slen + PFKEY_ALIGN8(sec_ctx.len)); + + m_sec_ctx.sadb_x_sec_exttype = + SADB_X_EXT_SEC_CTX; + m_sec_ctx.sadb_x_ctx_len = sec_ctx.len;/*bytes*/ + m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi; + m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg; + setvarbuf(buf, &l, + (struct sadb_ext *)&m_sec_ctx, slen, + (caddr_t)sec_ctx.buf, sec_ctx.len); + } +#endif + msg->sadb_msg_len = PFKEY_UNIT64(l); + + sendkeymsg(buf, l); + +#ifdef HAVE_POLICY_FWD + /* create extra call for FWD policy */ + if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) { + sp->sadb_x_policy_dir = IPSEC_DIR_FWD; + ps = (struct sadb_x_ipsecrequest*) (sp+1); + + /* if request level is unique, change it to + * require for fwd policy */ + /* XXX: currently, only first policy is updated + * only. Update following too... */ + saved_level = ps->sadb_x_ipsecrequest_level; + if (saved_level == IPSEC_LEVEL_UNIQUE) { + saved_id = ps->sadb_x_ipsecrequest_reqid; + ps->sadb_x_ipsecrequest_reqid=0; + ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE; + } + + sendkeymsg(buf, l); + /* restoring for next message */ + sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND; + if (saved_level == IPSEC_LEVEL_UNIQUE) { + ps->sadb_x_ipsecrequest_reqid = saved_id; + ps->sadb_x_ipsecrequest_level = saved_level; + } + } +#endif + + n++; + } + } + + if (n == 0) + return -1; + else + return 0; +} + +static int +setkeymsg_spdaddr_tag(type, tag, policy) + unsigned int type; + char *tag; + vchar_t *policy; +{ + struct sadb_msg *msg; + char buf[BUFSIZ]; + int l, l0; +#ifdef SADB_X_EXT_TAG + struct sadb_x_tag m_tag; +#endif + int n; + + msg = (struct sadb_msg *)buf; + + /* fix up length afterwards */ + setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); + l = sizeof(struct sadb_msg); + + memcpy(buf + l, policy->buf, policy->len); + l += policy->len; + + l0 = l; + n = 0; + +#ifdef SADB_X_EXT_TAG + memset(&m_tag, 0, sizeof(m_tag)); + m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag)); + m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG; + if (strlcpy(m_tag.sadb_x_tag_name, tag, + sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name)) + return -1; + memcpy(buf + l, &m_tag, sizeof(m_tag)); + l += sizeof(m_tag); +#endif + + msg->sadb_msg_len = PFKEY_UNIT64(l); + + sendkeymsg(buf, l); + + return 0; +} + +/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ +static int +setkeymsg_addr(type, satype, srcs, dsts, no_spi) + unsigned int type; + unsigned int satype; + struct addrinfo *srcs; + struct addrinfo *dsts; + int no_spi; +{ + struct sadb_msg *msg; + char buf[BUFSIZ]; + int l, l0, len; + struct sadb_sa m_sa; + struct sadb_x_sa2 m_sa2; + struct sadb_address m_addr; + struct addrinfo *s, *d; + int n; + int plen; + struct sockaddr *sa; + int salen; + + msg = (struct sadb_msg *)buf; + + if (!srcs || !dsts) + return -1; + + /* fix up length afterwards */ + setkeymsg0(msg, type, satype, 0); + l = sizeof(struct sadb_msg); + + if (!no_spi) { + len = sizeof(struct sadb_sa); + m_sa.sadb_sa_len = PFKEY_UNIT64(len); + m_sa.sadb_sa_exttype = SADB_EXT_SA; + m_sa.sadb_sa_spi = htonl(p_spi); + m_sa.sadb_sa_replay = p_replay; + m_sa.sadb_sa_state = 0; + m_sa.sadb_sa_auth = p_alg_auth; + m_sa.sadb_sa_encrypt = p_alg_enc; + m_sa.sadb_sa_flags = p_ext; + + memcpy(buf + l, &m_sa, len); + l += len; + + len = sizeof(struct sadb_x_sa2); + m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); + m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; + m_sa2.sadb_x_sa2_mode = p_mode; + m_sa2.sadb_x_sa2_reqid = p_reqid; + + memcpy(buf + l, &m_sa2, len); + l += len; + } + + l0 = l; + n = 0; + + /* do it for all src/dst pairs */ + for (s = srcs; s; s = s->ai_next) { + for (d = dsts; d; d = d->ai_next) { + /* rewind pointer */ + l = l0; + + if (s->ai_addr->sa_family != d->ai_addr->sa_family) + continue; + switch (s->ai_addr->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + continue; + } + + /* set src */ + sa = s->ai_addr; + salen = sysdep_sa_len(s->ai_addr); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), sa, salen); + + /* set dst */ + sa = d->ai_addr; + salen = sysdep_sa_len(d->ai_addr); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), sa, salen); + + msg->sadb_msg_len = PFKEY_UNIT64(l); + + sendkeymsg(buf, l); + + n++; + } + } + + if (n == 0) + return -1; + else + return 0; +} + +#ifdef SADB_X_EXT_NAT_T_TYPE +static u_int16_t get_port (struct addrinfo *addr) +{ + struct sockaddr *s = addr->ai_addr; + u_int16_t port = 0; + + switch (s->sa_family) { + case AF_INET: + { + struct sockaddr_in *sin4 = (struct sockaddr_in *)s; + port = ntohs(sin4->sin_port); + break; + } + case AF_INET6: + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s; + port = ntohs(sin6->sin6_port); + break; + } + } + + if (port == 0) + port = DEFAULT_NATT_PORT; + + return port; +} +#endif + +/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ +static int +setkeymsg_add(type, satype, srcs, dsts) + unsigned int type; + unsigned int satype; + struct addrinfo *srcs; + struct addrinfo *dsts; +{ + struct sadb_msg *msg; + char buf[BUFSIZ]; + int l, l0, len; + struct sadb_sa m_sa; + struct sadb_x_sa2 m_sa2; + struct sadb_address m_addr; + struct addrinfo *s, *d; + int n; + int plen; + struct sockaddr *sa; + int salen; + + msg = (struct sadb_msg *)buf; + + if (!srcs || !dsts) + return -1; + + /* fix up length afterwards */ + setkeymsg0(msg, type, satype, 0); + l = sizeof(struct sadb_msg); + + /* set encryption algorithm, if present. */ + if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) { + union { + struct sadb_key key; + struct sadb_ext ext; + } m; + + m.key.sadb_key_len = + PFKEY_UNIT64(sizeof(m.key) + + PFKEY_ALIGN8(p_key_enc_len)); + m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; + m.key.sadb_key_bits = p_key_enc_len * 8; + m.key.sadb_key_reserved = 0; + + setvarbuf(buf, &l, &m.ext, sizeof(m.key), + p_key_enc, p_key_enc_len); + } + + /* set authentication algorithm, if present. */ + if (p_key_auth) { + union { + struct sadb_key key; + struct sadb_ext ext; + } m; + + m.key.sadb_key_len = + PFKEY_UNIT64(sizeof(m.key) + + PFKEY_ALIGN8(p_key_auth_len)); + m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH; + m.key.sadb_key_bits = p_key_auth_len * 8; + m.key.sadb_key_reserved = 0; + + setvarbuf(buf, &l, &m.ext, sizeof(m.key), + p_key_auth, p_key_auth_len); + } + + /* set lifetime for HARD */ + if (p_lt_hard != 0 || p_lb_hard != 0) { + struct sadb_lifetime m_lt; + u_int slen = sizeof(struct sadb_lifetime); + + m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); + m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; + m_lt.sadb_lifetime_allocations = 0; + m_lt.sadb_lifetime_bytes = p_lb_hard; + m_lt.sadb_lifetime_addtime = p_lt_hard; + m_lt.sadb_lifetime_usetime = 0; + + memcpy(buf + l, &m_lt, slen); + l += slen; + } + + /* set lifetime for SOFT */ + if (p_lt_soft != 0 || p_lb_soft != 0) { + struct sadb_lifetime m_lt; + u_int slen = sizeof(struct sadb_lifetime); + + m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); + m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; + m_lt.sadb_lifetime_allocations = 0; + m_lt.sadb_lifetime_bytes = p_lb_soft; + m_lt.sadb_lifetime_addtime = p_lt_soft; + m_lt.sadb_lifetime_usetime = 0; + + memcpy(buf + l, &m_lt, slen); + l += slen; + } + +#ifdef SADB_X_EXT_SEC_CTX + /* Add security context label */ + if (sec_ctx.doi) { + struct sadb_x_sec_ctx m_sec_ctx; + u_int slen = sizeof(struct sadb_x_sec_ctx); + + memset(&m_sec_ctx, 0, slen); + + m_sec_ctx.sadb_x_sec_len = PFKEY_UNIT64(slen + + PFKEY_ALIGN8(sec_ctx.len)); + m_sec_ctx.sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX; + m_sec_ctx.sadb_x_ctx_len = sec_ctx.len; /* bytes */ + m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi; + m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg; + setvarbuf(buf, &l, (struct sadb_ext *)&m_sec_ctx, slen, + (caddr_t)sec_ctx.buf, sec_ctx.len); + } +#endif + + len = sizeof(struct sadb_sa); + m_sa.sadb_sa_len = PFKEY_UNIT64(len); + m_sa.sadb_sa_exttype = SADB_EXT_SA; + m_sa.sadb_sa_spi = htonl(p_spi); + m_sa.sadb_sa_replay = p_replay; + m_sa.sadb_sa_state = 0; + m_sa.sadb_sa_auth = p_alg_auth; + m_sa.sadb_sa_encrypt = p_alg_enc; + m_sa.sadb_sa_flags = p_ext; + + memcpy(buf + l, &m_sa, len); + l += len; + + len = sizeof(struct sadb_x_sa2); + m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); + m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; + m_sa2.sadb_x_sa2_mode = p_mode; + m_sa2.sadb_x_sa2_reqid = p_reqid; + + memcpy(buf + l, &m_sa2, len); + l += len; + +#ifdef SADB_X_EXT_NAT_T_TYPE + if (p_natt_type) { + struct sadb_x_nat_t_type natt_type; + + len = sizeof(struct sadb_x_nat_t_type); + memset(&natt_type, 0, len); + natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len); + natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; + natt_type.sadb_x_nat_t_type_type = p_natt_type; + + memcpy(buf + l, &natt_type, len); + l += len; + + if (p_natt_oa) { + sa = p_natt_oa->ai_addr; + switch (sa->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + return -1; + } + salen = sysdep_sa_len(sa); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), sa, salen); + } + } +#endif + + l0 = l; + n = 0; + + /* do it for all src/dst pairs */ + for (s = srcs; s; s = s->ai_next) { + for (d = dsts; d; d = d->ai_next) { + /* rewind pointer */ + l = l0; + + if (s->ai_addr->sa_family != d->ai_addr->sa_family) + continue; + switch (s->ai_addr->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + continue; + } + + /* set src */ + sa = s->ai_addr; + salen = sysdep_sa_len(s->ai_addr); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), sa, salen); + + /* set dst */ + sa = d->ai_addr; + salen = sysdep_sa_len(d->ai_addr); + m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + + PFKEY_ALIGN8(salen)); + m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; + m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, + sizeof(m_addr), sa, salen); + +#ifdef SADB_X_EXT_NAT_T_TYPE + if (p_natt_type) { + struct sadb_x_nat_t_port natt_port; + + /* NATT_SPORT */ + len = sizeof(struct sadb_x_nat_t_port); + memset(&natt_port, 0, len); + natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len); + natt_port.sadb_x_nat_t_port_exttype = + SADB_X_EXT_NAT_T_SPORT; + natt_port.sadb_x_nat_t_port_port = htons(get_port(s)); + + memcpy(buf + l, &natt_port, len); + l += len; + + /* NATT_DPORT */ + natt_port.sadb_x_nat_t_port_exttype = + SADB_X_EXT_NAT_T_DPORT; + natt_port.sadb_x_nat_t_port_port = htons(get_port(d)); + + memcpy(buf + l, &natt_port, len); + l += len; + } +#endif + msg->sadb_msg_len = PFKEY_UNIT64(l); + + sendkeymsg(buf, l); + + n++; + } + } + + if (n == 0) + return -1; + else + return 0; +} + +static struct addrinfo * +parse_addr(host, port) + char *host; + char *port; +{ + struct addrinfo hints, *res = NULL; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = p_aifamily; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_protocol = IPPROTO_UDP; /*dummy*/ + hints.ai_flags = p_aiflags; + error = getaddrinfo(host, port, &hints, &res); + if (error != 0) { + yyerror(gai_strerror(error)); + return NULL; + } + return res; +} + +static int +fix_portstr(ulproto, spec, sport, dport) + int ulproto; + vchar_t *spec, *sport, *dport; +{ + char sp[16], dp[16]; + int a, b, c, d; + unsigned long u; + + if (spec->buf == NULL) + return 0; + + switch (ulproto) { + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + case IPPROTO_MH: + if (sscanf(spec->buf, "%d,%d", &a, &b) == 2) { + sprintf(sp, "%d", a); + sprintf(dp, "%d", b); + } else if (sscanf(spec->buf, "%d", &a) == 1) { + sprintf(sp, "%d", a); + } else { + yyerror("invalid an upper layer protocol spec"); + return -1; + } + break; + case IPPROTO_GRE: + if (sscanf(spec->buf, "%d.%d.%d.%d", &a, &b, &c, &d) == 4) { + sprintf(sp, "%d", (a << 8) + b); + sprintf(dp, "%d", (c << 8) + d); + } else if (sscanf(spec->buf, "%lu", &u) == 1) { + sprintf(sp, "%d", (int) (u >> 16)); + sprintf(dp, "%d", (int) (u & 0xffff)); + } else { + yyerror("invalid an upper layer protocol spec"); + return -1; + } + break; + } + + free(sport->buf); + sport->buf = strdup(sp); + if (!sport->buf) { + yyerror("insufficient memory"); + return -1; + } + sport->len = strlen(sport->buf); + + free(dport->buf); + dport->buf = strdup(dp); + if (!dport->buf) { + yyerror("insufficient memory"); + return -1; + } + dport->len = strlen(dport->buf); + + return 0; +} + +static int +setvarbuf(buf, off, ebuf, elen, vbuf, vlen) + char *buf; + int *off; + struct sadb_ext *ebuf; + int elen; + const void *vbuf; + int vlen; +{ + memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); + memcpy(buf + *off, (caddr_t)ebuf, elen); + memcpy(buf + *off + elen, vbuf, vlen); + (*off) += PFKEY_ALIGN8(elen + vlen); + + return 0; +} + +void +parse_init() +{ + p_spi = 0; + + p_ext = SADB_X_EXT_CYCSEQ; + p_alg_enc = SADB_EALG_NONE; + p_alg_auth = SADB_AALG_NONE; + p_mode = IPSEC_MODE_ANY; + p_reqid = 0; + p_replay = 0; + p_key_enc_len = p_key_auth_len = 0; + p_key_enc = p_key_auth = 0; + p_lt_hard = p_lt_soft = 0; + p_lb_hard = p_lb_soft = 0; + + memset(&sec_ctx, 0, sizeof(struct security_ctx)); + + p_aiflags = 0; + p_aifamily = PF_UNSPEC; + + /* Clear out any natt OA information */ + if (p_natt_oa) + freeaddrinfo (p_natt_oa); + p_natt_oa = NULL; + p_natt_type = 0; + + return; +} + +void +free_buffer() +{ + /* we got tons of memory leaks in the parser anyways, leave them */ + + return; +} diff --git a/ipsec-tools/src/setkey/sample-policy01.cf b/ipsec-tools/src/setkey/sample-policy01.cf new file mode 100644 index 00000000..42c16b2f --- /dev/null +++ b/ipsec-tools/src/setkey/sample-policy01.cf @@ -0,0 +1,20 @@ +# +# This is for basic policy test on loopback. +# + +spdflush; +spdadd 127.0.0.1 127.0.0.1 icmp + -P out ipsec + esp/transport//require ; +spdadd ::1 ::1 icmp6 + -P out ipsec + esp/transport//require ; + +flush; +add 127.0.0.1 127.0.0.1 esp 0x1000 + -m transport + -E des-cbc "kamekame"; +add ::1 ::1 esp 0x1001 + -m transport + -E des-cbc "hagehage"; +flush; diff --git a/ipsec-tools/src/setkey/sample-policy02.cf b/ipsec-tools/src/setkey/sample-policy02.cf new file mode 100644 index 00000000..8c5134a8 --- /dev/null +++ b/ipsec-tools/src/setkey/sample-policy02.cf @@ -0,0 +1,43 @@ +# +# this is test configuration for unique policy on loopback. +# + +spdflush; +# connection to 9999 encrypted, reverse no encrypted. +spdadd ::1 ::1[9999] tcp + -P out ipsec + esp/transport//unique:2 ; + +# Session encrypted. Inbound policy check takes place non-strictly. +spdadd ::1 ::1[9998] tcp + -P out ipsec + esp/transport//unique:1 ; +spdadd ::1[9998] ::1 tcp + -P in ipsec + esp/transport//unique:2 ; +spdadd ::1[9998] ::1 tcp + -P out ipsec + esp/transport//unique:1 ; + +# Cause new SA to be acquired. +spdadd ::1 ::1[9997] tcp + -P out ipsec + esp/transport//unique ; + +# Used proper SA. +spdadd ::1 ::1[9996] tcp + -P out ipsec + esp/transport//require ; + +# reqid will be updated by kernel. +spdadd ::1 ::1[9995] tcp + -P out ipsec + esp/transport//unique:28000 ; + +flush; +add ::1 ::1 esp 0x1001 + -u 1 + -E des-cbc "kamekame"; +add ::1 ::1 esp 0x1002 + -u 2 + -E des-cbc "hogehoge"; diff --git a/ipsec-tools/src/setkey/sample.cf b/ipsec-tools/src/setkey/sample.cf new file mode 100644 index 00000000..c64fd366 --- /dev/null +++ b/ipsec-tools/src/setkey/sample.cf @@ -0,0 +1,217 @@ +# Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +# There are sample scripts for IPsec configuration by manual keying. +# A security association is uniquely identified by a triple consisting +# of a Security Parameter Index (SPI), an IP Destination Address, and a +# security protocol (AH or ESP) identifier. You must take care of these +# parameters when you configure by manual keying. + +# ESP transport mode is recommended for TCP port number 110 between +# Host-A and Host-B. Encryption algorithm is blowfish-cbc whose key +# is "kamekame", and authentication algorithm is hmac-sha1 whose key +# is "this is the test key". +# +# ============ ESP ============ +# | | +# Host-A Host-B +# fec0::10 -------------------- fec0::11 +# +# At Host-A and Host-B, +spdadd fec0::10[any] fec0::11[110] tcp -P out ipsec + esp/transport//use ; +spdadd fec0::11[110] fec0::10[any] tcp -P in ipsec + esp/transport//use ; +add fec0::10 fec0::11 esp 0x10001 + -m transport + -E blowfish-cbc "kamekame" + -A hmac-sha1 "this is the test key" ; +add fec0::11 fec0::10 esp 0x10002 + -m transport + -E blowfish-cbc "kamekame" + -A hmac-sha1 "this is the test key" ; + +# "[any]" is wildcard of port number. Note that "[0]" is the number of +# zero in port number. + +# Security protocol is old AH tunnel mode, i.e. RFC1826, with keyed-md5 +# whose key is "this is the test" as authentication algorithm. +# That protocol takes place between Gateway-A and Gateway-B. +# +# ======= AH ======= +# | | +# Network-A Gateway-A Gateway-B Network-B +# 10.0.1.0/24 ---- 172.16.0.1 ----- 172.16.0.2 ---- 10.0.2.0/24 +# +# At Gateway-A: +spdadd 10.0.1.0/24 10.0.2.0/24 any -P out ipsec + ah/tunnel/172.16.0.1-172.16.0.2/require ; +spdadd 10.0.2.0/24 10.0.1.0/24 any -P in ipsec + ah/tunnel/172.16.0.2-172.16.0.1/require ; +add 172.16.0.1 172.16.0.2 ah-old 0x10003 + -m any + -A keyed-md5 "this is the test" ; +add 172.16.0.2 172.16.0.1 ah-old 0x10004 + -m any + -A keyed-md5 "this is the test" ; + +# If port number field is omitted such above then "[any]" is employed. +# -m specifies the mode of SA to be used. "-m any" means wildcard of +# mode of security protocol. You can use this SAs for both tunnel and +# transport mode. + +# At Gateway-B. Attention to the selector and peer's IP address for tunnel. +spdadd 10.0.2.0/24 10.0.1.0/24 any -P out ipsec + ah/tunnel/172.16.0.2-172.16.0.1/require ; +spdadd 10.0.1.0/24 10.0.2.0/24 any -P in ipsec + ah/tunnel/172.16.0.1-172.16.0.2/require ; +add 172.16.0.1 172.16.0.2 ah-old 0x10003 + -m tunnel + -A keyed-md5 "this is the test" ; +add 172.16.0.2 172.16.0.1 ah-old 0x10004 + -m tunnel + -A keyed-md5 "this is the test" ; + +# AH transport mode followed by ESP tunnel mode is required between +# Gateway-A and Gateway-B. +# Encryption algorithm is 3des-cbc, and authentication algorithm for ESP +# is hmac-sha1. Authentication algorithm for AH is hmac-md5. +# +# ========== AH ========= +# | ======= ESP ===== | +# | | | | +# Network-A Gateway-A Gateway-B Network-B +# fec0:0:0:1::/64 --- fec0:0:0:1::1 ---- fec0:0:0:2::1 --- fec0:0:0:2::/64 +# +# At Gateway-A: +spdadd fec0:0:0:1::/64 fec0:0:0:2::/64 any -P out ipsec + esp/tunnel/fec0:0:0:1::1-fec0:0:0:2::1/require + ah/transport//require ; +spdadd fec0:0:0:2::/64 fec0:0:0:1::/64 any -P in ipsec + esp/tunnel/fec0:0:0:2::1-fec0:0:0:1::1/require + ah/transport//require ; +add fec0:0:0:1::1 fec0:0:0:2::1 esp 0x10001 + -m tunnel + -E 3des-cbc "kamekame12341234kame1234" + -A hmac-sha1 "this is the test key" ; +add fec0:0:0:1::1 fec0:0:0:2::1 ah 0x10001 + -m transport + -A hmac-md5 "this is the test" ; +add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10001 + -m tunnel + -E 3des-cbc "kamekame12341234kame1234" + -A hmac-sha1 "this is the test key" ; +add fec0:0:0:2::1 fec0:0:0:1::1 ah 0x10001 + -m transport + -A hmac-md5 "this is the test" ; + +# ESP tunnel mode is required between Host-A and Gateway-A. +# Encryption algorithm is cast128-cbc, and authentication algorithm +# for ESP is hmac-sha1. +# ESP transport mode is recommended between Host-A and Host-B. +# Encryption algorithm is rc5-cbc, and authentication algorithm +# for ESP is hmac-md5. +# +# ================== ESP ================= +# | ======= ESP ======= | +# | | | | +# Host-A Gateway-A Host-B +# fec0:0:0:1::1 ---- fec0:0:0:2::1 ---- fec0:0:0:2::2 +# +# At Host-A: +spdadd fec0:0:0:1::1[any] fec0:0:0:2::2[80] tcp -P out ipsec + esp/transport//use + esp/tunnel/fec0:0:0:1::1-fec0:0:0:2::1/require ; +spdadd fec0:0:0:2::1[80] fec0:0:0:1::1[any] tcp -P in ipsec + esp/transport//use + esp/tunnel/fec0:0:0:2::1-fec0:0:0:1::1/require ; +add fec0:0:0:1::1 fec0:0:0:2::2 esp 0x10001 + -m transport + -E cast128-cbc "12341234" + -A hmac-sha1 "this is the test key" ; +add fec0:0:0:1::1 fec0:0:0:2::1 esp 0x10002 + -E rc5-cbc "kamekame" + -A hmac-md5 "this is the test" ; +add fec0:0:0:2::2 fec0:0:0:1::1 esp 0x10003 + -m transport + -E cast128-cbc "12341234" + -A hmac-sha1 "this is the test key" ; +add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10004 + -E rc5-cbc "kamekame" + -A hmac-md5 "this is the test" ; + +# By "get" command, you can get a entry of either SP or SA. +get fec0:0:0:1::1 fec0:0:0:2::2 ah 0x10004 ; + +# Also delete command, you can delete a entry of either SP or SA. +spddelete fec0:0:0:1::/64 fec0:0:0:2::/64 any -P out; +delete fec0:0:0:1::1 fec0:0:0:2::2 ah 0x10004 ; + +# By dump command, you can dump all entry of either SP or SA. +dump ; +spddump ; +dump esp ; +flush esp ; + +# By flush command, you can flush all entry of either SP or SA. +flush ; +spdflush ; + +# "flush" and "dump" commands can specify a security protocol. +dump esp ; +flush ah ; + +# XXX +add ::1 ::1 esp 10001 -m transport -E null ; +add ::1 ::1 esp 10002 -m transport -E des-deriv "12341234" ; +add ::1 ::1 esp-old 10003 -m transport -E des-32iv "12341234" ; +add ::1 ::1 esp 10004 -m transport -E null -A null ; +add ::1 ::1 esp 10005 -m transport -E null -A hmac-md5 "1234123412341234" ; +add ::1 ::1 esp 10006 -m tunnel -E null -A hmac-sha1 "12341234123412341234" ; +add ::1 ::1 esp 10007 -m transport -E null -A keyed-md5 "1234123412341234" ; +add ::1 ::1 esp 10008 -m any -E null -A keyed-sha1 "12341234123412341234" ; +add ::1 ::1 esp 10009 -m transport -E des-cbc "testtest" ; +add ::1 ::1 esp 10010 -m transport -E 3des-cbc "testtest12341234testtest" ; +add ::1 ::1 esp 10011 -m tunnel -E cast128-cbc "testtest1234" ; +add ::1 ::1 esp 10012 -m tunnel -E blowfish-cbc "testtest1234" ; +add ::1 ::1 esp 10013 -m tunnel -E rc5-cbc "testtest1234" ; +add ::1 ::1 esp 10014 -m any -E rc5-cbc "testtest1234" ; +add ::1 ::1 esp 10015 -m transport -f zero-pad -E null ; +add ::1 ::1 esp 10016 -m tunnel -f random-pad -r 8 -lh 100 -ls 80 -E null ; +add ::1 ::1 esp 10017 -m transport -f seq-pad -f nocyclic-seq -E null ; +add ::1 ::1 esp 10018 -m transport -E null ; +#add ::1 ::1 ah 20000 -m transport -A null ; +add ::1 ::1 ah 20001 -m any -A hmac-md5 "1234123412341234"; +add ::1 ::1 ah 20002 -m tunnel -A hmac-sha1 "12341234123412341234"; +add ::1 ::1 ah 20003 -m transport -A keyed-md5 "1234123412341234"; +add ::1 ::1 ah-old 20004 -m transport -A keyed-md5 "1234123412341234"; +add ::1 ::1 ah 20005 -m transport -A keyed-sha1 "12341234123412341234"; +#add ::1 ::1 ipcomp 30000 -C oui ; +add ::1 ::1 ipcomp 30001 -C deflate ; +#add ::1 ::1 ipcomp 30002 -C lzs ; + +# enjoy. diff --git a/ipsec-tools/src/setkey/scriptdump.pl b/ipsec-tools/src/setkey/scriptdump.pl new file mode 100644 index 00000000..f5b9f254 --- /dev/null +++ b/ipsec-tools/src/setkey/scriptdump.pl @@ -0,0 +1,55 @@ +#! @LOCALPREFIX@/bin/perl + +if ($< != 0) { + print STDERR "must be root to invoke this\n"; + exit 1; +} + +$mode = 'add'; +while ($i = shift @ARGV) { + if ($i eq '-d') { + $mode = 'delete'; + } else { + print STDERR "usage: scriptdump [-d]\n"; + exit 1; + } +} + +open(IN, "setkey -D |") || die; +foreach $_ () { + if (/^[^\t]/) { + ($src, $dst) = split(/\s+/, $_); + } elsif (/^\t(esp|ah) mode=(\S+) spi=(\d+).*reqid=(\d+)/) { + ($proto, $ipsecmode, $spi, $reqid) = ($1, $2, $3, $4); + } elsif (/^\tE: (\S+) (.*)/) { + $ealgo = $1; + $ekey = $2; + $ekey =~ s/\s//g; + $ekey =~ s/^/0x/g; + } elsif (/^\tA: (\S+) (.*)/) { + $aalgo = $1; + $akey = $2; + $akey =~ s/\s//g; + $akey =~ s/^/0x/g; + } elsif (/^\tseq=(0x\d+) replay=(\d+) flags=(0x\d+) state=/) { + print "$mode $src $dst $proto $spi"; + $replay = $2; + print " -u $reqid" if $reqid; + if ($mode eq 'add') { + print " -m $ipsecmode -r $replay" if $replay; + if ($proto eq 'esp') { + print " -E $ealgo $ekey" if $ealgo; + print " -A $aalgo $akey" if $aalgo; + } elsif ($proto eq 'ah') { + print " -A $aalgo $akey" if $aalgo; + } + } + print ";\n"; + + $src = $dst = $upper = $proxy = ''; + $ealgo = $ekey = $aalgo = $akey = ''; + } +} +close(IN); + +exit 0; diff --git a/ipsec-tools/src/setkey/setkey.8 b/ipsec-tools/src/setkey/setkey.8 new file mode 100644 index 00000000..76356790 --- /dev/null +++ b/ipsec-tools/src/setkey/setkey.8 @@ -0,0 +1,837 @@ +.\" $NetBSD: setkey.8,v 1.26 2010/12/03 14:32:52 tteras Exp $ +.\" +.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the project nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd June 4, 2010 +.Dt SETKEY 8 +.Os +.\" +.Sh NAME +.Nm setkey +.Nd manually manipulate the IPsec SA/SP database +.\" +.Sh SYNOPSIS +.Nm setkey +.Op Fl knrv +.Ar file ... +.Nm setkey +.Op Fl knrv +.Fl c +.Nm setkey +.Op Fl krv +.Fl f Ar filename +.Nm setkey +.Op Fl aklPrv +.Fl D +.Nm setkey +.Op Fl Pvp +.Fl F +.Nm setkey +.Op Fl H +.Fl x +.Nm setkey +.Op Fl ?V +.\" +.Sh DESCRIPTION +.Nm +adds, updates, dumps, or flushes +Security Association Database (SAD) entries +as well as Security Policy Database (SPD) entries in the kernel. +.Pp +.Nm +takes a series of operations from standard input +.Po +if invoked with +.Fl c +.Pc +or the file named +.Ar filename +.Po +if invoked with +.Fl f Ar filename +.Pc . +.Bl -tag -width Ds +.It (no flag) +Dump the SAD entries or SPD entries contained in the specified +.Ar file . +.It Fl ? +Print short help. +.It Fl a +.Nm +usually does not display dead SAD entries with +.Fl D . +If +.Fl a +is also specified, the dead SAD entries will be displayed as well. +A dead SAD entry is one that has expired but remains in the +system because it is referenced by some SPD entries. +.It Fl D +Dump the SAD entries. +If +.Fl P +is also specified, the SPD entries are dumped. +If +.Fl p +is specified, the ports are displayed. +.It Fl F +Flush the SAD entries. +If +.Fl P +is also specified, the SPD entries are flushed. +.It Fl H +Add hexadecimal dump in +.Fl x +mode. +.It Fl h +On +.Nx , +synonym for +.Fl H . +On other systems, synonym for +.Fl ? . +.It Fl k +Use semantics used in kernel. +Available only in Linux. +See also +.Fl r . +.It Fl l +Loop forever with short output on +.Fl D . +.It Fl n +No action. +The program will check validity of the input, but no changes to +the SPD will be made. +.It Fl r +Use semantics described in IPsec RFCs. +This mode is default. +For details see section +.Sx RFC vs Linux kernel semantics . +Available only in Linux. +See also +.Fl k . +.It Fl x +Loop forever and dump all the messages transmitted to the +.Dv PF_KEY +socket. +.Fl xx +prints the unformatted timestamps. +.It Fl V +Print version string. +.It Fl v +Be verbose. +The program will dump messages exchanged on the +.Dv PF_KEY +socket, including messages sent from other processes to the kernel. +.El +.Ss Configuration syntax +With +.Fl c +or +.Fl f +on the command line, +.Nm +accepts the following configuration syntax. +Lines starting with hash signs +.Pq Sq # +are treated as comment lines. +.Bl -tag -width Ds +.It Li add Oo Fl 46n Oc Ar src Ar dst Ar protocol Ar spi \ +Oo Ar extensions Oc Ar algorithm ... Li ; +Add an SAD entry. +.Li add +can fail for multiple reasons, including when the key length does +not match the specified algorithm. +.\" +.It Li get Oo Fl 46n Oc Ar src Ar dst Ar protocol Ar spi Li ; +Show an SAD entry. +.\" +.It Li delete Oo Fl 46n Oc Ar src Ar dst Ar protocol Ar spi Li ; +Remove an SAD entry. +.\" +.It Li deleteall Oo Fl 46n Oc Ar src Ar dst Ar protocol Li ; +Remove all SAD entries that match the specification. +.\" +.It Li flush Oo Ar protocol Oc Li ; +Clear all SAD entries matched by the options. +.Fl F +on the command line achieves the same functionality. +.\" +.It Li dump Oo Ar protocol Oc Li ; +Dumps all SAD entries matched by the options. +.Fl D +on the command line achieves the same functionality. +.\" +.It Li spdadd Oo Fl 46n Oc Ar src_range Ar dst_range Ar upperspec \ +Ar label Ar policy Li ; +Add an SPD entry. +.\" +.It Li spdadd tagged Ar tag Ar policy Li ; +Add an SPD entry based on a PF tag. +.Ar tag +must be a string surrounded by double quotes. +.\" +.It Li spdupdate Oo Fl 46n Oc Ar src_range Ar dst_range Ar upperspec \ +Ar label Ar policy Li ; +Updates an SPD entry. +.\" +.It Li spdupdate tagged Ar tag Ar policy Li ; +Update an SPD entry based on a PF tag. +.Ar tag +must be a string surrounded by double quotes. +.\" +.It Li spddelete Oo Fl 46n Oc Ar src_range Ar dst_range Ar upperspec \ +Fl P Ar direction Li ; +Delete an SPD entry. +.\" +.It Li spdflush Li ; +Clear all SPD entries. +.Fl FP +on the command line achieves the same functionality. +.\" +.It Li spddump Li ; +Dumps all SPD entries. +.Fl DP +on the command line achieves the same functionality. +.El +.\" +.Pp +Meta-arguments are as follows: +.Pp +.Bl -tag -compact -width Ds +.It Ar src +.It Ar dst +Source/destination of the secure communication is specified as +an IPv4/v6 address, and an optional port number between square +brackets. +.Nm +can resolve a FQDN into numeric addresses. +If the FQDN resolves into multiple addresses, +.Nm +will install multiple SAD/SPD entries into the kernel +by trying all possible combinations. +.Fl 4 , +.Fl 6 , +and +.Fl n +restrict the address resolution of FQDN in certain ways. +.Fl 4 +and +.Fl 6 +restrict results into IPv4/v6 addresses only, respectively. +.Fl n +avoids FQDN resolution and requires addresses to be numeric addresses. +.\" +.Pp +.It Ar protocol +.Ar protocol +is one of following: +.Bl -tag -width Fl -compact +.It Li esp +ESP based on rfc2406 +.It Li esp-old +ESP based on rfc1827 +.It Li ah +AH based on rfc2402 +.It Li ah-old +AH based on rfc1826 +.It Li ipcomp +IPComp +.It Li tcp +TCP-MD5 based on rfc2385 +.El +.\" +.Pp +.It Ar spi +Security Parameter Index +.Pq SPI +for the SAD and the SPD. +.Ar spi +must be a decimal number, or a hexadecimal number with a +.Dq Li 0x +prefix. +SPI values between 0 and 255 are reserved for future use by IANA +and cannot be used. +TCP-MD5 associations must use 0x1000 and therefore only have per-host +granularity at this time. +.\" +.Pp +.It Ar extensions +take some of the following: +.Bl -tag -width Fl -compact +.\" +.It Fl m Ar mode +Specify a security protocol mode for use. +.Ar mode +is one of following: +.Li transport , tunnel , +or +.Li any . +The default value is +.Li any . +.\" +.It Fl r Ar size +Specify window size of bytes for replay prevention. +.Ar size +must be decimal number in 32-bit word. +If +.Ar size +is zero or not specified, replay checks don't take place. +.\" +.It Fl u Ar id +Specify the identifier of the policy entry in the SPD. +See +.Ar policy . +.\" +.It Fl f Ar pad_option +defines the content of the ESP padding. +.Ar pad_option +is one of following: +.Bl -tag -width random-pad -compact +.It Li zero-pad +All the paddings are zero. +.It Li random-pad +A series of randomized values are used. +.It Li seq-pad +A series of sequential increasing numbers started from 1 are used. +.El +.\" +.It Fl f Li nocyclic-seq +Don't allow cyclic sequence numbers. +.\" +.It Fl lh Ar time +.It Fl ls Ar time +Specify hard/soft life time duration of the SA measured in seconds. +.\" +.It Fl bh Ar bytes +.It Fl bs Ar bytes +Specify hard/soft life time duration of the SA measured in bytes transported. +.\" +.It Fl ctx Ar doi Ar algorithm Ar context-name +Specify an access control label. +The access control label is interpreted by the LSM (e.g., SELinux). +Ultimately, it enables MAC on network communications. +.Bl -tag -width Fl -compact +.It Ar doi +The domain of interpretation, which is used by the +IKE daemon to identify the domain in which negotiation takes place. +.It Ar algorithm +Indicates the LSM for which the label is generated (e.g., SELinux). +.It Ar context-name +The string representation of the label that is interpreted by the LSM. +.El +.El +.\" +.Pp +.It Ar algorithm +.Bl -tag -width Fl -compact +.It Fl E Ar ealgo Ar key +Specify an encryption algorithm +.Ar ealgo +for ESP. +.It Fl E Ar ealgo Ar key Fl A Ar aalgo Ar key +Specify an encryption algorithm +.Ar ealgo , +as well as a payload authentication algorithm +.Ar aalgo , +for ESP. +.It Fl A Ar aalgo Ar key +Specify an authentication algorithm for AH. +.It Fl C Ar calgo Op Fl R +Specify a compression algorithm for IPComp. +If +.Fl R +is specified, the +.Ar spi +field value will be used as the IPComp CPI +.Pq compression parameter index +on wire as-is. +If +.Fl R +is not specified, +the kernel will use well-known CPI on wire, and +.Ar spi +field will be used only as an index for kernel internal usage. +.El +.Pp +.Ar key +must be a double-quoted character string, or a series of hexadecimal +digits preceded by +.Dq Li 0x . +.Pp +Possible values for +.Ar ealgo , +.Ar aalgo , +and +.Ar calgo +are specified in the +.Sx Algorithms +sections. +.\" +.Pp +.It Ar src_range +.It Ar dst_range +These select the communications that should be secured by IPsec. +They can be an IPv4/v6 address or an IPv4/v6 address range, and +may be accompanied by a TCP/UDP port specification. +This takes the following form: +.Bd -literal -offset +.Ar address +.Ar address/prefixlen +.Ar address[port] +.Ar address/prefixlen[port] +.Ed +.Pp +.Ar prefixlen +and +.Ar port +must be decimal numbers. +The square brackets around +.Ar port +are really necessary, +they are not man page meta-characters. +For FQDN resolution, the rules applicable to +.Ar src +and +.Ar dst +apply here as well. +.\" +.Pp +.It Ar upperspec +Upper-layer protocol to be used. +You can use one of the words in +.Pa /etc/protocols +as +.Ar upperspec , +or +.Li icmp6 , +.Li ip4 , +.Li gre , +or +.Li any . +.Li any +stands for +.Dq any protocol . +You can also use the protocol number. +Additional specification can be placed after the protocol name for +some protocols. +You can specify a type and/or a code of ICMP or ICMPv6. +The type is separated from a code by single comma and the code must +always be specified. +GRE key can be specified in dotted-quad format or as plain number. +When a zero is specified, the kernel deals with it as a wildcard. +Note that the kernel can not distinguish a wildcard from an ICPMv6 +type of zero. +.Pp +For example, the following means that the policy doesn't require IPsec +for any inbound Neighbor Solicitation. +.Dl spdadd ::/0 ::/0 icmp6 135,0 -P in none ; +.Pp +A second example of requiring transport mode encryption of specific +GRE tunnel: +.Dl spdadd 0.0.0.0 0.0.0.0 gre 1234 ipsec esp/transport//require ; +.Pp +.Em Note : +.Ar upperspec +does not work against forwarding case at this moment, +as it requires extra reassembly at the forwarding node +.Pq not implemented at this moment . +There are many protocols in +.Pa /etc/protocols , +but all protocols except of TCP, UDP, GRE, and ICMP may not be suitable +to use with IPsec. +You have to consider carefully what to use. +.\" +.Pp +.It Ar label +.Ar label +is the access control label for the policy. +This label is interpreted by the LSM (e.g., SELinux). +Ultimately, it enables MAC on network communications. +When a policy contains an access control label, SAs +negotiated with this policy will contain the label. +Its format: +.Bl -tag -width Fl -compact +.\" +.It Fl ctx Ar doi Ar algorithm Ar context-name +.Bl -tag -width Fl -compact +.It Ar doi +The domain of interpretation, which is used by the +IKE daemon to identify the domain in which negotiation takes place. +.It Ar algorithm +Indicates the LSM for which the label is generated (e.g., SELinux). +.It Ar context-name +The string representation of the label that is interpreted by the LSM. +.El +.El +.\" +.Pp +.It Ar policy +.Ar policy +is in one of the following three formats: +.Bl -item -compact +.It +.Fl P Ar direction [priority specification] Li discard +.It +.Fl P Ar direction [priority specification] Li none +.It +.Fl P Ar direction [priority specification] Li ipsec +.Ar protocol/mode/src-dst/level Op ... +.El +.Pp +You must specify the direction of its policy as +.Ar direction . +Either +.Ar out , +.Ar in , +or +.Ar fwd +can be used. +.Pp +.Ar priority specification +is used to control the placement of the policy within the SPD. +Policy position is determined by +a signed integer where higher priorities indicate the policy is placed +closer to the beginning of the list and lower priorities indicate the +policy is placed closer to the end of the list. +Policies with equal priorities are added at the end of groups +of such policies. +.Pp +Priority can only +be specified when setkey has been compiled against kernel headers that +support policy priorities (Linux \*[Gt]= 2.6.6). +If the kernel does not support priorities, a warning message will +be printed the first time a priority specification is used. +Policy priority takes one of the following formats: +.Bl -tag -width "discard" +.It Ar {priority,prio} offset +.Ar offset +is an integer in the range from \-2147483647 to 214783648. +.It Ar {priority,prio} base {+,\-} offset +.Ar base +is either +.Li low (\-1073741824) , +.Li def (0) , +or +.Li high (1073741824) +.Pp +.Ar offset +is an unsigned integer. +It can be up to 1073741824 for +positive offsets, and up to 1073741823 for negative offsets. +.El +.Pp +.Li discard +means the packet matching indexes will be discarded. +.Li none +means that IPsec operation will not take place onto the packet. +.Li ipsec +means that IPsec operation will take place onto the packet. +.Pp +The +.Ar protocol/mode/src-dst/level +part specifies the rule how to process the packet. +Either +.Li ah , +.Li esp , +or +.Li ipcomp +must be used as +.Ar protocol . +.Ar mode +is either +.Li transport +or +.Li tunnel . +If +.Ar mode +is +.Li tunnel , +you must specify the end-point addresses of the SA as +.Ar src +and +.Ar dst +with +.Sq - +between these addresses, which is used to specify the SA to use. +If +.Ar mode +is +.Li transport , +both +.Ar src +and +.Ar dst +can be omitted. +.Ar level +is to be one of the following: +.Li default , use , require , +or +.Li unique . +If the SA is not available in every level, the kernel will +ask the key exchange daemon to establish a suitable SA. +.Li default +means the kernel consults the system wide default for the protocol +you specified, e.g. the +.Li esp_trans_deflev +sysctl variable, when the kernel processes the packet. +.Li use +means that the kernel uses an SA if it's available, +otherwise the kernel keeps normal operation. +.Li require +means SA is required whenever the kernel sends a packet matched +with the policy. +.Li unique +is the same as +.Li require ; +in addition, it allows the policy to match the unique out-bound SA. +You just specify the policy level +.Li unique , +.Xr racoon 8 +will configure the SA for the policy. +If you configure the SA by manual keying for that policy, +you can put a decimal number as the policy identifier after +.Li unique +separated by a colon +.Sq \&: +like: +.Li unique:number +in order to bind this policy to the SA. +.Li number +must be between 1 and 32767. +It corresponds to +.Ar extensions Fl u +of the manual SA configuration. +When you want to use SA bundle, you can define multiple rules. +For example, if an IP header was followed by an AH header followed +by an ESP header followed by an upper layer protocol header, the +rule would be: +.Dl esp/transport//require ah/transport//require ; +The rule order is very important. +.Pp +When NAT-T is enabled in the kernel, policy matching for ESP over +UDP packets may be done on endpoint addresses and port +(this depends on the system. +System that do not perform the port check cannot support +multiple endpoints behind the same NAT). +When using ESP over UDP, you can specify port numbers in the endpoint +addresses to get the correct matching. +Here is an example: +.Bd -literal -offset +spdadd 10.0.11.0/24[any] 10.0.11.33/32[any] any \-P out ipsec + esp/tunnel/192.168.0.1[4500]-192.168.1.2[30000]/require ; + +.Ed +These ports must be left unspecified (which defaults to 0) for +anything other than ESP over UDP. +They can be displayed in SPD dump using +.Nm +.Fl DPp . +.Pp +Note that +.Dq Li discard +and +.Dq Li none +are not in the syntax described in +.Xr ipsec_set_policy 3 . +There are a few differences in the syntax. +See +.Xr ipsec_set_policy 3 +for detail. +.El +.\" +.Ss Algorithms +The following list shows the supported algorithms. +.Sy protocol +and +.Sy algorithm +are almost orthogonal. +These authentication algorithms can be used as +.Ar aalgo +in +.Fl A Ar aalgo +of the +.Ar protocol +parameter: +.Pp +.Bd -literal -offset indent +algorithm keylen (bits) +hmac-md5 128 ah: rfc2403 + 128 ah-old: rfc2085 +hmac-sha1 160 ah: rfc2404 + 160 ah-old: 128bit ICV (no document) +keyed-md5 128 ah: 96bit ICV (no document) + 128 ah-old: rfc1828 +keyed-sha1 160 ah: 96bit ICV (no document) + 160 ah-old: 128bit ICV (no document) +null 0 to 2048 for debugging +hmac-sha256 256 ah: 96bit ICV + (draft-ietf-ipsec-ciph-sha-256-00) + 256 ah-old: 128bit ICV (no document) +hmac-sha384 384 ah: 96bit ICV (no document) + 384 ah-old: 128bit ICV (no document) +hmac-sha512 512 ah: 96bit ICV (no document) + 512 ah-old: 128bit ICV (no document) +hmac-ripemd160 160 ah: 96bit ICV (RFC2857) + ah-old: 128bit ICV (no document) +aes-xcbc-mac 128 ah: 96bit ICV (RFC3566) + 128 ah-old: 128bit ICV (no document) +tcp-md5 8 to 640 tcp: rfc2385 +.Ed +.Pp +These encryption algorithms can be used as +.Ar ealgo +in +.Fl E Ar ealgo +of the +.Ar protocol +parameter: +.Pp +.Bd -literal -offset indent +algorithm keylen (bits) +des-cbc 64 esp-old: rfc1829, esp: rfc2405 +3des-cbc 192 rfc2451 +null 0 to 2048 rfc2410 +blowfish-cbc 40 to 448 rfc2451 +cast128-cbc 40 to 128 rfc2451 +des-deriv 64 ipsec-ciph-des-derived-01 +3des-deriv 192 no document +rijndael-cbc 128/192/256 rfc3602 +twofish-cbc 0 to 256 draft-ietf-ipsec-ciph-aes-cbc-01 +aes-ctr 160/224/288 draft-ietf-ipsec-ciph-aes-ctr-03 +camellia-cbc 128/192/256 rfc4312 +.Ed +.Pp +Note that the first 128 bits of a key for +.Li aes-ctr +will be used as AES key, and the remaining 32 bits will be used as nonce. +.Pp +These compression algorithms can be used as +.Ar calgo +in +.Fl C Ar calgo +of the +.Ar protocol +parameter: +.Pp +.Bd -literal -offset indent +algorithm +deflate rfc2394 +.Ed +.\" +.Ss RFC vs Linux kernel semantics +The Linux kernel uses the +.Ar fwd +policy instead of the +.Ar in +policy for packets what are forwarded through that particular box. +.Pp +In +.Ar kernel +mode, +.Nm +manages and shows policies and SAs exactly as they are stored in the kernel. +.Pp +In +.Ar RFC +mode, +.Nm +.Bl -item +.It +creates +.Ar fwd +policies for every +.Ar in +policy inserted +.It +(not implemented yet) filters out all +.Ar fwd +policies +.El +.Sh RETURN VALUES +The command exits with 0 on success, and non-zero on errors. +.\" +.Sh EXAMPLES +.Bd -literal -offset +add 3ffe:501:4819::1 3ffe:501:481d::1 esp 123457 + \-E des-cbc 0x3ffe05014819ffff ; + +add \-6 myhost.example.com yourhost.example.com ah 123456 + \-A hmac-sha1 "AH SA configuration!" ; + +add 10.0.11.41 10.0.11.33 esp 0x10001 + \-E des-cbc 0x3ffe05014819ffff + \-A hmac-md5 "authentication!!" ; + +get 3ffe:501:4819::1 3ffe:501:481d::1 ah 123456 ; + +flush ; + +dump esp ; + +spdadd 10.0.11.41/32[21] 10.0.11.33/32[any] any + \-P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require ; + +add 10.1.10.34 10.1.10.36 tcp 0x1000 \-A tcp-md5 "TCP-MD5 BGP secret" ; + +add 10.0.11.41 10.0.11.33 esp 0x10001 + \-ctx 1 1 "system_u:system_r:unconfined_t:SystemLow-SystemHigh" + \-E des-cbc 0x3ffe05014819ffff; + +spdadd 10.0.11.41 10.0.11.33 any + \-ctx 1 1 "system_u:system_r:unconfined_t:SystemLow-SystemHigh" + \-P out ipsec esp/transport//require ; +.Ed +.\" +.Sh SEE ALSO +.Xr ipsec_set_policy 3 , +.Xr racoon 8 , +.Xr sysctl 8 +.Rs +.%T "Changed manual key configuration for IPsec" +.%U "http://www.kame.net/newsletter/19991007/" +.%D "October 1999" +.Re +.\" +.Sh HISTORY +The +.Nm +command first appeared in the WIDE Hydrangea IPv6 protocol stack +kit. +The command was completely re-designed in June 1998. +.\" +.Sh BUGS +.Nm +should report and handle syntax errors better. +.Pp +For IPsec gateway configuration, +.Ar src_range +and +.Ar dst_range +with TCP/UDP port numbers does not work, as the gateway does not +reassemble packets +.Pq it cannot inspect upper-layer headers . diff --git a/ipsec-tools/src/setkey/setkey.c b/ipsec-tools/src/setkey/setkey.c new file mode 100644 index 00000000..c400faa6 --- /dev/null +++ b/ipsec-tools/src/setkey/setkey.c @@ -0,0 +1,1062 @@ +/* $NetBSD: setkey.c,v 1.14 2009/08/06 04:44:43 tteras Exp $ */ + +/* $KAME: setkey.c,v 1.36 2003/09/24 23:52:51 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_READLINE +#include +#include +#endif + +#include "config.h" +#include "libpfkey.h" +#include "package_version.h" +#define extern /* so that variables in extern.h are not extern... */ +#include "extern.h" + +#define strlcpy(d,s,l) (strncpy(d,s,l), (d)[(l)-1] = '\0') + +void usage __P((int)); +int main __P((int, char **)); +int get_supported __P((void)); +void sendkeyshort __P((u_int)); +void promisc __P((void)); +int postproc __P((struct sadb_msg *, int)); +int verifypriority __P((struct sadb_msg *m)); +int fileproc __P((const char *)); +const char *numstr __P((int)); +void shortdump_hdr __P((void)); +void shortdump __P((struct sadb_msg *)); +static void printdate __P((void)); +static int32_t gmt2local __P((time_t)); +void stdin_loop __P((void)); + +#define MODE_SCRIPT 1 +#define MODE_CMDDUMP 2 +#define MODE_CMDFLUSH 3 +#define MODE_PROMISC 4 +#define MODE_STDIN 5 + +int so; + +int f_forever = 0; +int f_all = 0; +int f_verbose = 0; +int f_mode = 0; +int f_cmddump = 0; +int f_policy = 0; +int f_hexdump = 0; +int f_tflag = 0; +int f_notreally = 0; +int f_withports = 0; +#ifdef HAVE_POLICY_FWD +int f_rfcmode = 1; +#define RK_OPTS "rk" +#else +int f_rkwarn = 0; +#define RK_OPTS "" +static void rkwarn(void); +static void +rkwarn(void) +{ + if (!f_rkwarn) { + f_rkwarn = 1; + printf("warning: -r and -k options are not supported in this environment\n"); + } +} + +#endif +static time_t thiszone; + +void +usage(int only_version) +{ + printf("setkey @(#) %s (%s)\n", TOP_PACKAGE_STRING, TOP_PACKAGE_URL); + if (! only_version) { + printf("usage: setkey [-v" RK_OPTS "] file ...\n"); + printf(" setkey [-nv" RK_OPTS "] -c\n"); + printf(" setkey [-nv" RK_OPTS "] -f filename\n"); + printf(" setkey [-Palpv" RK_OPTS "] -D\n"); + printf(" setkey [-Pv] -F\n"); + printf(" setkey [-H] -x\n"); + printf(" setkey [-V] [-h]\n"); + } + exit(1); +} + +int +main(argc, argv) + int argc; + char **argv; +{ + FILE *fp = stdin; + int c; + + if (argc == 1) { + usage(0); + /* NOTREACHED */ + } + + thiszone = gmt2local(0); + + while ((c = getopt(argc, argv, "acdf:HlnvxDFPphVrk?")) != -1) { + switch (c) { + case 'c': + f_mode = MODE_STDIN; +#ifdef HAVE_READLINE + /* disable filename completion */ + rl_bind_key('\t', rl_insert); +#endif + break; + case 'f': + f_mode = MODE_SCRIPT; + if ((fp = fopen(optarg, "r")) == NULL) { + err(1, "fopen"); + /*NOTREACHED*/ + } + break; + case 'D': + f_mode = MODE_CMDDUMP; + break; + case 'F': + f_mode = MODE_CMDFLUSH; + break; + case 'a': + f_all = 1; + break; + case 'l': + f_forever = 1; + break; + case 'n': + f_notreally = 1; + break; +#ifdef __NetBSD__ + case 'h': +#endif + case 'H': + f_hexdump = 1; + break; + case 'x': + f_mode = MODE_PROMISC; + f_tflag++; + break; + case 'P': + f_policy = 1; + break; + case 'p': + f_withports = 1; + break; + case 'v': + f_verbose = 1; + break; + case 'r': +#ifdef HAVE_POLICY_FWD + f_rfcmode = 1; +#else + rkwarn(); +#endif + break; + case 'k': +#ifdef HAVE_POLICY_FWD + f_rfcmode = 0; +#else + rkwarn(); +#endif + break; + case 'V': + usage(1); + break; + /*NOTREACHED*/ +#ifndef __NetBSD__ + case 'h': +#endif + case '?': + default: + usage(0); + /*NOTREACHED*/ + } + } + + argc -= optind; + argv += optind; + + if (argc > 0) { + while (argc--) + if (fileproc(*argv++) < 0) { + err(1, "%s", argv[-1]); + /*NOTREACHED*/ + } + exit(0); + } + + so = pfkey_open(); + if (so < 0) { + perror("pfkey_open"); + exit(1); + } + + switch (f_mode) { + case MODE_CMDDUMP: + sendkeyshort(f_policy ? SADB_X_SPDDUMP : SADB_DUMP); + break; + case MODE_CMDFLUSH: + sendkeyshort(f_policy ? SADB_X_SPDFLUSH: SADB_FLUSH); + break; + case MODE_SCRIPT: + if (get_supported() < 0) { + errx(1, "%s", ipsec_strerror()); + /*NOTREACHED*/ + } + if (parse(&fp)) + exit (1); + break; + case MODE_STDIN: + if (get_supported() < 0) { + errx(1, "%s", ipsec_strerror()); + /*NOTREACHED*/ + } + stdin_loop(); + break; + case MODE_PROMISC: + promisc(); + /*NOTREACHED*/ + default: + usage(0); + /*NOTREACHED*/ + } + + exit(0); +} + +int +get_supported() +{ + + if (pfkey_send_register(so, SADB_SATYPE_UNSPEC) < 0) + return -1; + + if (pfkey_recv_register(so) < 0) + return -1; + + return (0); +} + +void +stdin_loop() +{ + char line[1024], *semicolon, *comment; + size_t linelen = 0; + + memset (line, 0, sizeof(line)); + + parse_init(); + while (1) { +#ifdef HAVE_READLINE + char *rbuf; + rbuf = readline (""); + if (! rbuf) + break; +#else + char rbuf[1024]; + rbuf[0] = '\0'; + if (fgets(rbuf, sizeof(rbuf), stdin) == NULL) + break; + if (rbuf[strlen(rbuf)-1] == '\n') + rbuf[strlen(rbuf)-1] = '\0'; +#endif + comment = strchr(rbuf, '#'); + if (comment) + *comment = '\0'; + + if (!rbuf[0]) + continue; + + linelen += snprintf (&line[linelen], sizeof(line) - linelen, + "%s%s", linelen > 0 ? " " : "", rbuf); + + semicolon = strchr(line, ';'); + while (semicolon) { + char saved_char = *++semicolon; + *semicolon = '\0'; +#ifdef HAVE_READLINE + add_history (line); +#endif + +#ifdef HAVE_PFKEY_POLICY_PRIORITY + last_msg_type = -1; /* invalid message type */ +#endif + + parse_string (line); + if (exit_now) + return; + if (saved_char) { + *semicolon = saved_char; + linelen = strlen (semicolon); + memmove (line, semicolon, linelen + 1); + semicolon = strchr(line, ';'); + } + else { + semicolon = NULL; + linelen = 0; + } + } + } +} + +void +sendkeyshort(type) + u_int type; +{ + struct sadb_msg msg; + + msg.sadb_msg_version = PF_KEY_V2; + msg.sadb_msg_type = type; + msg.sadb_msg_errno = 0; + msg.sadb_msg_satype = SADB_SATYPE_UNSPEC; + msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg)); + msg.sadb_msg_reserved = 0; + msg.sadb_msg_seq = 0; + msg.sadb_msg_pid = getpid(); + + sendkeymsg((char *)&msg, sizeof(msg)); + + return; +} + +void +promisc() +{ + struct sadb_msg msg; + u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ + ssize_t l; + + msg.sadb_msg_version = PF_KEY_V2; + msg.sadb_msg_type = SADB_X_PROMISC; + msg.sadb_msg_errno = 0; + msg.sadb_msg_satype = 1; + msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg)); + msg.sadb_msg_reserved = 0; + msg.sadb_msg_seq = 0; + msg.sadb_msg_pid = getpid(); + + if ((l = send(so, &msg, sizeof(msg), 0)) < 0) { + err(1, "send"); + /*NOTREACHED*/ + } + + while (1) { + struct sadb_msg *base; + + if ((l = recv(so, rbuf, sizeof(*base), MSG_PEEK)) < 0) { + err(1, "recv"); + /*NOTREACHED*/ + } + + if (l != sizeof(*base)) + continue; + + base = (struct sadb_msg *)rbuf; + if ((l = recv(so, rbuf, PFKEY_UNUNIT64(base->sadb_msg_len), + 0)) < 0) { + err(1, "recv"); + /*NOTREACHED*/ + } + printdate(); + if (f_hexdump) { + int i; + for (i = 0; i < l; i++) { + if (i % 16 == 0) + printf("%08x: ", i); + printf("%02x ", rbuf[i] & 0xff); + if (i % 16 == 15) + printf("\n"); + } + if (l % 16) + printf("\n"); + } + /* adjust base pointer for promisc mode */ + if (base->sadb_msg_type == SADB_X_PROMISC) { + if ((ssize_t)sizeof(*base) < l) + base++; + else + base = NULL; + } + if (base) { + kdebug_sadb(base); + printf("\n"); + fflush(stdout); + } + } +} + +/* Generate 'spi' array with SPIs matching 'satype', 'srcs', and 'dsts' + * Return value is dynamically generated array of SPIs, also number of + * SPIs through num_spi pointer. + * On any error, set *num_spi to 0 and return NULL. + */ +u_int32_t * +sendkeymsg_spigrep(satype, srcs, dsts, num_spi) + unsigned int satype; + struct addrinfo *srcs; + struct addrinfo *dsts; + int *num_spi; +{ + struct sadb_msg msg, *m; + char *buf; + size_t len; + ssize_t l; + u_char rbuf[1024 * 32]; + caddr_t mhp[SADB_EXT_MAX + 1]; + struct sadb_address *saddr; + struct sockaddr *s; + struct addrinfo *a; + struct sadb_sa *sa; + u_int32_t *spi = NULL; + int max_spi = 0, fail = 0; + + *num_spi = 0; + + if (f_notreally) { + return NULL; + } + + { + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { + perror("setsockopt"); + return NULL; + } + } + + msg.sadb_msg_version = PF_KEY_V2; + msg.sadb_msg_type = SADB_DUMP; + msg.sadb_msg_errno = 0; + msg.sadb_msg_satype = satype; + msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg)); + msg.sadb_msg_reserved = 0; + msg.sadb_msg_seq = 0; + msg.sadb_msg_pid = getpid(); + buf = (char *)&msg; + len = sizeof(msg); + + if (f_verbose) { + kdebug_sadb(&msg); + printf("\n"); + } + if (f_hexdump) { + int i; + for (i = 0; i < len; i++) { + if (i % 16 == 0) + printf("%08x: ", i); + printf("%02x ", buf[i] & 0xff); + if (i % 16 == 15) + printf("\n"); + } + if (len % 16) + printf("\n"); + } + + if ((l = send(so, buf, len, 0)) < 0) { + perror("send"); + return NULL; + } + + m = (struct sadb_msg *)rbuf; + do { + if ((l = recv(so, rbuf, sizeof(rbuf), 0)) < 0) { + perror("recv"); + fail = 1; + break; + } + + if (PFKEY_UNUNIT64(m->sadb_msg_len) != l) { + warnx("invalid keymsg length"); + fail = 1; + break; + } + + if (f_verbose) { + kdebug_sadb(m); + printf("\n"); + } + + if (m->sadb_msg_type != SADB_DUMP) { + warnx("unexpected message type"); + fail = 1; + break; + } + + if (m->sadb_msg_errno != 0) { + warnx("error encountered"); + fail = 1; + break; + } + + /* match satype */ + if (m->sadb_msg_satype != satype) + continue; + + pfkey_align(m, mhp); + pfkey_check(mhp); + + /* match src */ + saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; + if (saddr == NULL) + continue; + s = (struct sockaddr *)(saddr + 1); + for (a = srcs; a; a = a->ai_next) + if (memcmp(a->ai_addr, s, a->ai_addrlen) == 0) + break; + if (a == NULL) + continue; + + /* match dst */ + saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; + if (saddr == NULL) + continue; + s = (struct sockaddr *)(saddr + 1); + for (a = dsts; a; a = a->ai_next) + if (memcmp(a->ai_addr, s, a->ai_addrlen) == 0) + break; + if (a == NULL) + continue; + + if (*num_spi >= max_spi) { + max_spi += 512; + spi = realloc(spi, max_spi * sizeof(u_int32_t)); + } + + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; + if (sa != NULL) + spi[(*num_spi)++] = (u_int32_t)ntohl(sa->sadb_sa_spi); + + m = (struct sadb_msg *)((caddr_t)m + PFKEY_UNUNIT64(m->sadb_msg_len)); + + if (f_verbose) { + kdebug_sadb(m); + printf("\n"); + } + + } while (m->sadb_msg_seq); + + if (fail) { + free(spi); + *num_spi = 0; + return NULL; + } + + return spi; +} + +int +sendkeymsg(buf, len) + char *buf; + size_t len; +{ + u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ + ssize_t l; + struct sadb_msg *msg; + + if (f_notreally) { + goto end; + } + + { + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { + perror("setsockopt"); + goto end; + } + } + + if (f_forever) + shortdump_hdr(); +again: + if (f_verbose) { + kdebug_sadb((struct sadb_msg *)buf); + printf("\n"); + } + if (f_hexdump) { + int i; + for (i = 0; i < len; i++) { + if (i % 16 == 0) + printf("%08x: ", i); + printf("%02x ", buf[i] & 0xff); + if (i % 16 == 15) + printf("\n"); + } + if (len % 16) + printf("\n"); + } + + if ((l = send(so, buf, len, 0)) < 0) { + perror("send"); + goto end; + } + + msg = (struct sadb_msg *)rbuf; + do { + if ((l = recv(so, rbuf, sizeof(rbuf), 0)) < 0) { + perror("recv"); + goto end; + } + + if (PFKEY_UNUNIT64(msg->sadb_msg_len) != l) { + warnx("invalid keymsg length"); + break; + } + + if (f_verbose) { + kdebug_sadb(msg); + printf("\n"); + } + if (postproc(msg, l) < 0) + break; + } while (msg->sadb_msg_errno || msg->sadb_msg_seq); + + if (f_forever) { + fflush(stdout); + sleep(1); + goto again; + } + +end: + return (0); +} + +int +postproc(msg, len) + struct sadb_msg *msg; + int len; +{ +#ifdef HAVE_PFKEY_POLICY_PRIORITY + static int priority_support_check = 0; +#endif + + if (msg->sadb_msg_errno != 0) { + char inf[80]; + const char *errmsg = NULL; + + if (f_mode == MODE_SCRIPT) + snprintf(inf, sizeof(inf), "The result of line %d: ", lineno); + else + inf[0] = '\0'; + + switch (msg->sadb_msg_errno) { + case ENOENT: + switch (msg->sadb_msg_type) { + case SADB_DELETE: + case SADB_GET: + case SADB_X_SPDDELETE: + errmsg = "No entry"; + break; + case SADB_DUMP: + errmsg = "No SAD entries"; + break; + case SADB_X_SPDDUMP: + errmsg = "No SPD entries"; + break; + } + break; + default: + errmsg = strerror(msg->sadb_msg_errno); + } + printf("%s%s.\n", inf, errmsg); + return (-1); + } + + switch (msg->sadb_msg_type) { + case SADB_GET: + if (f_withports) + pfkey_sadump_withports(msg); + else + pfkey_sadump(msg); + break; + + case SADB_DUMP: + /* filter out DEAD SAs */ + if (!f_all) { + caddr_t mhp[SADB_EXT_MAX + 1]; + struct sadb_sa *sa; + pfkey_align(msg, mhp); + pfkey_check(mhp); + if ((sa = (struct sadb_sa *)mhp[SADB_EXT_SA]) != NULL) { + if (sa->sadb_sa_state == SADB_SASTATE_DEAD) + break; + } + } + if (f_forever) { + /* TODO: f_withports */ + shortdump(msg); + } else { + if (f_withports) + pfkey_sadump_withports(msg); + else + pfkey_sadump(msg); + } + msg = (struct sadb_msg *)((caddr_t)msg + + PFKEY_UNUNIT64(msg->sadb_msg_len)); + if (f_verbose) { + kdebug_sadb((struct sadb_msg *)msg); + printf("\n"); + } + break; + + case SADB_X_SPDGET: + if (f_withports) + pfkey_spdump_withports(msg); + else + pfkey_spdump(msg); + break; + + case SADB_X_SPDDUMP: + if (f_withports) + pfkey_spdump_withports(msg); + else + pfkey_spdump(msg); + if (msg->sadb_msg_seq == 0) break; + msg = (struct sadb_msg *)((caddr_t)msg + + PFKEY_UNUNIT64(msg->sadb_msg_len)); + if (f_verbose) { + kdebug_sadb((struct sadb_msg *)msg); + printf("\n"); + } + break; +#ifdef HAVE_PFKEY_POLICY_PRIORITY + case SADB_X_SPDADD: + if (last_msg_type == SADB_X_SPDADD && last_priority != 0 && + msg->sadb_msg_pid == getpid() && !priority_support_check) { + priority_support_check = 1; + if (!verifypriority(msg)) + printf ("WARNING: Kernel does not support policy priorities\n"); + } + break; +#endif + } + + return (0); +} + +#ifdef HAVE_PFKEY_POLICY_PRIORITY +int +verifypriority(m) + struct sadb_msg *m; +{ + caddr_t mhp[SADB_EXT_MAX + 1]; + struct sadb_x_policy *xpl; + + /* check pfkey message. */ + if (pfkey_align(m, mhp)) { + printf("(%s\n", ipsec_strerror()); + return 0; + } + if (pfkey_check(mhp)) { + printf("%s\n", ipsec_strerror()); + return 0; + } + + xpl = (struct sadb_x_policy *) mhp[SADB_X_EXT_POLICY]; + + if (xpl == NULL) { + printf("no X_POLICY extension.\n"); + return 0; + } + + /* now make sure they match */ + if (last_priority != xpl->sadb_x_policy_priority) + return 0; + + return 1; +} +#endif + +int +fileproc(filename) + const char *filename; +{ + int fd; + ssize_t len, l; + u_char *p, *ep; + struct sadb_msg *msg; + u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ + + fd = open(filename, O_RDONLY); + if (fd < 0) + return -1; + + l = 0; + while (1) { + len = read(fd, rbuf + l, sizeof(rbuf) - l); + if (len < 0) { + close(fd); + return -1; + } else if (len == 0) + break; + l += len; + } + + if (l < sizeof(struct sadb_msg)) { + close(fd); + errno = EINVAL; + return -1; + } + close(fd); + + p = rbuf; + ep = rbuf + l; + + while (p < ep) { + msg = (struct sadb_msg *)p; + len = PFKEY_UNUNIT64(msg->sadb_msg_len); + postproc(msg, len); + p += len; + } + + return (0); +} + + +/*------------------------------------------------------------*/ +static const char *satype[] = { + NULL, NULL, "ah", "esp" +}; +static const char *sastate[] = { + "L", "M", "D", "d" +}; +static const char *ipproto[] = { +/*0*/ "ip", "icmp", "igmp", "ggp", "ip4", + NULL, "tcp", NULL, "egp", NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, + NULL, NULL, "udp", NULL, NULL, +/*20*/ NULL, NULL, "idp", NULL, NULL, + NULL, NULL, NULL, NULL, "tp", +/*30*/ NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, +/*40*/ NULL, "ip6", NULL, "rt6", "frag6", + NULL, "rsvp", "gre", NULL, NULL, +/*50*/ "esp", "ah", NULL, NULL, NULL, + NULL, NULL, NULL, "icmp6", "none", +/*60*/ "dst6", +}; + +#define STR_OR_ID(x, tab) \ + (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) + +const char * +numstr(x) + int x; +{ + static char buf[20]; + snprintf(buf, sizeof(buf), "#%d", x); + return buf; +} + +void +shortdump_hdr() +{ + printf("%-4s %-3s %-1s %-8s %-7s %s -> %s\n", + "time", "p", "s", "spi", "ltime", "src", "dst"); +} + +void +shortdump(msg) + struct sadb_msg *msg; +{ + caddr_t mhp[SADB_EXT_MAX + 1]; + char buf[NI_MAXHOST], pbuf[NI_MAXSERV]; + struct sadb_sa *sa; + struct sadb_address *saddr; + struct sadb_lifetime *lts, *lth, *ltc; + struct sockaddr *s; + u_int t; + time_t cur = time(0); + + pfkey_align(msg, mhp); + pfkey_check(mhp); + + printf("%02lu%02lu", (u_long)(cur % 3600) / 60, (u_long)(cur % 60)); + + printf(" %-3s", STR_OR_ID(msg->sadb_msg_satype, satype)); + + if ((sa = (struct sadb_sa *)mhp[SADB_EXT_SA]) != NULL) { + printf(" %-1s", STR_OR_ID(sa->sadb_sa_state, sastate)); + printf(" %08x", (u_int32_t)ntohl(sa->sadb_sa_spi)); + } else + printf("%-1s %-8s", "?", "?"); + + lts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT]; + lth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD]; + ltc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT]; + if (lts && lth && ltc) { + if (ltc->sadb_lifetime_addtime == 0) + t = (u_long)0; + else + t = (u_long)(cur - ltc->sadb_lifetime_addtime); + if (t >= 1000) + strlcpy(buf, " big/", sizeof(buf)); + else + snprintf(buf, sizeof(buf), " %3lu/", (u_long)t); + printf("%s", buf); + + t = (u_long)lth->sadb_lifetime_addtime; + if (t >= 1000) + strlcpy(buf, "big", sizeof(buf)); + else + snprintf(buf, sizeof(buf), "%-3lu", (u_long)t); + printf("%s", buf); + } else + printf(" ??\?/???"); /* backslash to avoid trigraph ??/ */ + + printf(" "); + + if ((saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]) != NULL) { + if (saddr->sadb_address_proto) + printf("%s ", STR_OR_ID(saddr->sadb_address_proto, ipproto)); + s = (struct sockaddr *)(saddr + 1); + getnameinfo(s, sysdep_sa_len(s), buf, sizeof(buf), + pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV); + if (strcmp(pbuf, "0") != 0) + printf("%s[%s]", buf, pbuf); + else + printf("%s", buf); + } else + printf("?"); + + printf(" -> "); + + if ((saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]) != NULL) { + if (saddr->sadb_address_proto) + printf("%s ", STR_OR_ID(saddr->sadb_address_proto, ipproto)); + + s = (struct sockaddr *)(saddr + 1); + getnameinfo(s, sysdep_sa_len(s), buf, sizeof(buf), + pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV); + if (strcmp(pbuf, "0") != 0) + printf("%s[%s]", buf, pbuf); + else + printf("%s", buf); + } else + printf("?"); + + printf("\n"); +} + +/* From: tcpdump(1):gmt2local.c and util.c */ +/* + * Print the timestamp + */ +static void +printdate() +{ + struct timeval tp; + int s; + + if (gettimeofday(&tp, NULL) == -1) { + perror("gettimeofday"); + return; + } + + if (f_tflag == 1) { + /* Default */ + s = (tp.tv_sec + thiszone ) % 86400; + (void)printf("%02d:%02d:%02d.%06u ", + s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tp.tv_usec); + } else if (f_tflag > 1) { + /* Unix timeval style */ + (void)printf("%u.%06u ", + (u_int32_t)tp.tv_sec, (u_int32_t)tp.tv_usec); + } + + printf("\n"); +} + +/* + * Returns the difference between gmt and local time in seconds. + * Use gmtime() and localtime() to keep things simple. + */ +int32_t +gmt2local(time_t t) +{ + register int dt, dir; + register struct tm *gmt, *loc; + struct tm sgmt; + + if (t == 0) + t = time(NULL); + gmt = &sgmt; + *gmt = *gmtime(&t); + loc = localtime(&t); + dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 + + (loc->tm_min - gmt->tm_min) * 60; + + /* + * If the year or julian day is different, we span 00:00 GMT + * and must add or subtract a day. Check the year first to + * avoid problems when the julian day wraps. + */ + dir = loc->tm_year - gmt->tm_year; + if (dir == 0) + dir = loc->tm_yday - gmt->tm_yday; + dt += dir * 24 * 60 * 60; + + return (dt); +} diff --git a/ipsec-tools/src/setkey/test-pfkey.c b/ipsec-tools/src/setkey/test-pfkey.c new file mode 100644 index 00000000..bb0ad7bf --- /dev/null +++ b/ipsec-tools/src/setkey/test-pfkey.c @@ -0,0 +1,590 @@ +/* $NetBSD: test-pfkey.c,v 1.7 2006/10/06 12:02:27 manu Exp $ */ + +/* $KAME: test-pfkey.c,v 1.4 2000/06/07 00:29:14 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +u_char m_buf[BUFSIZ]; +u_int m_len; +char *pname; + +void Usage __P((void)); +int sendkeymsg __P((void)); +void key_setsadbmsg __P((u_int)); +void key_setsadbsens __P((void)); +void key_setsadbprop __P((void)); +void key_setsadbid __P((u_int, caddr_t)); +void key_setsadblft __P((u_int, u_int)); +void key_setspirange __P((void)); +void key_setsadbkey __P((u_int, caddr_t)); +void key_setsadbsa __P((void)); +void key_setsadbaddr __P((u_int, u_int, caddr_t)); +void key_setsadbextbuf __P((caddr_t, int, caddr_t, int, caddr_t, int)); + +void +Usage() +{ + printf("Usage:\t%s number\n", pname); + exit(0); +} + +int +main(ac, av) + int ac; + char **av; +{ + pname = *av; + + if (ac == 1) Usage(); + + key_setsadbmsg(atoi(*(av+1))); + sendkeymsg(); + + exit(0); +} + +/* %%% */ +int +sendkeymsg() +{ + u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ + int so, len; + + if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { + perror("socket(PF_KEY)"); + goto end; + } +#if 0 + { +#include + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { + perror("setsockopt"); + goto end; + } + } +#endif + + pfkey_sadump((struct sadb_msg *)m_buf); + + if ((len = send(so, m_buf, m_len, 0)) < 0) { + perror("send"); + goto end; + } + + if ((len = recv(so, rbuf, sizeof(rbuf), 0)) < 0) { + perror("recv"); + goto end; + } + + pfkey_sadump((struct sadb_msg *)rbuf); + +end: + (void)close(so); + return(0); +} + +void +key_setsadbmsg(type) + u_int type; +{ + struct sadb_msg m_msg; + + memset(&m_msg, 0, sizeof(m_msg)); + m_msg.sadb_msg_version = PF_KEY_V2; + m_msg.sadb_msg_type = type; + m_msg.sadb_msg_errno = 0; + m_msg.sadb_msg_satype = SADB_SATYPE_ESP; +#if 0 + m_msg.sadb_msg_reserved = 0; +#endif + m_msg.sadb_msg_seq = 0; + m_msg.sadb_msg_pid = getpid(); + + m_len = sizeof(struct sadb_msg); + memcpy(m_buf, &m_msg, m_len); + + switch (type) { + case SADB_GETSPI: + /**/ + key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "10.0.3.4"); + key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "127.0.0.1"); + key_setspirange(); + /**/ + break; + + case SADB_ADD: + /* */ + key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); + case SADB_UPDATE: + key_setsadbsa(); + key_setsadblft(SADB_EXT_LIFETIME_HARD, 10); + key_setsadblft(SADB_EXT_LIFETIME_SOFT, 5); + key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); + key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); + /* XXX key_setsadbkey(SADB_EXT_KEY_AUTH, "abcde"); */ + key_setsadbkey(SADB_EXT_KEY_AUTH, "1234567812345678"); + key_setsadbkey(SADB_EXT_KEY_ENCRYPT, "12345678"); + key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com"); + key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net"); + key_setsadbsens(); + /* */ + break; + + case SADB_DELETE: + /* */ + key_setsadbsa(); + key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); + key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); + key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); + /* */ + break; + + case SADB_GET: + /* */ + key_setsadbsa(); + key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); + key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); + key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); + /* */ + break; + + case SADB_ACQUIRE: + /* */ + key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); + key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); + key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); + key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com"); + key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net"); + key_setsadbsens(); + key_setsadbprop(); + /* */ + break; + + case SADB_REGISTER: + /* */ + /* */ + break; + + case SADB_EXPIRE: + case SADB_FLUSH: + break; + + case SADB_DUMP: + break; + + case SADB_X_PROMISC: + /* */ + /* */ + break; + + case SADB_X_PCHANGE: + break; + + /* for SPD management */ + case SADB_X_SPDFLUSH: + case SADB_X_SPDDUMP: + break; + + case SADB_X_SPDADD: +#if 0 + { + struct sadb_x_policy m_policy; + + m_policy.sadb_x_policy_len = PFKEY_UNIT64(sizeof(m_policy)); + m_policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY; + m_policy.sadb_x_policy_type = SADB_X_PL_IPSEC; + m_policy.sadb_x_policy_esp_trans = 1; + m_policy.sadb_x_policy_ah_trans = 2; + m_policy.sadb_x_policy_esp_network = 3; + m_policy.sadb_x_policy_ah_network = 4; + m_policy.sadb_x_policy_reserved = 0; + + memcpy(m_buf + m_len, &m_policy, sizeof(struct sadb_x_policy)); + m_len += sizeof(struct sadb_x_policy); + } +#endif + + case SADB_X_SPDDELETE: + key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); + key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); + break; + } + + ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len); + + return; +} + +void +key_setsadbsens() +{ + struct sadb_sens m_sens; + u_char buf[64]; + u_int s, i, slen, ilen, len; + + /* make sens & integ */ + s = htonl(0x01234567); + i = htonl(0x89abcdef); + slen = sizeof(s); + ilen = sizeof(i); + memcpy(buf, &s, slen); + memcpy(buf + slen, &i, ilen); + + len = sizeof(m_sens) + PFKEY_ALIGN8(slen) + PFKEY_ALIGN8(ilen); + m_sens.sadb_sens_len = PFKEY_UNIT64(len); + m_sens.sadb_sens_exttype = SADB_EXT_SENSITIVITY; + m_sens.sadb_sens_dpd = 1; + m_sens.sadb_sens_sens_level = 2; + m_sens.sadb_sens_sens_len = PFKEY_ALIGN8(slen); + m_sens.sadb_sens_integ_level = 3; + m_sens.sadb_sens_integ_len = PFKEY_ALIGN8(ilen); + m_sens.sadb_sens_reserved = 0; + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_sens, sizeof(struct sadb_sens), + buf, slen + ilen); + m_len += len; + + return; +} + +void +key_setsadbprop() +{ + struct sadb_prop m_prop; + struct sadb_comb *m_comb; + u_char buf[256]; +#if (defined(SADB_X_EALG_AESCBC) || defined(SADB_X_EALG_CAMELLIACBC)) && defined(SADB_X_AALG_SHA2_256) + u_int len = sizeof(m_prop) + sizeof(m_comb) * 3; +#else + u_int len = sizeof(m_prop) + sizeof(m_comb) * 2; +#endif + + /* make prop & comb */ + m_prop.sadb_prop_len = PFKEY_UNIT64(len); + m_prop.sadb_prop_exttype = SADB_EXT_PROPOSAL; + m_prop.sadb_prop_replay = 0; + m_prop.sadb_prop_reserved[0] = 0; + m_prop.sadb_prop_reserved[1] = 0; + m_prop.sadb_prop_reserved[2] = 0; + + /* the 1st is ESP DES-CBC HMAC-MD5 */ + m_comb = (struct sadb_comb *)buf; + m_comb->sadb_comb_auth = SADB_AALG_MD5HMAC; + m_comb->sadb_comb_encrypt = SADB_EALG_DESCBC; + m_comb->sadb_comb_flags = 0; + m_comb->sadb_comb_auth_minbits = 8; + m_comb->sadb_comb_auth_maxbits = 96; + m_comb->sadb_comb_encrypt_minbits = 64; + m_comb->sadb_comb_encrypt_maxbits = 64; + m_comb->sadb_comb_reserved = 0; + m_comb->sadb_comb_soft_allocations = 0; + m_comb->sadb_comb_hard_allocations = 0; + m_comb->sadb_comb_soft_bytes = 0; + m_comb->sadb_comb_hard_bytes = 0; + m_comb->sadb_comb_soft_addtime = 0; + m_comb->sadb_comb_hard_addtime = 0; + m_comb->sadb_comb_soft_usetime = 0; + m_comb->sadb_comb_hard_usetime = 0; + + /* the 2st is ESP 3DES-CBC and AH HMAC-SHA1 */ + m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb)); + m_comb->sadb_comb_auth = SADB_AALG_SHA1HMAC; + m_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC; + m_comb->sadb_comb_flags = 0; + m_comb->sadb_comb_auth_minbits = 8; + m_comb->sadb_comb_auth_maxbits = 96; + m_comb->sadb_comb_encrypt_minbits = 64; + m_comb->sadb_comb_encrypt_maxbits = 64; + m_comb->sadb_comb_reserved = 0; + m_comb->sadb_comb_soft_allocations = 0; + m_comb->sadb_comb_hard_allocations = 0; + m_comb->sadb_comb_soft_bytes = 0; + m_comb->sadb_comb_hard_bytes = 0; + m_comb->sadb_comb_soft_addtime = 0; + m_comb->sadb_comb_hard_addtime = 0; + m_comb->sadb_comb_soft_usetime = 0; + m_comb->sadb_comb_hard_usetime = 0; + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_prop, sizeof(struct sadb_prop), + buf, sizeof(*m_comb) * 2); + m_len += len; + + #if defined(SADB_X_EALG_AESCBC) && defined(SADB_X_AALG_SHA2_256) + /* the 3rd is ESP AES-CBC and AH HMAC-SHA256 */ + m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb)); + m_comb->sadb_comb_auth = SADB_X_AALG_SHA2_256; + m_comb->sadb_comb_encrypt = SADB_X_EALG_AESCBC; + m_comb->sadb_comb_flags = 0; + m_comb->sadb_comb_auth_minbits = 8; + m_comb->sadb_comb_auth_maxbits = 96; + m_comb->sadb_comb_encrypt_minbits = 128; + m_comb->sadb_comb_encrypt_maxbits = 128; + m_comb->sadb_comb_reserved = 0; + m_comb->sadb_comb_soft_allocations = 0; + m_comb->sadb_comb_hard_allocations = 0; + m_comb->sadb_comb_soft_bytes = 0; + m_comb->sadb_comb_hard_bytes = 0; + m_comb->sadb_comb_soft_addtime = 0; + m_comb->sadb_comb_hard_addtime = 0; + m_comb->sadb_comb_soft_usetime = 0; + m_comb->sadb_comb_hard_usetime = 0; + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_prop, sizeof(struct sadb_prop), + buf, sizeof(*m_comb) * 3); + m_len += len; + #elif defined(SADB_X_EALG_CAMELLIACBC) && defined(SADB_X_AALG_SHA2_256) + /* the 3rd is ESP CAMELLIA-CBC and AH HMAC-SHA256 */ + m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb)); + m_comb->sadb_comb_auth = SADB_X_AALG_SHA2_256; + m_comb->sadb_comb_encrypt = SADB_X_EALG_CAMELLIACBC; + m_comb->sadb_comb_flags = 0; + m_comb->sadb_comb_auth_minbits = 8; + m_comb->sadb_comb_auth_maxbits = 96; + m_comb->sadb_comb_encrypt_minbits = 128; + m_comb->sadb_comb_encrypt_maxbits = 128; + m_comb->sadb_comb_reserved = 0; + m_comb->sadb_comb_soft_allocations = 0; + m_comb->sadb_comb_hard_allocations = 0; + m_comb->sadb_comb_soft_bytes = 0; + m_comb->sadb_comb_hard_bytes = 0; + m_comb->sadb_comb_soft_addtime = 0; + m_comb->sadb_comb_hard_addtime = 0; + m_comb->sadb_comb_soft_usetime = 0; + m_comb->sadb_comb_hard_usetime = 0; + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_prop, sizeof(struct sadb_prop), + buf, sizeof(*m_comb) * 3); + m_len += len; +#else + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_prop, sizeof(struct sadb_prop), + buf, sizeof(*m_comb) * 2); + m_len += len; +#endif + return; +} + +void +key_setsadbid(ext, str) + u_int ext; + caddr_t str; +{ + struct sadb_ident m_id; + u_int idlen = strlen(str), len; + + len = sizeof(m_id) + PFKEY_ALIGN8(idlen); + m_id.sadb_ident_len = PFKEY_UNIT64(len); + m_id.sadb_ident_exttype = ext; + m_id.sadb_ident_type = SADB_IDENTTYPE_USERFQDN; + m_id.sadb_ident_reserved = 0; + m_id.sadb_ident_id = getpid(); + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_id, sizeof(struct sadb_ident), + str, idlen); + m_len += len; + + return; +} + +void +key_setsadblft(ext, time) + u_int ext, time; +{ + struct sadb_lifetime m_lft; + + m_lft.sadb_lifetime_len = PFKEY_UNIT64(sizeof(m_lft)); + m_lft.sadb_lifetime_exttype = ext; + m_lft.sadb_lifetime_allocations = 0x2; + m_lft.sadb_lifetime_bytes = 0x1000; + m_lft.sadb_lifetime_addtime = time; + m_lft.sadb_lifetime_usetime = 0x0020; + + memcpy(m_buf + m_len, &m_lft, sizeof(struct sadb_lifetime)); + m_len += sizeof(struct sadb_lifetime); + + return; +} + +void +key_setspirange() +{ + struct sadb_spirange m_spi; + + m_spi.sadb_spirange_len = PFKEY_UNIT64(sizeof(m_spi)); + m_spi.sadb_spirange_exttype = SADB_EXT_SPIRANGE; + m_spi.sadb_spirange_min = 0x00001000; + m_spi.sadb_spirange_max = 0x00002000; + m_spi.sadb_spirange_reserved = 0; + + memcpy(m_buf + m_len, &m_spi, sizeof(struct sadb_spirange)); + m_len += sizeof(struct sadb_spirange); + + return; +} + +void +key_setsadbkey(ext, str) + u_int ext; + caddr_t str; +{ + struct sadb_key m_key; + u_int keylen = strlen(str); + u_int len; + + len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); + m_key.sadb_key_len = PFKEY_UNIT64(len); + m_key.sadb_key_exttype = ext; + m_key.sadb_key_bits = keylen * 8; + m_key.sadb_key_reserved = 0; + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_key, sizeof(struct sadb_key), + str, keylen); + m_len += len; + + return; +} + +void +key_setsadbsa() +{ + struct sadb_sa m_sa; + + m_sa.sadb_sa_len = PFKEY_UNIT64(sizeof(struct sadb_sa)); + m_sa.sadb_sa_exttype = SADB_EXT_SA; + m_sa.sadb_sa_spi = htonl(0x12345678); + m_sa.sadb_sa_replay = 4; + m_sa.sadb_sa_state = 0; + m_sa.sadb_sa_auth = SADB_AALG_MD5HMAC; + m_sa.sadb_sa_encrypt = SADB_EALG_DESCBC; + m_sa.sadb_sa_flags = 0; + + memcpy(m_buf + m_len, &m_sa, sizeof(struct sadb_sa)); + m_len += sizeof(struct sadb_sa); + + return; +} + +void +key_setsadbaddr(ext, af, str) + u_int ext, af; + caddr_t str; +{ + struct sadb_address m_addr; + u_int len; + struct addrinfo hints, *res; + const char *serv; + int plen; + + switch (af) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + /* XXX bark */ + exit(1); + } + + /* make sockaddr buffer */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + serv = (ext == SADB_EXT_ADDRESS_PROXY ? "0" : "4660"); /*0x1234*/ + if (getaddrinfo(str, serv, &hints, &res) != 0 || res->ai_next) { + /* XXX bark */ + exit(1); + } + + len = sizeof(struct sadb_address) + PFKEY_ALIGN8(res->ai_addrlen); + m_addr.sadb_address_len = PFKEY_UNIT64(len); + m_addr.sadb_address_exttype = ext; + m_addr.sadb_address_proto = + (ext == SADB_EXT_ADDRESS_PROXY ? 0 : IPPROTO_TCP); + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_addr, sizeof(struct sadb_address), + (caddr_t)res->ai_addr, res->ai_addrlen); + m_len += len; + + freeaddrinfo(res); + + return; +} + +void +key_setsadbextbuf(dst, off, ebuf, elen, vbuf, vlen) + caddr_t dst, ebuf, vbuf; + int off, elen, vlen; +{ + memset(dst + off, 0, elen + vlen); + memcpy(dst + off, (caddr_t)ebuf, elen); + memcpy(dst + off + elen, vbuf, vlen); + + return; +} + diff --git a/ipsec-tools/src/setkey/token.c b/ipsec-tools/src/setkey/token.c new file mode 100644 index 00000000..f533cfc1 --- /dev/null +++ b/ipsec-tools/src/setkey/token.c @@ -0,0 +1,2910 @@ + +#line 3 "token.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 37 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +typedef unsigned char YY_CHAR; + +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + (yytext_ptr) -= (yy_more_len); \ + yyleng = (size_t) (yy_cp - (yytext_ptr)); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 90 +#define YY_END_OF_BUFFER 91 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[564] = + { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 91, 89, + 77, 78, 89, 79, 88, 89, 81, 84, 84, 87, + 80, 82, 83, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 17, 17, + 17, 17, 17, 17, 17, 17, 18, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 87, 87, 87, 87, 87, 84, 87, 87, + 87, 87, 87, 87, 87, 87, 77, 0, 86, 79, + 88, 19, 27, 56, 42, 16, 60, 0, 0, 65, + 0, 61, 70, 64, 87, 84, 87, 87, 20, 87, + + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 17, 17, 17, 17, 17, 17, 16, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 19, 73, 74, 0, 71, + 72, 85, 1, 87, 76, 9, 87, 87, 87, 21, + 87, 87, 4, 87, 59, 87, 57, 87, 87, 87, + + 87, 87, 26, 87, 87, 87, 17, 17, 17, 17, + 17, 17, 17, 1, 17, 17, 9, 17, 17, 17, + 17, 17, 17, 4, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 87, 87, 87, + 87, 26, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 75, 87, 87, 87, 6, 87, 7, 87, + 87, 87, 8, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 17, 17, 17, 17, 6, 17, 7, + 17, 17, 17, 8, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 87, 87, 87, 41, 87, 87, + + 87, 87, 87, 87, 87, 45, 87, 87, 87, 87, + 87, 87, 87, 87, 5, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 17, 17, + 17, 17, 17, 5, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 22, 87, 2, 87, 87, 25, 87, 87, + 87, 10, 87, 87, 87, 87, 15, 87, 63, 87, + 17, 17, 2, 17, 17, 17, 17, 17, 17, 10, + 17, 17, 17, 17, 15, 17, 17, 17, 87, 87, + + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 46, 87, 58, 87, 23, 24, + 87, 87, 67, 87, 13, 87, 87, 87, 87, 17, + 17, 17, 17, 17, 17, 17, 17, 13, 17, 17, + 17, 17, 87, 87, 87, 87, 87, 87, 40, 87, + 52, 54, 87, 87, 87, 87, 43, 87, 87, 87, + 87, 87, 87, 87, 14, 87, 87, 68, 17, 17, + 17, 17, 14, 17, 17, 17, 87, 28, 87, 87, + 87, 87, 44, 87, 87, 87, 50, 87, 87, 87, + 3, 87, 87, 12, 11, 62, 3, 17, 17, 12, + + 11, 17, 87, 87, 29, 87, 87, 87, 30, 87, + 87, 87, 87, 49, 87, 87, 87, 66, 17, 17, + 87, 87, 87, 87, 87, 87, 31, 87, 87, 87, + 87, 87, 87, 17, 87, 87, 87, 87, 87, 33, + 35, 37, 87, 87, 48, 87, 51, 69, 17, 39, + 87, 87, 87, 87, 47, 55, 53, 87, 32, 34, + 36, 38, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 4, 5, 1, 6, 1, 1, 1, + 1, 1, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 19, 21, 22, 1, + 1, 1, 1, 1, 23, 24, 25, 24, 26, 24, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 27, + 21, 28, 21, 21, 21, 21, 21, 29, 21, 21, + 30, 1, 31, 1, 32, 1, 33, 34, 35, 36, + + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[59] = + { 0, + 1, 2, 3, 1, 1, 4, 2, 5, 4, 4, + 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 4, 1, 4, 4, 4, 4, 4, 4, 4, 2, + 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4 + } ; + +static yyconst flex_int16_t yy_base[570] = + { 0, + 0, 0, 58, 0, 84, 85, 123, 161, 1553, 1554, + 1550, 1554, 1547, 0, 0, 198, 1554, 244, 293, 1542, + 1554, 1554, 1554, 114, 111, 112, 115, 118, 124, 131, + 125, 133, 132, 134, 113, 140, 156, 126, 1547, 0, + 298, 0, 0, 350, 405, 197, 1554, 436, 146, 194, + 199, 107, 229, 231, 232, 234, 246, 249, 251, 282, + 338, 301, 309, 127, 144, 137, 342, 1512, 364, 332, + 185, 346, 241, 352, 421, 395, 1545, 1542, 1554, 0, + 0, 313, 1554, 1554, 1554, 1554, 1554, 104, 1493, 1554, + 127, 1554, 1554, 1554, 1536, 0, 475, 162, 193, 246, + + 209, 388, 275, 245, 386, 378, 382, 202, 288, 379, + 401, 432, 230, 307, 397, 296, 403, 438, 407, 446, + 1541, 0, 439, 0, 0, 0, 0, 0, 401, 1490, + 0, 409, 0, 0, 0, 434, 0, 506, 509, 518, + 510, 511, 525, 530, 532, 541, 543, 548, 555, 557, + 569, 566, 577, 574, 585, 586, 597, 599, 608, 606, + 613, 451, 448, 471, 290, 455, 467, 456, 469, 611, + 620, 453, 544, 470, 526, 611, 1554, 1554, 1485, 1554, + 1554, 0, 1532, 527, 1531, 1530, 509, 525, 457, 211, + 603, 616, 1529, 551, 1528, 528, 1527, 608, 630, 389, + + 632, 498, 1526, 584, 642, 552, 656, 0, 0, 1477, + 0, 0, 0, 633, 640, 653, 654, 661, 672, 674, + 675, 677, 688, 690, 691, 704, 705, 706, 707, 718, + 739, 727, 730, 732, 741, 746, 748, 669, 684, 667, + 688, 673, 698, 747, 643, 753, 683, 788, 749, 687, + 763, 766, 1554, 775, 781, 783, 1524, 790, 1523, 791, + 793, 792, 1522, 794, 797, 798, 795, 800, 799, 802, + 801, 805, 807, 0, 782, 784, 810, 813, 818, 815, + 827, 830, 842, 843, 844, 856, 857, 869, 872, 871, + 884, 887, 889, 901, 804, 860, 821, 1521, 886, 877, + + 864, 890, 892, 926, 934, 1520, 924, 906, 675, 932, + 893, 935, 936, 938, 1519, 905, 940, 943, 944, 946, + 947, 948, 828, 949, 950, 951, 953, 954, 927, 935, + 958, 965, 943, 960, 967, 972, 974, 988, 986, 987, + 999, 1000, 1001, 1002, 1014, 1015, 1027, 957, 1021, 1048, + 1022, 982, 1035, 1041, 1044, 1056, 1060, 207, 1057, 1068, + 1069, 1070, 1518, 1071, 1072, 1073, 1075, 1517, 1076, 1077, + 1082, 1516, 1083, 1081, 1084, 1089, 1515, 1085, 1514, 1091, + 1064, 1079, 1094, 1067, 1097, 1102, 1110, 1117, 1118, 1119, + 1130, 1132, 1133, 1141, 1146, 1149, 1154, 1165, 1094, 1103, + + 1090, 1104, 1152, 1144, 1128, 1106, 653, 1163, 1167, 813, + 1175, 1180, 1141, 1185, 1513, 1191, 1512, 1194, 1511, 1510, + 1198, 1196, 1509, 1199, 1508, 1201, 1202, 1205, 1204, 1181, + 1184, 1183, 1196, 1199, 1210, 1207, 1221, 1223, 1224, 1226, + 1235, 1240, 1217, 1257, 1229, 1260, 1271, 1274, 1507, 1275, + 1506, 1505, 1276, 1279, 1087, 1240, 1504, 1280, 1281, 1282, + 1284, 1287, 1289, 1290, 1497, 1292, 1291, 1485, 1265, 1294, + 1299, 1301, 1277, 1312, 1310, 1315, 1310, 1475, 1294, 1351, + 1298, 1300, 1474, 1345, 1361, 1328, 1472, 1318, 1365, 1336, + 1471, 1316, 1349, 1467, 1466, 1464, 1340, 1341, 1342, 1343, + + 1354, 1355, 1352, 1367, 1458, 1390, 956, 1395, 1334, 1396, + 1376, 1385, 1388, 1312, 1394, 1397, 1398, 1296, 1377, 1379, + 1408, 1402, 1413, 1416, 879, 1418, 1241, 1410, 1425, 1428, + 1431, 1429, 1432, 1406, 1435, 1437, 1439, 958, 1440, 1139, + 1017, 866, 1441, 1443, 832, 1449, 817, 815, 1422, 717, + 1453, 1459, 1210, 1446, 530, 478, 476, 1461, 394, 319, + 214, 121, 1554, 1484, 1490, 1492, 1495, 1500, 1505 + } ; + +static yyconst flex_int16_t yy_def[570] = + { 0, + 563, 1, 563, 3, 1, 1, 1, 1, 563, 563, + 563, 563, 564, 565, 566, 563, 563, 567, 567, 567, + 563, 563, 563, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 568, 568, + 568, 568, 568, 569, 569, 569, 563, 569, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 567, 567, 567, 567, 567, 19, 567, 567, + 567, 567, 567, 567, 567, 567, 563, 564, 563, 565, + 566, 563, 563, 563, 563, 563, 563, 563, 563, 563, + 563, 563, 563, 563, 567, 19, 19, 567, 567, 567, + + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 48, 45, 45, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 563, 563, 563, 563, 563, + 563, 97, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + + 567, 567, 567, 567, 567, 567, 568, 568, 568, 568, + 568, 568, 138, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 563, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 568, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 567, 567, 567, 567, 567, 567, + + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 567, 567, + + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 48, 48, + 48, 48, 48, 48, 48, 48, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 48, 48, 48, 48, + + 48, 48, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 48, 48, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 48, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 48, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 0, 563, 563, 563, 563, 563, 563 + } ; + +static yyconst flex_int16_t yy_nxt[1613] = + { 0, + 10, 11, 12, 13, 14, 10, 10, 15, 16, 10, + 17, 18, 19, 19, 19, 19, 19, 19, 19, 19, + 20, 21, 20, 20, 20, 20, 20, 20, 20, 22, + 23, 10, 24, 25, 20, 26, 27, 28, 29, 20, + 30, 20, 20, 31, 20, 32, 33, 20, 34, 35, + 36, 37, 20, 20, 20, 20, 20, 38, 10, 39, + 40, 13, 14, 10, 10, 15, 41, 42, 43, 44, + 45, 45, 45, 45, 45, 45, 45, 45, 46, 47, + 46, 46, 46, 46, 46, 46, 46, 22, 23, 42, + 48, 49, 46, 50, 51, 52, 53, 46, 54, 46, + + 46, 55, 46, 56, 57, 46, 58, 59, 60, 61, + 46, 46, 46, 46, 46, 62, 63, 63, 563, 563, + 563, 563, 563, 64, 64, 563, 65, 65, 563, 66, + 66, 563, 563, 563, 563, 67, 67, 68, 563, 563, + 563, 563, 136, 177, 563, 113, 136, 563, 102, 98, + 147, 563, 136, 99, 178, 69, 70, 71, 72, 100, + 107, 106, 120, 563, 103, 104, 180, 101, 73, 563, + 105, 163, 74, 75, 76, 68, 114, 181, 108, 110, + 164, 136, 109, 110, 111, 136, 112, 115, 116, 165, + 117, 136, 563, 69, 70, 71, 72, 183, 122, 122, + + 563, 184, 142, 122, 563, 118, 73, 122, 119, 563, + 74, 75, 76, 82, 563, 82, 563, 170, 563, 258, + 83, 563, 84, 85, 86, 87, 122, 122, 122, 136, + 143, 88, 89, 136, 136, 90, 194, 563, 136, 136, + 412, 91, 92, 82, 136, 186, 144, 93, 563, 145, + 94, 81, 563, 563, 146, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 136, 148, 136, 136, 136, 136, + 136, 136, 97, 136, 136, 199, 136, 136, 149, 136, + 151, 136, 563, 154, 136, 136, 136, 110, 136, 150, + 136, 136, 190, 172, 136, 563, 136, 563, 152, 97, + + 81, 153, 185, 563, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 123, 563, 123, 563, 136, 155, 189, + 124, 136, 125, 126, 127, 128, 563, 136, 176, 156, + 176, 129, 130, 241, 202, 131, 136, 161, 195, 563, + 136, 132, 133, 123, 98, 162, 136, 134, 99, 563, + 135, 122, 122, 563, 100, 200, 122, 81, 176, 563, + 122, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 157, 563, 158, 136, 116, 169, 166, 136, 138, 122, + 122, 122, 171, 136, 113, 563, 563, 159, 101, 563, + 160, 118, 173, 563, 119, 563, 563, 265, 103, 98, + + 168, 563, 563, 99, 563, 138, 122, 122, 563, 100, + 563, 122, 81, 196, 563, 122, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 187, 191, 116, 563, 117, + 192, 188, 201, 193, 122, 122, 122, 122, 122, 563, + 208, 197, 122, 563, 118, 563, 122, 119, 211, 175, + 203, 209, 205, 563, 207, 563, 207, 114, 563, 212, + 563, 174, 563, 563, 563, 122, 122, 122, 115, 136, + 204, 139, 198, 136, 563, 140, 563, 563, 563, 136, + 239, 141, 563, 563, 207, 563, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 206, 249, 182, 182, 182, + + 182, 238, 242, 243, 257, 563, 244, 182, 182, 182, + 182, 182, 182, 563, 251, 245, 563, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 215, 240, 213, 213, + 213, 213, 563, 563, 563, 563, 270, 563, 213, 213, + 213, 213, 213, 213, 214, 136, 136, 217, 136, 136, + 136, 563, 255, 136, 136, 136, 136, 136, 563, 563, + 136, 256, 218, 136, 136, 136, 216, 136, 219, 136, + 136, 136, 252, 254, 220, 136, 136, 136, 136, 221, + 136, 222, 136, 136, 262, 250, 136, 136, 136, 225, + 136, 563, 136, 136, 136, 223, 136, 261, 273, 224, + + 136, 136, 136, 227, 136, 136, 228, 226, 136, 136, + 563, 136, 136, 136, 136, 563, 136, 229, 563, 230, + 136, 232, 136, 563, 136, 136, 176, 563, 176, 271, + 136, 136, 136, 231, 136, 233, 136, 563, 136, 563, + 235, 136, 136, 136, 136, 136, 234, 136, 136, 563, + 563, 236, 136, 136, 259, 246, 176, 187, 136, 263, + 563, 247, 237, 188, 266, 264, 260, 267, 136, 268, + 248, 207, 136, 207, 563, 136, 563, 295, 136, 136, + 563, 299, 563, 279, 269, 136, 275, 272, 136, 136, + 563, 563, 136, 136, 563, 563, 136, 302, 136, 136, + + 136, 207, 452, 297, 276, 563, 136, 136, 277, 136, + 136, 136, 136, 136, 136, 362, 136, 136, 296, 136, + 136, 278, 136, 136, 563, 136, 136, 136, 280, 136, + 136, 298, 307, 136, 304, 136, 136, 282, 281, 136, + 136, 136, 136, 136, 136, 136, 136, 286, 300, 136, + 136, 136, 136, 285, 563, 301, 563, 136, 284, 287, + 563, 283, 288, 136, 289, 136, 136, 136, 291, 136, + 563, 136, 136, 563, 136, 136, 136, 136, 136, 290, + 136, 136, 563, 136, 136, 136, 292, 136, 563, 303, + 563, 293, 306, 136, 294, 563, 305, 563, 563, 563, + + 563, 563, 563, 309, 563, 563, 563, 563, 563, 563, + 308, 563, 563, 311, 563, 328, 330, 136, 310, 136, + 563, 136, 563, 136, 563, 329, 317, 136, 563, 136, + 315, 321, 455, 320, 312, 563, 313, 316, 325, 563, + 318, 327, 314, 323, 319, 136, 324, 322, 136, 136, + 136, 326, 136, 136, 136, 136, 350, 136, 136, 348, + 136, 331, 136, 136, 332, 136, 334, 563, 349, 136, + 333, 563, 136, 563, 335, 136, 336, 136, 136, 136, + 375, 136, 136, 136, 563, 352, 563, 136, 136, 136, + 337, 136, 339, 563, 541, 136, 136, 563, 353, 563, + + 563, 136, 136, 338, 136, 340, 136, 136, 136, 347, + 136, 136, 563, 563, 136, 342, 136, 136, 343, 136, + 344, 341, 136, 136, 136, 346, 136, 354, 136, 136, + 351, 563, 136, 563, 136, 355, 136, 345, 356, 563, + 136, 563, 563, 563, 364, 563, 136, 563, 357, 361, + 563, 563, 368, 563, 563, 563, 563, 563, 563, 360, + 563, 563, 381, 563, 563, 563, 136, 363, 358, 359, + 136, 365, 136, 367, 136, 525, 371, 553, 385, 366, + 136, 372, 136, 369, 376, 377, 382, 370, 136, 563, + 373, 399, 374, 136, 383, 136, 379, 136, 378, 136, + + 136, 380, 136, 136, 136, 136, 136, 136, 384, 136, + 136, 136, 136, 136, 386, 387, 405, 136, 388, 136, + 389, 390, 136, 136, 563, 136, 136, 136, 563, 563, + 391, 136, 136, 136, 136, 136, 394, 395, 136, 136, + 136, 136, 563, 392, 136, 136, 136, 136, 563, 136, + 136, 563, 393, 136, 136, 563, 403, 404, 397, 136, + 136, 396, 136, 563, 563, 400, 136, 563, 406, 410, + 401, 402, 136, 411, 398, 563, 563, 563, 563, 563, + 563, 408, 563, 563, 563, 422, 407, 409, 563, 563, + 563, 563, 563, 413, 563, 486, 563, 563, 563, 136, + + 414, 563, 432, 136, 418, 415, 136, 417, 419, 136, + 563, 563, 136, 563, 136, 430, 421, 423, 136, 424, + 416, 427, 420, 429, 136, 435, 431, 443, 425, 136, + 445, 428, 136, 136, 426, 563, 136, 136, 444, 136, + 451, 136, 136, 446, 433, 136, 563, 136, 563, 136, + 434, 563, 136, 436, 136, 136, 136, 136, 136, 563, + 449, 450, 136, 136, 136, 136, 437, 136, 136, 136, + 563, 136, 136, 440, 563, 136, 136, 136, 136, 438, + 136, 136, 563, 439, 136, 136, 136, 563, 136, 136, + 458, 136, 563, 136, 136, 441, 447, 442, 563, 136, + + 136, 563, 448, 563, 136, 563, 563, 454, 563, 563, + 136, 563, 563, 453, 457, 456, 136, 563, 136, 136, + 136, 459, 136, 136, 563, 560, 136, 469, 136, 136, + 460, 136, 462, 470, 136, 136, 563, 461, 136, 468, + 465, 136, 136, 463, 136, 136, 136, 563, 563, 136, + 464, 477, 136, 466, 467, 136, 136, 471, 136, 136, + 136, 136, 136, 473, 563, 136, 136, 563, 136, 136, + 136, 136, 472, 478, 136, 476, 479, 474, 563, 136, + 136, 563, 563, 563, 475, 136, 563, 563, 563, 563, + 490, 563, 480, 487, 563, 492, 563, 563, 563, 563, + + 136, 563, 498, 563, 136, 563, 481, 563, 497, 483, + 136, 485, 136, 482, 509, 484, 136, 563, 503, 563, + 488, 493, 136, 563, 489, 563, 494, 491, 495, 136, + 504, 499, 510, 136, 136, 563, 136, 500, 136, 136, + 136, 563, 496, 563, 136, 136, 136, 136, 501, 136, + 136, 136, 563, 511, 136, 136, 563, 136, 563, 563, + 136, 502, 513, 505, 506, 507, 517, 508, 563, 512, + 516, 514, 563, 515, 563, 136, 136, 520, 136, 136, + 136, 136, 136, 563, 518, 136, 136, 136, 136, 136, + 136, 519, 563, 136, 136, 563, 521, 563, 523, 136, + + 136, 563, 563, 563, 563, 563, 524, 526, 527, 563, + 528, 522, 136, 534, 136, 563, 136, 563, 136, 529, + 563, 530, 136, 563, 136, 563, 537, 538, 531, 539, + 532, 542, 563, 540, 533, 563, 563, 536, 563, 563, + 535, 136, 563, 543, 563, 136, 563, 563, 563, 551, + 563, 136, 554, 563, 549, 552, 563, 136, 544, 561, + 563, 136, 545, 547, 546, 563, 563, 136, 563, 550, + 558, 563, 562, 563, 563, 555, 559, 556, 563, 563, + 548, 563, 563, 557, 78, 78, 78, 78, 78, 78, + 80, 80, 563, 80, 80, 80, 81, 81, 95, 95, + + 95, 122, 122, 122, 563, 122, 136, 136, 136, 136, + 136, 563, 563, 563, 563, 563, 563, 563, 563, 563, + 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, + 563, 563, 274, 563, 563, 563, 563, 563, 563, 563, + 253, 210, 121, 563, 179, 79, 77, 167, 121, 563, + 79, 77, 563, 9, 563, 563, 563, 563, 563, 563, + 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, + 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, + 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, + 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, + + 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, + 563, 563 + } ; + +static yyconst flex_int16_t yy_chk[1613] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 5, 6, 25, 26, + 35, 24, 27, 5, 6, 28, 5, 6, 562, 5, + 6, 29, 31, 38, 64, 5, 6, 7, 30, 33, + 32, 34, 52, 88, 66, 35, 52, 36, 26, 24, + 52, 65, 52, 24, 88, 7, 7, 7, 7, 24, + 29, 28, 38, 37, 26, 27, 91, 25, 7, 98, + 27, 64, 7, 7, 7, 8, 36, 91, 30, 32, + 65, 49, 31, 66, 33, 49, 34, 36, 37, 66, + 37, 49, 71, 8, 8, 8, 8, 98, 46, 46, + + 99, 99, 49, 46, 46, 37, 8, 46, 37, 108, + 8, 8, 8, 16, 358, 16, 101, 71, 190, 190, + 16, 561, 16, 16, 16, 16, 46, 46, 46, 50, + 50, 16, 16, 50, 51, 16, 108, 113, 51, 50, + 358, 16, 16, 16, 51, 101, 50, 16, 73, 51, + 16, 18, 104, 100, 51, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 53, 53, 54, 55, 53, 56, + 54, 55, 18, 56, 53, 113, 54, 55, 54, 56, + 56, 57, 103, 59, 58, 57, 59, 73, 58, 55, + 59, 57, 104, 73, 58, 109, 59, 165, 57, 18, + + 19, 58, 100, 116, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 41, 114, 41, 63, 60, 60, 103, + 41, 60, 41, 41, 41, 41, 560, 60, 82, 60, + 82, 41, 41, 165, 116, 41, 62, 62, 109, 70, + 62, 41, 41, 41, 63, 63, 62, 41, 63, 67, + 41, 44, 44, 72, 63, 114, 44, 44, 82, 74, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 61, 69, 61, 61, 67, 70, 67, 61, 44, 44, + 44, 44, 72, 61, 74, 106, 110, 61, 70, 107, + 61, 67, 74, 105, 67, 102, 200, 200, 72, 69, + + 69, 559, 76, 69, 115, 44, 45, 45, 111, 69, + 117, 45, 45, 110, 119, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 102, 105, 76, 75, 76, + 106, 102, 115, 107, 45, 45, 45, 48, 48, 112, + 129, 111, 48, 48, 76, 118, 48, 76, 132, 76, + 117, 129, 119, 120, 123, 163, 123, 75, 162, 132, + 172, 75, 166, 168, 189, 48, 48, 48, 75, 136, + 118, 48, 112, 136, 167, 48, 169, 174, 164, 136, + 163, 48, 97, 557, 123, 556, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 120, 172, 97, 97, 97, + + 97, 162, 166, 167, 189, 202, 168, 97, 97, 97, + 97, 97, 97, 138, 174, 169, 187, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 140, 164, 138, 138, + 138, 138, 188, 175, 184, 196, 202, 555, 138, 138, + 138, 138, 138, 138, 139, 141, 142, 142, 139, 141, + 142, 173, 187, 140, 139, 141, 142, 140, 194, 206, + 143, 188, 143, 140, 143, 144, 141, 145, 143, 144, + 143, 145, 175, 184, 144, 144, 146, 145, 147, 145, + 146, 146, 147, 148, 196, 173, 146, 148, 147, 149, + 149, 204, 150, 148, 149, 147, 150, 194, 206, 148, + + 149, 152, 150, 151, 151, 152, 152, 150, 151, 154, + 191, 152, 153, 154, 151, 198, 153, 153, 170, 154, + 155, 156, 153, 192, 155, 156, 176, 171, 176, 204, + 155, 156, 157, 155, 158, 157, 157, 199, 158, 201, + 159, 160, 157, 159, 158, 160, 158, 159, 161, 205, + 245, 160, 161, 159, 191, 170, 176, 171, 161, 198, + 407, 170, 161, 171, 201, 199, 192, 201, 214, 201, + 171, 207, 214, 207, 240, 215, 238, 238, 214, 215, + 242, 242, 309, 221, 201, 215, 215, 205, 216, 217, + 247, 239, 216, 217, 250, 241, 218, 245, 216, 217, + + 218, 207, 407, 240, 218, 243, 218, 219, 219, 220, + 221, 219, 222, 220, 221, 309, 222, 219, 239, 220, + 221, 220, 222, 223, 550, 224, 225, 223, 222, 224, + 225, 241, 250, 223, 247, 224, 225, 225, 223, 226, + 227, 228, 229, 226, 227, 228, 229, 231, 243, 226, + 227, 228, 229, 230, 244, 244, 249, 230, 229, 232, + 246, 227, 232, 230, 232, 233, 232, 234, 233, 233, + 251, 234, 232, 252, 231, 233, 235, 234, 231, 232, + 235, 236, 254, 237, 231, 236, 235, 237, 255, 246, + 256, 236, 249, 237, 237, 248, 248, 258, 260, 262, + + 261, 264, 267, 252, 265, 266, 269, 268, 271, 270, + 251, 295, 272, 255, 273, 273, 276, 275, 254, 276, + 410, 275, 548, 276, 547, 275, 262, 275, 297, 276, + 260, 267, 410, 266, 256, 323, 258, 261, 270, 545, + 264, 272, 258, 268, 265, 277, 269, 267, 278, 277, + 280, 271, 278, 279, 280, 277, 297, 279, 278, 295, + 280, 277, 281, 279, 279, 282, 281, 296, 296, 282, + 279, 301, 281, 542, 282, 282, 283, 283, 284, 285, + 323, 283, 284, 285, 300, 300, 525, 283, 284, 285, + 285, 286, 287, 299, 525, 286, 287, 302, 301, 303, + + 311, 286, 287, 286, 288, 288, 290, 289, 288, 294, + 290, 289, 316, 308, 288, 289, 290, 289, 290, 291, + 291, 288, 292, 291, 293, 293, 292, 302, 293, 291, + 299, 307, 292, 304, 293, 303, 294, 292, 304, 310, + 294, 305, 312, 313, 311, 314, 294, 317, 305, 308, + 318, 319, 316, 320, 321, 322, 324, 325, 326, 307, + 327, 328, 329, 507, 348, 538, 329, 310, 305, 305, + 330, 312, 329, 314, 330, 507, 319, 538, 333, 313, + 330, 320, 333, 317, 324, 325, 330, 318, 333, 352, + 321, 348, 322, 331, 331, 334, 327, 331, 326, 334, + + 332, 328, 335, 331, 332, 334, 335, 336, 332, 337, + 332, 336, 335, 337, 335, 336, 352, 336, 337, 337, + 338, 339, 340, 338, 541, 339, 340, 338, 349, 351, + 340, 339, 340, 338, 341, 342, 343, 344, 341, 342, + 343, 344, 353, 341, 341, 342, 343, 344, 354, 345, + 346, 355, 342, 345, 346, 350, 350, 351, 346, 345, + 346, 345, 347, 356, 359, 349, 347, 357, 353, 356, + 349, 349, 347, 357, 347, 360, 361, 362, 364, 365, + 366, 354, 367, 369, 370, 370, 353, 355, 374, 371, + 373, 375, 378, 359, 455, 455, 376, 401, 380, 381, + + 360, 399, 384, 381, 365, 361, 384, 364, 366, 381, + 400, 402, 384, 406, 382, 382, 369, 371, 382, 373, + 362, 376, 367, 380, 382, 388, 383, 399, 374, 383, + 401, 378, 385, 383, 375, 405, 385, 386, 400, 383, + 406, 386, 385, 402, 385, 387, 540, 386, 413, 387, + 387, 404, 388, 389, 390, 387, 388, 389, 390, 403, + 404, 405, 388, 389, 390, 391, 391, 392, 393, 391, + 408, 392, 393, 394, 409, 391, 394, 392, 393, 392, + 394, 395, 411, 393, 396, 395, 394, 412, 396, 397, + 413, 395, 414, 397, 396, 396, 403, 398, 416, 397, + + 398, 418, 403, 422, 398, 421, 424, 409, 426, 427, + 398, 429, 428, 408, 412, 411, 430, 553, 432, 431, + 430, 414, 432, 431, 443, 553, 430, 431, 432, 431, + 416, 433, 421, 434, 434, 433, 445, 418, 434, 429, + 426, 433, 436, 422, 434, 435, 436, 456, 527, 435, + 424, 443, 436, 427, 428, 435, 437, 435, 438, 439, + 437, 440, 438, 439, 444, 440, 437, 446, 438, 439, + 441, 440, 437, 444, 441, 442, 445, 440, 447, 442, + 441, 448, 450, 453, 441, 442, 454, 458, 459, 460, + 460, 461, 446, 456, 462, 462, 463, 464, 467, 466, + + 469, 479, 470, 518, 469, 481, 447, 482, 469, 450, + 469, 454, 473, 448, 481, 453, 473, 477, 477, 514, + 458, 463, 473, 492, 459, 488, 464, 461, 466, 470, + 479, 471, 482, 470, 471, 486, 472, 472, 471, 470, + 472, 509, 467, 490, 471, 475, 472, 474, 474, 475, + 476, 474, 484, 484, 476, 475, 493, 474, 480, 503, + 476, 475, 486, 480, 480, 480, 492, 480, 485, 485, + 490, 488, 489, 489, 504, 497, 498, 499, 500, 497, + 498, 499, 500, 511, 493, 497, 498, 499, 500, 501, + 502, 498, 512, 501, 502, 513, 503, 506, 506, 501, + + 502, 515, 508, 510, 516, 517, 506, 508, 510, 522, + 511, 504, 519, 519, 520, 521, 519, 528, 520, 512, + 523, 513, 519, 524, 520, 526, 523, 523, 515, 523, + 516, 526, 529, 524, 517, 530, 532, 522, 531, 533, + 521, 534, 535, 528, 536, 534, 537, 539, 543, 536, + 544, 534, 539, 554, 534, 537, 546, 549, 529, 554, + 551, 549, 530, 532, 531, 505, 552, 549, 558, 535, + 551, 496, 558, 495, 494, 543, 552, 544, 491, 487, + 533, 483, 478, 546, 564, 564, 564, 564, 564, 564, + 565, 565, 468, 565, 565, 565, 566, 566, 567, 567, + + 567, 568, 568, 568, 465, 568, 569, 569, 569, 569, + 569, 457, 452, 451, 449, 425, 423, 420, 419, 417, + 415, 379, 377, 372, 368, 363, 315, 306, 298, 263, + 259, 257, 210, 203, 197, 195, 193, 186, 185, 183, + 179, 130, 121, 95, 89, 78, 77, 68, 39, 20, + 13, 11, 9, 563, 563, 563, 563, 563, 563, 563, + 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, + 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, + 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, + 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, + + 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, + 563, 563 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +static int yy_more_flag = 0; +static int yy_more_len = 0; +#define yymore() ((yy_more_flag) = 1) +#define YY_MORE_ADJ (yy_more_len) +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "token.l" +/* $NetBSD: token.l,v 1.15 2010/06/04 13:06:03 vanhu Exp $ */ +/* $KAME: token.l,v 1.44 2003/10/21 07:20:58 itojun Exp $ */ +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#line 35 "token.l" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include +#include +#include + +#include "vchar.h" +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || \ +(defined(__APPLE__) && defined(__MACH__)) +#include "parse.h" +#else +#include "y.tab.h" +#endif + +#include "extern.h" + +/* make the code compile on *BSD-current */ +#ifndef SADB_X_AALG_SHA2_256 +#define SADB_X_AALG_SHA2_256 (-1) +#endif +#ifndef SADB_X_AALG_SHA2_384 +#define SADB_X_AALG_SHA2_384 (-1) +#endif +#ifndef SADB_X_AALG_SHA2_512 +#define SADB_X_AALG_SHA2_512 (-1) +#endif +#ifndef SADB_X_AALG_RIPEMD160HMAC +#define SADB_X_AALG_RIPEMD160HMAC (-1) +#endif +#ifndef SADB_X_AALG_AES_XCBC_MAC +#define SADB_X_AALG_AES_XCBC_MAC (-1) +#endif +#ifndef SADB_X_EALG_TWOFISHCBC +#define SADB_X_EALG_TWOFISHCBC (-1) +#endif +#ifndef SADB_X_EALG_AESCTR +#define SADB_X_EALG_AESCTR (-1) +#endif +#if defined(SADB_X_EALG_AES) && ! defined(SADB_X_EALG_AESCBC) +#define SADB_X_EALG_AESCBC SADB_X_EALG_AES +#endif +/* common section */ + +#define YY_NO_INPUT 1 +#line 1083 "token.c" + +#define INITIAL 0 +#define S_PL 1 +#define S_AUTHALG 2 +#define S_ENCALG 3 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (void ); + +int yyget_debug (void ); + +void yyset_debug (int debug_flag ); + +YY_EXTRA_TYPE yyget_extra (void ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in (void ); + +void yyset_in (FILE * in_str ); + +FILE *yyget_out (void ); + +void yyset_out (FILE * out_str ); + +yy_size_t yyget_leng (void ); + +char *yyget_text (void ); + +int yyget_lineno (void ); + +void yyset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 115 "token.l" + + + +#line 1270 "token.c" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + (yy_more_len) = 0; + if ( (yy_more_flag) ) + { + (yy_more_len) = (yy_c_buf_p) - (yytext_ptr); + (yy_more_flag) = 0; + } + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 564 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 1554 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 118 "token.l" +{ return(ADD); } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 119 "token.l" +{ return(DELETE); } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 120 "token.l" +{ return(DELETEALL); } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 121 "token.l" +{ return(GET); } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 122 "token.l" +{ return(FLUSH); } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 123 "token.l" +{ return(DUMP); } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 124 "token.l" +{ return(EXIT); } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 125 "token.l" +{ return(EXIT); } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 126 "token.l" +{ return(EXIT); } + YY_BREAK +/* for management SPD */ +case 10: +YY_RULE_SETUP +#line 129 "token.l" +{ return(SPDADD); } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 130 "token.l" +{ return(SPDUPDATE); } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 131 "token.l" +{ return(SPDDELETE); } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 132 "token.l" +{ return(SPDDUMP); } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 133 "token.l" +{ return(SPDFLUSH); } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 134 "token.l" +{ return(TAGGED); } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 135 "token.l" +{ BEGIN S_PL; return(F_POLICY); } + YY_BREAK +case 17: +/* rule 17 can match eol */ +YY_RULE_SETUP +#line 136 "token.l" +{ + yymore(); + + /* count up for nl */ + { + char *p; + for (p = yytext; *p != '\0'; p++) + if (*p == '\n') + lineno++; + } + + yylval.val.len = strlen(yytext); + yylval.val.buf = strdup(yytext); + if (!yylval.val.buf) + yyfatal("insufficient memory"); + + return(PL_REQUESTS); + } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 154 "token.l" +{ BEGIN INITIAL; return(EOT); } + YY_BREAK +/* address resolution flags */ +case 19: +YY_RULE_SETUP +#line 157 "token.l" +{ + yylval.val.len = strlen(yytext); + yylval.val.buf = strdup(yytext); + if (!yylval.val.buf) + yyfatal("insufficient memory"); + return(F_AIFLAGS); + } + YY_BREAK +/* security protocols */ +case 20: +YY_RULE_SETUP +#line 166 "token.l" +{ yylval.num = 0; return(PR_AH); } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 167 "token.l" +{ yylval.num = 0; return(PR_ESP); } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 168 "token.l" +{ yylval.num = 1; return(PR_AH); } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 169 "token.l" +{ yylval.num = 1; return(PR_ESP); } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 170 "token.l" +{ yylval.num = 0; return(PR_ESPUDP); } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 171 "token.l" +{ yylval.num = 0; return(PR_IPCOMP); } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 172 "token.l" +{ + yylval.num = 0; return(PR_TCP); + } + YY_BREAK +/* authentication alogorithm */ +case 27: +YY_RULE_SETUP +#line 177 "token.l" +{ BEGIN S_AUTHALG; return(F_AUTH); } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 178 "token.l" +{ yylval.num = SADB_AALG_MD5HMAC; BEGIN INITIAL; return(ALG_AUTH); } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 179 "token.l" +{ yylval.num = SADB_AALG_SHA1HMAC; BEGIN INITIAL; return(ALG_AUTH); } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 180 "token.l" +{ yylval.num = SADB_X_AALG_MD5; BEGIN INITIAL; return(ALG_AUTH); } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 181 "token.l" +{ yylval.num = SADB_X_AALG_SHA; BEGIN INITIAL; return(ALG_AUTH); } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 182 "token.l" +{ yylval.num = SADB_X_AALG_SHA2_256; BEGIN INITIAL; return(ALG_AUTH); } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 183 "token.l" +{ yylval.num = SADB_X_AALG_SHA2_256; BEGIN INITIAL; return(ALG_AUTH); } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 184 "token.l" +{ yylval.num = SADB_X_AALG_SHA2_384; BEGIN INITIAL; return(ALG_AUTH); } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 185 "token.l" +{ yylval.num = SADB_X_AALG_SHA2_384; BEGIN INITIAL; return(ALG_AUTH); } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 186 "token.l" +{ yylval.num = SADB_X_AALG_SHA2_512; BEGIN INITIAL; return(ALG_AUTH); } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 187 "token.l" +{ yylval.num = SADB_X_AALG_SHA2_512; BEGIN INITIAL; return(ALG_AUTH); } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 188 "token.l" +{ yylval.num = SADB_X_AALG_RIPEMD160HMAC; BEGIN INITIAL; return(ALG_AUTH); } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 189 "token.l" +{ yylval.num = SADB_X_AALG_AES_XCBC_MAC; BEGIN INITIAL; return(ALG_AUTH); } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 190 "token.l" +{ +#ifdef SADB_X_AALG_TCP_MD5 + yylval.num = SADB_X_AALG_TCP_MD5; + BEGIN INITIAL; + return(ALG_AUTH); +#endif + } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 197 "token.l" +{ yylval.num = SADB_X_AALG_NULL; BEGIN INITIAL; return(ALG_AUTH_NOKEY); } + YY_BREAK +/* encryption alogorithm */ +case 42: +YY_RULE_SETUP +#line 200 "token.l" +{ BEGIN S_ENCALG; return(F_ENC); } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 201 "token.l" +{ yylval.num = SADB_EALG_DESCBC; BEGIN INITIAL; return(ALG_ENC); } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 202 "token.l" +{ yylval.num = SADB_EALG_3DESCBC; BEGIN INITIAL; return(ALG_ENC); } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 203 "token.l" +{ yylval.num = SADB_EALG_NULL; BEGIN INITIAL; return(ALG_ENC_NOKEY); } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 204 "token.l" +{ yylval.num = SADB_EALG_NULL; BEGIN INITIAL; return(ALG_ENC_OLD); } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 205 "token.l" +{ yylval.num = SADB_X_EALG_BLOWFISHCBC; BEGIN INITIAL; return(ALG_ENC); } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 206 "token.l" +{ yylval.num = SADB_X_EALG_CAST128CBC; BEGIN INITIAL; return(ALG_ENC); } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 207 "token.l" +{ yylval.num = SADB_EALG_DESCBC; BEGIN INITIAL; return(ALG_ENC_DESDERIV); } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 208 "token.l" +{ yylval.num = SADB_EALG_DESCBC; BEGIN INITIAL; return(ALG_ENC_DES32IV); } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 209 "token.l" +{ yylval.num = SADB_X_EALG_TWOFISHCBC; BEGIN INITIAL; return(ALG_ENC); } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 210 "token.l" +{ +#ifdef SADB_X_EALG_AESCBC + yylval.num = SADB_X_EALG_AESCBC; BEGIN INITIAL; return(ALG_ENC); +#endif +} + YY_BREAK +case 53: +YY_RULE_SETUP +#line 215 "token.l" +{ +#ifdef SADB_X_EALG_AESCBC + yylval.num = SADB_X_EALG_AESCBC; BEGIN INITIAL; return(ALG_ENC); +#endif +} + YY_BREAK +case 54: +YY_RULE_SETUP +#line 220 "token.l" +{ yylval.num = SADB_X_EALG_AESCTR; BEGIN INITIAL; return(ALG_ENC); } + YY_BREAK +case 55: +YY_RULE_SETUP +#line 221 "token.l" +{ +#ifdef SADB_X_EALG_CAMELLIACBC + yylval.num = SADB_X_EALG_CAMELLIACBC; BEGIN INITIAL; return(ALG_ENC); +#endif +} + YY_BREAK +/* compression algorithms */ +case 56: +YY_RULE_SETUP +#line 228 "token.l" +{ return(F_COMP); } + YY_BREAK +case 57: +YY_RULE_SETUP +#line 229 "token.l" +{ yylval.num = SADB_X_CALG_OUI; return(ALG_COMP); } + YY_BREAK +case 58: +YY_RULE_SETUP +#line 230 "token.l" +{ yylval.num = SADB_X_CALG_DEFLATE; return(ALG_COMP); } + YY_BREAK +case 59: +YY_RULE_SETUP +#line 231 "token.l" +{ yylval.num = SADB_X_CALG_LZS; return(ALG_COMP); } + YY_BREAK +case 60: +YY_RULE_SETUP +#line 232 "token.l" +{ return(F_RAWCPI); } + YY_BREAK +/* extension */ +case 61: +YY_RULE_SETUP +#line 235 "token.l" +{ return(F_MODE); } + YY_BREAK +case 62: +YY_RULE_SETUP +#line 236 "token.l" +{ yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); } + YY_BREAK +case 63: +YY_RULE_SETUP +#line 237 "token.l" +{ yylval.num = IPSEC_MODE_TUNNEL; return(MODE); } + YY_BREAK +case 64: +YY_RULE_SETUP +#line 238 "token.l" +{ return(F_REQID); } + YY_BREAK +case 65: +YY_RULE_SETUP +#line 239 "token.l" +{ return(F_EXT); } + YY_BREAK +case 66: +YY_RULE_SETUP +#line 240 "token.l" +{ yylval.num = SADB_X_EXT_PRAND; return(EXTENSION); } + YY_BREAK +case 67: +YY_RULE_SETUP +#line 241 "token.l" +{ yylval.num = SADB_X_EXT_PSEQ; return(EXTENSION); } + YY_BREAK +case 68: +YY_RULE_SETUP +#line 242 "token.l" +{ yylval.num = SADB_X_EXT_PZERO; return(EXTENSION); } + YY_BREAK +case 69: +YY_RULE_SETUP +#line 243 "token.l" +{ return(NOCYCLICSEQ); } + YY_BREAK +case 70: +YY_RULE_SETUP +#line 244 "token.l" +{ return(F_REPLAY); } + YY_BREAK +case 71: +YY_RULE_SETUP +#line 245 "token.l" +{ return(F_LIFETIME_HARD); } + YY_BREAK +case 72: +YY_RULE_SETUP +#line 246 "token.l" +{ return(F_LIFETIME_SOFT); } + YY_BREAK +case 73: +YY_RULE_SETUP +#line 247 "token.l" +{ return(F_LIFEBYTE_HARD); } + YY_BREAK +case 74: +YY_RULE_SETUP +#line 248 "token.l" +{ return(F_LIFEBYTE_SOFT); } + YY_BREAK +case 75: +YY_RULE_SETUP +#line 249 "token.l" +{ return(SECURITY_CTX); } + YY_BREAK +/* ... */ +case 76: +YY_RULE_SETUP +#line 252 "token.l" +{ return(ANY); } + YY_BREAK +case 77: +YY_RULE_SETUP +#line 253 "token.l" +{ } + YY_BREAK +case 78: +/* rule 78 can match eol */ +YY_RULE_SETUP +#line 254 "token.l" +{ lineno++; } + YY_BREAK +case 79: +YY_RULE_SETUP +#line 255 "token.l" + + YY_BREAK +case 80: +YY_RULE_SETUP +#line 256 "token.l" +{ return(EOT); } + YY_BREAK +/* for address parameters: /prefix, [port] */ +case 81: +YY_RULE_SETUP +#line 259 "token.l" +{ return SLASH; } + YY_BREAK +case 82: +YY_RULE_SETUP +#line 260 "token.l" +{ return BLCL; } + YY_BREAK +case 83: +YY_RULE_SETUP +#line 261 "token.l" +{ return ELCL; } + YY_BREAK +/* parameter */ +case 84: +YY_RULE_SETUP +#line 264 "token.l" +{ + char *bp; + + yylval.ulnum = strtoul(yytext, &bp, 10); + return(DECSTRING); + } + YY_BREAK +case 85: +YY_RULE_SETUP +#line 271 "token.l" +{ + yylval.val.buf = strdup(yytext + 2); + if (!yylval.val.buf) + yyfatal("insufficient memory"); + yylval.val.len = strlen(yylval.val.buf); + + return(HEXSTRING); + } + YY_BREAK +case 86: +/* rule 86 can match eol */ +YY_RULE_SETUP +#line 280 "token.l" +{ + char *p = yytext; + while (*++p != '"') ; + *p = '\0'; + yytext++; + yylval.val.len = yyleng - 2; + yylval.val.buf = strdup(yytext); + if (!yylval.val.buf) + yyfatal("insufficient memory"); + + return(QUOTEDSTRING); + } + YY_BREAK +case 87: +YY_RULE_SETUP +#line 293 "token.l" +{ + yylval.val.len = yyleng; + yylval.val.buf = strdup(yytext); + if (!yylval.val.buf) + yyfatal("insufficient memory"); + return(STRING); + } + YY_BREAK +case 88: +YY_RULE_SETUP +#line 301 "token.l" +{ + yylval.val.len = yyleng; + yylval.val.buf = strdup(yytext); + if (!yylval.val.buf) + yyfatal("insufficient memory"); + return(STRING); + } + YY_BREAK +case 89: +YY_RULE_SETUP +#line 309 "token.l" +{ + yyfatal("Syntax error"); + /*NOTREACHED*/ + } + YY_BREAK +case 90: +YY_RULE_SETUP +#line 314 "token.l" +ECHO; + YY_BREAK +#line 1903 "token.c" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(S_PL): +case YY_STATE_EOF(S_AUTHALG): +case YY_STATE_EOF(S_ENCALG): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 564 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 564 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 563); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +yy_size_t yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} + +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 314 "token.l" + + + +void +yyfatal(s) + const char *s; +{ + yyerror(s); + exit(1); +} + +void +yyerror(s) + const char *s; +{ + printf("line %d: %s at [%s]\n", lineno, s, yytext); +} + +int +parse(fp) + FILE **fp; +{ + yyin = *fp; + + lineno = 1; + parse_init(); + + if (yyparse()) { + printf("parse failed, line %d.\n", lineno); + return(-1); + } + + return(0); +} + +int +parse_string (char *src) +{ + int result; + YY_BUFFER_STATE buf_state; + + buf_state = yy_scan_string(src); + result = yyparse(); + yy_delete_buffer(buf_state); + return result; +} + + diff --git a/ipsec-tools/src/setkey/token.l b/ipsec-tools/src/setkey/token.l new file mode 100644 index 00000000..ad3d8431 --- /dev/null +++ b/ipsec-tools/src/setkey/token.l @@ -0,0 +1,359 @@ +/* $NetBSD: token.l,v 1.15 2010/06/04 13:06:03 vanhu Exp $ */ + +/* $KAME: token.l,v 1.44 2003/10/21 07:20:58 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +%{ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include PATH_IPSEC_H + +#include +#include +#include +#include +#include +#include + +#include "vchar.h" +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || \ +(defined(__APPLE__) && defined(__MACH__)) +#include "parse.h" +#else +#include "y.tab.h" +#endif + +#include "extern.h" + +/* make the code compile on *BSD-current */ +#ifndef SADB_X_AALG_SHA2_256 +#define SADB_X_AALG_SHA2_256 (-1) +#endif +#ifndef SADB_X_AALG_SHA2_384 +#define SADB_X_AALG_SHA2_384 (-1) +#endif +#ifndef SADB_X_AALG_SHA2_512 +#define SADB_X_AALG_SHA2_512 (-1) +#endif +#ifndef SADB_X_AALG_RIPEMD160HMAC +#define SADB_X_AALG_RIPEMD160HMAC (-1) +#endif +#ifndef SADB_X_AALG_AES_XCBC_MAC +#define SADB_X_AALG_AES_XCBC_MAC (-1) +#endif +#ifndef SADB_X_EALG_TWOFISHCBC +#define SADB_X_EALG_TWOFISHCBC (-1) +#endif +#ifndef SADB_X_EALG_AESCTR +#define SADB_X_EALG_AESCTR (-1) +#endif +#if defined(SADB_X_EALG_AES) && ! defined(SADB_X_EALG_AESCBC) +#define SADB_X_EALG_AESCBC SADB_X_EALG_AES +#endif +%} + +/* common section */ +nl \n +ws [ \t]+ +digit [0-9] +letter [0-9A-Za-z] +hexdigit [0-9A-Fa-f] +dot \. +hyphen \- +slash \/ +blcl \[ +elcl \] +semi \; +comment \#.* +quotedstring \"[^"]*\" +decstring {digit}+ +hexstring 0[xX]{hexdigit}+ +ipaddress [a-fA-F0-9:]([a-fA-F0-9:\.]*|[a-fA-F0-9:\.]*%[a-zA-Z0-9]*) +ipaddrmask {slash}{digit}{1,3} +name {letter}(({letter}|{digit}|{hyphen})*({letter}|{digit}))* +hostname {name}(({dot}{name})+{dot}?)? + +%s S_PL S_AUTHALG S_ENCALG + +%option noinput nounput +%% + + +add { return(ADD); } +delete { return(DELETE); } +deleteall { return(DELETEALL); } +get { return(GET); } +flush { return(FLUSH); } +dump { return(DUMP); } +exit { return(EXIT); } +quit { return(EXIT); } +bye { return(EXIT); } + + /* for management SPD */ +spdadd { return(SPDADD); } +spdupdate { return(SPDUPDATE); } +spddelete { return(SPDDELETE); } +spddump { return(SPDDUMP); } +spdflush { return(SPDFLUSH); } +tagged { return(TAGGED); } +{hyphen}P { BEGIN S_PL; return(F_POLICY); } +[a-zA-Z0-9:\.\-_/ \n\t][a-zA-Z0-9:\.%\-+_/ \n\t\]\[]* { + yymore(); + + /* count up for nl */ + { + char *p; + for (p = yytext; *p != '\0'; p++) + if (*p == '\n') + lineno++; + } + + yylval.val.len = strlen(yytext); + yylval.val.buf = strdup(yytext); + if (!yylval.val.buf) + yyfatal("insufficient memory"); + + return(PL_REQUESTS); + } +{semi} { BEGIN INITIAL; return(EOT); } + + /* address resolution flags */ +{hyphen}[n46][n46]* { + yylval.val.len = strlen(yytext); + yylval.val.buf = strdup(yytext); + if (!yylval.val.buf) + yyfatal("insufficient memory"); + return(F_AIFLAGS); + } + + /* security protocols */ +ah { yylval.num = 0; return(PR_AH); } +esp { yylval.num = 0; return(PR_ESP); } +ah-old { yylval.num = 1; return(PR_AH); } +esp-old { yylval.num = 1; return(PR_ESP); } +esp-udp { yylval.num = 0; return(PR_ESPUDP); } +ipcomp { yylval.num = 0; return(PR_IPCOMP); } +tcp { + yylval.num = 0; return(PR_TCP); + } + + /* authentication alogorithm */ +{hyphen}A { BEGIN S_AUTHALG; return(F_AUTH); } +hmac-md5 { yylval.num = SADB_AALG_MD5HMAC; BEGIN INITIAL; return(ALG_AUTH); } +hmac-sha1 { yylval.num = SADB_AALG_SHA1HMAC; BEGIN INITIAL; return(ALG_AUTH); } +keyed-md5 { yylval.num = SADB_X_AALG_MD5; BEGIN INITIAL; return(ALG_AUTH); } +keyed-sha1 { yylval.num = SADB_X_AALG_SHA; BEGIN INITIAL; return(ALG_AUTH); } +hmac-sha2-256 { yylval.num = SADB_X_AALG_SHA2_256; BEGIN INITIAL; return(ALG_AUTH); } +hmac-sha256 { yylval.num = SADB_X_AALG_SHA2_256; BEGIN INITIAL; return(ALG_AUTH); } +hmac-sha2-384 { yylval.num = SADB_X_AALG_SHA2_384; BEGIN INITIAL; return(ALG_AUTH); } +hmac-sha384 { yylval.num = SADB_X_AALG_SHA2_384; BEGIN INITIAL; return(ALG_AUTH); } +hmac-sha2-512 { yylval.num = SADB_X_AALG_SHA2_512; BEGIN INITIAL; return(ALG_AUTH); } +hmac-sha512 { yylval.num = SADB_X_AALG_SHA2_512; BEGIN INITIAL; return(ALG_AUTH); } +hmac-ripemd160 { yylval.num = SADB_X_AALG_RIPEMD160HMAC; BEGIN INITIAL; return(ALG_AUTH); } +aes-xcbc-mac { yylval.num = SADB_X_AALG_AES_XCBC_MAC; BEGIN INITIAL; return(ALG_AUTH); } +tcp-md5 { +#ifdef SADB_X_AALG_TCP_MD5 + yylval.num = SADB_X_AALG_TCP_MD5; + BEGIN INITIAL; + return(ALG_AUTH); +#endif + } +null { yylval.num = SADB_X_AALG_NULL; BEGIN INITIAL; return(ALG_AUTH_NOKEY); } + + /* encryption alogorithm */ +{hyphen}E { BEGIN S_ENCALG; return(F_ENC); } +des-cbc { yylval.num = SADB_EALG_DESCBC; BEGIN INITIAL; return(ALG_ENC); } +3des-cbc { yylval.num = SADB_EALG_3DESCBC; BEGIN INITIAL; return(ALG_ENC); } +null { yylval.num = SADB_EALG_NULL; BEGIN INITIAL; return(ALG_ENC_NOKEY); } +simple { yylval.num = SADB_EALG_NULL; BEGIN INITIAL; return(ALG_ENC_OLD); } +blowfish-cbc { yylval.num = SADB_X_EALG_BLOWFISHCBC; BEGIN INITIAL; return(ALG_ENC); } +cast128-cbc { yylval.num = SADB_X_EALG_CAST128CBC; BEGIN INITIAL; return(ALG_ENC); } +des-deriv { yylval.num = SADB_EALG_DESCBC; BEGIN INITIAL; return(ALG_ENC_DESDERIV); } +des-32iv { yylval.num = SADB_EALG_DESCBC; BEGIN INITIAL; return(ALG_ENC_DES32IV); } +twofish-cbc { yylval.num = SADB_X_EALG_TWOFISHCBC; BEGIN INITIAL; return(ALG_ENC); } +aes-cbc { +#ifdef SADB_X_EALG_AESCBC + yylval.num = SADB_X_EALG_AESCBC; BEGIN INITIAL; return(ALG_ENC); +#endif +} +rijndael-cbc { +#ifdef SADB_X_EALG_AESCBC + yylval.num = SADB_X_EALG_AESCBC; BEGIN INITIAL; return(ALG_ENC); +#endif +} +aes-ctr { yylval.num = SADB_X_EALG_AESCTR; BEGIN INITIAL; return(ALG_ENC); } +camellia-cbc { +#ifdef SADB_X_EALG_CAMELLIACBC + yylval.num = SADB_X_EALG_CAMELLIACBC; BEGIN INITIAL; return(ALG_ENC); +#endif +} + + /* compression algorithms */ +{hyphen}C { return(F_COMP); } +oui { yylval.num = SADB_X_CALG_OUI; return(ALG_COMP); } +deflate { yylval.num = SADB_X_CALG_DEFLATE; return(ALG_COMP); } +lzs { yylval.num = SADB_X_CALG_LZS; return(ALG_COMP); } +{hyphen}R { return(F_RAWCPI); } + + /* extension */ +{hyphen}m { return(F_MODE); } +transport { yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); } +tunnel { yylval.num = IPSEC_MODE_TUNNEL; return(MODE); } +{hyphen}u { return(F_REQID); } +{hyphen}f { return(F_EXT); } +random-pad { yylval.num = SADB_X_EXT_PRAND; return(EXTENSION); } +seq-pad { yylval.num = SADB_X_EXT_PSEQ; return(EXTENSION); } +zero-pad { yylval.num = SADB_X_EXT_PZERO; return(EXTENSION); } +nocyclic-seq { return(NOCYCLICSEQ); } +{hyphen}r { return(F_REPLAY); } +{hyphen}lh { return(F_LIFETIME_HARD); } +{hyphen}ls { return(F_LIFETIME_SOFT); } +{hyphen}bh { return(F_LIFEBYTE_HARD); } +{hyphen}bs { return(F_LIFEBYTE_SOFT); } +{hyphen}ctx { return(SECURITY_CTX); } + + /* ... */ +any { return(ANY); } +{ws} { } +{nl} { lineno++; } +{comment} +{semi} { return(EOT); } + + /* for address parameters: /prefix, [port] */ +{slash} { return SLASH; } +{blcl} { return BLCL; } +{elcl} { return ELCL; } + + /* parameter */ +{decstring} { + char *bp; + + yylval.ulnum = strtoul(yytext, &bp, 10); + return(DECSTRING); + } + +{hexstring} { + yylval.val.buf = strdup(yytext + 2); + if (!yylval.val.buf) + yyfatal("insufficient memory"); + yylval.val.len = strlen(yylval.val.buf); + + return(HEXSTRING); + } + +{quotedstring} { + char *p = yytext; + while (*++p != '"') ; + *p = '\0'; + yytext++; + yylval.val.len = yyleng - 2; + yylval.val.buf = strdup(yytext); + if (!yylval.val.buf) + yyfatal("insufficient memory"); + + return(QUOTEDSTRING); + } + +[A-Za-z0-9:][A-Za-z0-9:%\.-]* { + yylval.val.len = yyleng; + yylval.val.buf = strdup(yytext); + if (!yylval.val.buf) + yyfatal("insufficient memory"); + return(STRING); + } + +[0-9,]+ { + yylval.val.len = yyleng; + yylval.val.buf = strdup(yytext); + if (!yylval.val.buf) + yyfatal("insufficient memory"); + return(STRING); + } + +. { + yyfatal("Syntax error"); + /*NOTREACHED*/ + } + +%% + +void +yyfatal(s) + const char *s; +{ + yyerror(s); + exit(1); +} + +void +yyerror(s) + const char *s; +{ + printf("line %d: %s at [%s]\n", lineno, s, yytext); +} + +int +parse(fp) + FILE **fp; +{ + yyin = *fp; + + lineno = 1; + parse_init(); + + if (yyparse()) { + printf("parse failed, line %d.\n", lineno); + return(-1); + } + + return(0); +} + +int +parse_string (char *src) +{ + int result; + YY_BUFFER_STATE buf_state; + + buf_state = yy_scan_string(src); + result = yyparse(); + yy_delete_buffer(buf_state); + return result; +} + diff --git a/ipsec-tools/src/setkey/vchar.h b/ipsec-tools/src/setkey/vchar.h new file mode 100644 index 00000000..5529291a --- /dev/null +++ b/ipsec-tools/src/setkey/vchar.h @@ -0,0 +1,42 @@ +/* $NetBSD: vchar.h,v 1.4 2006/09/09 16:22:37 manu Exp $ */ + +/* Id: vchar.h,v 1.2 2004/06/07 09:18:47 ludvigm Exp */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _VCHAR_H +#define _VCHAR_H + +typedef struct { + u_int len; + caddr_t buf; +} vchar_t; + +#endif /* _VCHAR_H */ diff --git a/ipsec-tools/test-driver b/ipsec-tools/test-driver new file mode 100755 index 00000000..32bf39e8 --- /dev/null +++ b/ipsec-tools/test-driver @@ -0,0 +1,127 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2012-06-27.10; # UTC + +# Copyright (C) 2011-2013 Free Software Foundation, Inc. +# +# 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, or (at your option) +# any later version. +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <$log_file 2>&1 +estatus=$? +if test $enable_hard_errors = no && test $estatus -eq 99; then + estatus=1 +fi + +case $estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/ipsec-tools/ylwrap b/ipsec-tools/ylwrap new file mode 100755 index 00000000..92536350 --- /dev/null +++ b/ipsec-tools/ylwrap @@ -0,0 +1,226 @@ +#! /bin/sh +# ylwrap - wrapper for lex/yacc invocations. + +scriptversion=2011-08-25.18; # UTC + +# Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005, +# 2007, 2009, 2010, 2011 Free Software Foundation, Inc. +# +# Written by Tom Tromey . +# +# 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, or (at your option) +# any later version. +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +case "$1" in + '') + echo "$0: No files given. Try \`$0 --help' for more information." 1>&2 + exit 1 + ;; + --basedir) + basedir=$2 + shift 2 + ;; + -h|--h*) + cat <<\EOF +Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... + +Wrapper for lex/yacc invocations, renaming files as desired. + + INPUT is the input file + OUTPUT is one file PROG generates + DESIRED is the file we actually want instead of OUTPUT + PROGRAM is program to run + ARGS are passed to PROG + +Any number of OUTPUT,DESIRED pairs may be used. + +Report bugs to . +EOF + exit $? + ;; + -v|--v*) + echo "ylwrap $scriptversion" + exit $? + ;; +esac + + +# The input. +input="$1" +shift +case "$input" in + [\\/]* | ?:[\\/]*) + # Absolute path; do nothing. + ;; + *) + # Relative path. Make it absolute. + input="`pwd`/$input" + ;; +esac + +pairlist= +while test "$#" -ne 0; do + if test "$1" = "--"; then + shift + break + fi + pairlist="$pairlist $1" + shift +done + +# The program to run. +prog="$1" +shift +# Make any relative path in $prog absolute. +case "$prog" in + [\\/]* | ?:[\\/]*) ;; + *[\\/]*) prog="`pwd`/$prog" ;; +esac + +# FIXME: add hostname here for parallel makes that run commands on +# other machines. But that might take us over the 14-char limit. +dirname=ylwrap$$ +do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret' +trap "ret=129; $do_exit" 1 +trap "ret=130; $do_exit" 2 +trap "ret=141; $do_exit" 13 +trap "ret=143; $do_exit" 15 +mkdir $dirname || exit 1 + +cd $dirname + +case $# in + 0) "$prog" "$input" ;; + *) "$prog" "$@" "$input" ;; +esac +ret=$? + +if test $ret -eq 0; then + set X $pairlist + shift + first=yes + # Since DOS filename conventions don't allow two dots, + # the DOS version of Bison writes out y_tab.c instead of y.tab.c + # and y_tab.h instead of y.tab.h. Test to see if this is the case. + y_tab_nodot="no" + if test -f y_tab.c || test -f y_tab.h; then + y_tab_nodot="yes" + fi + + # The directory holding the input. + input_dir=`echo "$input" | sed -e 's,\([\\/]\)[^\\/]*$,\1,'` + # Quote $INPUT_DIR so we can use it in a regexp. + # FIXME: really we should care about more than `.' and `\'. + input_rx=`echo "$input_dir" | sed 's,\\\\,\\\\\\\\,g;s,\\.,\\\\.,g'` + + while test "$#" -ne 0; do + from="$1" + # Handle y_tab.c and y_tab.h output by DOS + if test $y_tab_nodot = "yes"; then + if test $from = "y.tab.c"; then + from="y_tab.c" + else + if test $from = "y.tab.h"; then + from="y_tab.h" + fi + fi + fi + if test -f "$from"; then + # If $2 is an absolute path name, then just use that, + # otherwise prepend `../'. + case "$2" in + [\\/]* | ?:[\\/]*) target="$2";; + *) target="../$2";; + esac + + # We do not want to overwrite a header file if it hasn't + # changed. This avoid useless recompilations. However the + # parser itself (the first file) should always be updated, + # because it is the destination of the .y.c rule in the + # Makefile. Divert the output of all other files to a temporary + # file so we can compare them to existing versions. + if test $first = no; then + realtarget="$target" + target="tmp-`echo $target | sed s/.*[\\/]//g`" + fi + # Edit out `#line' or `#' directives. + # + # We don't want the resulting debug information to point at + # an absolute srcdir; it is better for it to just mention the + # .y file with no path. + # + # We want to use the real output file name, not yy.lex.c for + # instance. + # + # We want the include guards to be adjusted too. + FROM=`echo "$from" | sed \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\ + -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'` + TARGET=`echo "$2" | sed \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\ + -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'` + + sed -e "/^#/!b" -e "s,$input_rx,," -e "s,$from,$2," \ + -e "s,$FROM,$TARGET," "$from" >"$target" || ret=$? + + # Check whether header files must be updated. + if test $first = no; then + if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then + echo "$2" is unchanged + rm -f "$target" + else + echo updating "$2" + mv -f "$target" "$realtarget" + fi + fi + else + # A missing file is only an error for the first file. This + # is a blatant hack to let us support using "yacc -d". If -d + # is not specified, we don't want an error when the header + # file is "missing". + if test $first = yes; then + ret=1 + fi + fi + shift + shift + first=no + done +else + ret=$? +fi + +# Remove the directory. +cd .. +rm -rf $dirname + +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: -- cgit v1.2.3