From 2d74f24bd2f173e04bb170a42ed0195a15231537 Mon Sep 17 00:00:00 2001 From: manu Date: Sat, 9 Sep 2006 16:11:26 +0000 Subject: [PATCH] Migrate ipsec-tools CVS to cvs.netbsd.org --- crypto/dist/ipsec-tools/ChangeLog | 905 +++- crypto/dist/ipsec-tools/Makefile.am | 2 + crypto/dist/ipsec-tools/NEWS | 22 +- crypto/dist/ipsec-tools/bootstrap | 12 +- crypto/dist/ipsec-tools/configure.ac | 284 +- crypto/dist/ipsec-tools/src/Makefile.am | 2 + .../src/libipsec/ipsec_dump_policy.c | 4 +- .../dist/ipsec-tools/src/libipsec/key_debug.c | 36 +- .../dist/ipsec-tools/src/libipsec/libpfkey.h | 9 +- crypto/dist/ipsec-tools/src/libipsec/pfkey.c | 100 +- .../ipsec-tools/src/libipsec/pfkey_dump.c | 90 +- .../ipsec-tools/src/libipsec/policy_token.l | 7 +- .../dist/ipsec-tools/src/racoon/Makefile.am | 2 +- crypto/dist/ipsec-tools/src/racoon/admin.c | 97 +- crypto/dist/ipsec-tools/src/racoon/admin.h | 9 +- .../dist/ipsec-tools/src/racoon/algorithm.c | 62 +- .../dist/ipsec-tools/src/racoon/algorithm.h | 8 +- crypto/dist/ipsec-tools/src/racoon/backupsa.c | 4 +- crypto/dist/ipsec-tools/src/racoon/cfparse.y | 632 ++- crypto/dist/ipsec-tools/src/racoon/cftoken.l | 106 +- .../ipsec-tools/src/racoon/crypto_openssl.c | 31 +- crypto/dist/ipsec-tools/src/racoon/debugrm.c | 21 +- crypto/dist/ipsec-tools/src/racoon/debugrm.h | 12 +- crypto/dist/ipsec-tools/src/racoon/dnssec.c | 9 +- crypto/dist/ipsec-tools/src/racoon/doc/FAQ | 8 + crypto/dist/ipsec-tools/src/racoon/eaytest.c | 4 +- crypto/dist/ipsec-tools/src/racoon/evt.c | 13 +- crypto/dist/ipsec-tools/src/racoon/evt.h | 6 +- crypto/dist/ipsec-tools/src/racoon/gcmalloc.h | 13 +- .../ipsec-tools/src/racoon/getcertsbyname.c | 5 +- .../dist/ipsec-tools/src/racoon/grabmyaddr.c | 13 +- crypto/dist/ipsec-tools/src/racoon/gssapi.c | 16 +- crypto/dist/ipsec-tools/src/racoon/handler.c | 514 +- crypto/dist/ipsec-tools/src/racoon/handler.h | 16 +- .../dist/ipsec-tools/src/racoon/ipsec_doi.c | 464 +- .../dist/ipsec-tools/src/racoon/ipsec_doi.h | 17 +- crypto/dist/ipsec-tools/src/racoon/isakmp.c | 615 ++- crypto/dist/ipsec-tools/src/racoon/isakmp.h | 6 +- .../dist/ipsec-tools/src/racoon/isakmp_agg.c | 328 +- .../dist/ipsec-tools/src/racoon/isakmp_base.c | 337 +- .../dist/ipsec-tools/src/racoon/isakmp_cfg.c | 717 ++- .../dist/ipsec-tools/src/racoon/isakmp_cfg.h | 92 +- .../dist/ipsec-tools/src/racoon/isakmp_frag.h | 5 +- .../ipsec-tools/src/racoon/isakmp_ident.c | 235 +- .../dist/ipsec-tools/src/racoon/isakmp_inf.c | 653 +-- .../dist/ipsec-tools/src/racoon/isakmp_inf.h | 7 +- .../ipsec-tools/src/racoon/isakmp_quick.c | 61 +- .../ipsec-tools/src/racoon/isakmp_unity.c | 243 +- .../ipsec-tools/src/racoon/isakmp_unity.h | 27 +- .../dist/ipsec-tools/src/racoon/isakmp_var.h | 8 +- .../ipsec-tools/src/racoon/isakmp_xauth.c | 799 ++- .../ipsec-tools/src/racoon/isakmp_xauth.h | 65 +- crypto/dist/ipsec-tools/src/racoon/kmpstat.c | 4 +- .../dist/ipsec-tools/src/racoon/localconf.c | 38 +- .../dist/ipsec-tools/src/racoon/localconf.h | 7 +- crypto/dist/ipsec-tools/src/racoon/logger.c | 6 +- crypto/dist/ipsec-tools/src/racoon/main.c | 64 +- crypto/dist/ipsec-tools/src/racoon/misc.h | 18 +- .../ipsec-tools/src/racoon/nattraversal.c | 19 +- crypto/dist/ipsec-tools/src/racoon/oakley.c | 173 +- crypto/dist/ipsec-tools/src/racoon/oakley.h | 28 +- crypto/dist/ipsec-tools/src/racoon/pfkey.c | 73 +- .../ipsec-tools/src/racoon/plainrsa-gen.8 | 14 +- .../ipsec-tools/src/racoon/plainrsa-gen.c | 4 +- crypto/dist/ipsec-tools/src/racoon/plog.c | 41 +- crypto/dist/ipsec-tools/src/racoon/plog.h | 16 +- crypto/dist/ipsec-tools/src/racoon/privsep.c | 303 +- crypto/dist/ipsec-tools/src/racoon/privsep.h | 11 +- crypto/dist/ipsec-tools/src/racoon/proposal.c | 45 +- crypto/dist/ipsec-tools/src/racoon/proposal.h | 5 +- crypto/dist/ipsec-tools/src/racoon/racoon.8 | 4 +- .../dist/ipsec-tools/src/racoon/racoon.conf.5 | 297 +- .../dist/ipsec-tools/src/racoon/racoonctl.8 | 13 +- .../dist/ipsec-tools/src/racoon/racoonctl.c | 92 +- .../dist/ipsec-tools/src/racoon/racoonctl.h | 6 +- .../dist/ipsec-tools/src/racoon/remoteconf.c | 114 +- .../dist/ipsec-tools/src/racoon/remoteconf.h | 26 +- .../ipsec-tools/src/racoon/rfc/rfc2367.txt | 3811 +++++++++++++ .../ipsec-tools/src/racoon/rfc/rfc2407.txt | 1795 ++++++ .../ipsec-tools/src/racoon/rfc/rfc2408.txt | 4819 +++++++++++++++++ .../ipsec-tools/src/racoon/rfc/rfc3706.txt | 731 +++ .../ipsec-tools/src/racoon/rfc/rfc3715.txt | 1011 ++++ .../ipsec-tools/src/racoon/rfc/rfc4109.txt | 282 + crypto/dist/ipsec-tools/src/racoon/sainfo.c | 109 +- crypto/dist/ipsec-tools/src/racoon/sainfo.h | 12 +- .../src/racoon/samples/racoon.conf.in | 2 +- .../src/racoon/samples/racoon.conf.sample | 10 +- .../racoon/samples/racoon.conf.sample-inherit | 4 +- .../racoon/samples/racoon.conf.sample-natt | 4 +- .../samples/racoon.conf.sample-plainrsa | 4 +- .../samples/roadwarrior/client/phase1-up.sh | 2 +- .../samples/roadwarrior/client/racoon.conf | 2 +- .../samples/roadwarrior/server/racoon.conf | 2 +- .../roadwarrior/server/racoon.conf-radius | 2 +- crypto/dist/ipsec-tools/src/racoon/schedule.c | 4 +- crypto/dist/ipsec-tools/src/racoon/schedule.h | 6 +- crypto/dist/ipsec-tools/src/racoon/session.c | 195 +- crypto/dist/ipsec-tools/src/racoon/sockmisc.c | 38 +- crypto/dist/ipsec-tools/src/racoon/sockmisc.h | 4 +- crypto/dist/ipsec-tools/src/racoon/strnames.c | 157 +- crypto/dist/ipsec-tools/src/racoon/strnames.h | 8 +- crypto/dist/ipsec-tools/src/racoon/throttle.c | 16 +- crypto/dist/ipsec-tools/src/racoon/vendorid.c | 13 +- crypto/dist/ipsec-tools/src/racoon/vendorid.h | 17 +- crypto/dist/ipsec-tools/src/racoon/vmbuf.c | 8 +- crypto/dist/ipsec-tools/src/racoon/vmbuf.h | 9 +- crypto/dist/ipsec-tools/src/setkey/parse.y | 94 +- crypto/dist/ipsec-tools/src/setkey/setkey.8 | 54 +- crypto/dist/ipsec-tools/src/setkey/setkey.c | 20 +- crypto/dist/ipsec-tools/src/setkey/token.l | 6 +- 110 files changed, 20395 insertions(+), 2030 deletions(-) create mode 100644 crypto/dist/ipsec-tools/src/racoon/rfc/rfc2367.txt create mode 100644 crypto/dist/ipsec-tools/src/racoon/rfc/rfc2407.txt create mode 100644 crypto/dist/ipsec-tools/src/racoon/rfc/rfc2408.txt create mode 100644 crypto/dist/ipsec-tools/src/racoon/rfc/rfc3706.txt create mode 100644 crypto/dist/ipsec-tools/src/racoon/rfc/rfc3715.txt create mode 100644 crypto/dist/ipsec-tools/src/racoon/rfc/rfc4109.txt diff --git a/crypto/dist/ipsec-tools/ChangeLog b/crypto/dist/ipsec-tools/ChangeLog index d36670a729d94..e235e59ed975b 100644 --- a/crypto/dist/ipsec-tools/ChangeLog +++ b/crypto/dist/ipsec-tools/ChangeLog @@ -1,6 +1,333 @@ --------------------------------------------- - 0.6.3 released + 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 @@ -15,18 +342,43 @@ using IKE test suite from http://www.ee.oulu.fi/research/ouspg/protos/testing/c09/isakmp/ -2005-11-06 Aidas Kasparas +2005-11-10 Yvan Vanhullebus - * 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 + 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 @@ -37,41 +389,28 @@ * src/racoon/ipsec-doi.c: adopted to above * src/racoon/racoon.conf.5: documented above -2005-10-14 Emmanuel Dreyfus +2005-09-14 Emmanuel Dreyfus * src/libipsec/pfkey.c: One forgotten cast caddr_t -> void * ---------------------------------------------- - - 0.6.2 released - 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). ---------------------------------------------- - - 0.6.2.beta3 released +2005-09-10 Emmanuel Dreyfus -2005-09-05 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. - From Andreas Hasenack - * configure.ac: More build fixes for Linux - ---------------------------------------------- - - 0.6.2.beta2 released - -2005-09-04 Emmanuel Dreyfus - - From Wilfried Weissmann - * src/libipsec/policy_parse.y src/racoon/{ipsec_doi.c|oakley.c} +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 ---------------------------------------------- - - 0.6.2.beta1 released 2005-09-03 Emmanuel Dreyfus @@ -80,10 +419,6 @@ 2005-08-26 Emmanuel Dreyfus - * src/racoon/cfparse.y: handle xauth_login correctly - * src/racoon/isakmp.c: catch internal error - * src/raccon/isakmp_agg.c: fix racoon as Xauth client - * src/raccon/{isakmp_agg.c|isakmp_base.c}: Proposal safety checks * src/racoon/evt.c: Fix memory leak when event queue overflows 2005-08-23 Emmanuel Dreyfus @@ -97,19 +432,20 @@ * src/racoon/{isakmp_cfg.c|racoon.conf.5}: enable the use of ISAKMP mode config without Xauth. -2005-09-16 Yvan Vanhullebus +2005-08-16 Emmanuel Dreyfus - * src/racoon/policy.c: Do not parse all sptree in inssp() if we - don't use Policies priority. + From Thomas Klausner + * src/setkey/setkey.8: remove trailing whitespaces -2005-08-15 Emmanuel Dreyfus +2005-09-09 Yvan Vanhullebus - From: Thomas Klausner - src/setkey/setkey.8: Drop trailing spaces + * src/racoon/policy.c: Do not parse all sptree in inssp() if we + don't use Policies priority. ---------------------------------------------- +2005-08-20 Yvan Vanhullebus - 0.6.1 released + * src/racoon/handler.c: Fixed a possible crash in + remove_ph2(). Reported by Dietmar Eggemann. 2005-08-14 Emmanuel Dreyfus @@ -130,10 +466,6 @@ * src/racoon/privsep.c: Fixed a %d -> %zu in port_check() (reported by Matthias Scheler). ---------------------------------------------- - - 0.6.1.rc1 released - 2005-08-04 Emmanuel Dreyfus * configure.ac: correctly quote RACOON_PATH_LIBS arguments @@ -143,10 +475,6 @@ * src/racoon/isakmp_inf.c: First fix to info_recv_initialcontact(): do a basic IP check when no NAT-T. -2005-07-28 Emmanuel Dreyfus - - * src/racoon/{pfkey.c|proposal.c}: IPcomp CPI size fixes - 2005-07-26 Yvan Vanhullebus * src/racoon/isakmp.c: Fixed purge_remote() @@ -156,19 +484,19 @@ * src/racoon/isakmp.c: Do not purge IPSec SAs in purge_remote() if a new ph1handle exists (patch by Krzysztof Oledzki) ---------------------------------------------- - - 0.6.1.beta3 released - 2005-07-20 Aidas Kasparas - * configure.ac: disabled --enable-samode-unspec for linux + * 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 @@ -180,27 +508,24 @@ * src/racoon/grabmyaddr.c: fixed file descriptor leak. Thanks to Patrice Fournier - * src/setkey/setkey.c: disabled readline's filename completion. - Fixed bug 1179281. + * 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. + complex_bundle on behind NAT 2005-07-14 Yvan Vanhullebus - * src/racoon/handler.c: Clears the DPD schedule in delph1() - ---------------------------------------------- - - 0.6.1.beta2 released + * 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 - * src/racoon/isakmp_inf.c: build fix - ---------------------------------------------- - - 0.6.1.beta1 released 2005-07-12 Yvan Vanhullebus @@ -217,14 +542,15 @@ * src/racoon/samples/roadwarrior/client/{pahse1-up.sh|phase1-down.sh}: Add comments for using the scripts without NAT-T -2005-07-04 Emmanuel Dreyfus +2005-07-11 Emmanuel Dreyfus - * src/racoon/isakmp_inf.c: safety checks on informational messages + * src/racoon/ipsec_doi.c configure.ac: More build fixes on Linux. + Accomodate various libiconv versions -2005-07-11 Emmanuel Dreyfus +2005-07-10 Emmanuel Dreyfus - * configure.ac: build fixes on Linux. Accomodate various libiconv - versions + * src/racoon/ipsec_doi.c configure.ac: build fixes on Linux. + Accomodate various libiconv versions 2005-07-09 Yvan Vanhullebus @@ -238,20 +564,21 @@ * src/racoon/raccon.conf.5: Document that aes can be used in racoon.conf -2005-07-06 Emmanuel Dreyfus - - * src/setkey/extern.h: new file (was missing in previous commit) - 2005-07-06 Frederic Senault * src/setkey/setkey.c: fix compilation with readline. - * src/racoon/oakley.c: move declarations to the top of the function - to fix compilation issues with gcc 2.95.4/FreeBSD4, re-indentation - and style cleanup of the pkcs7 patch. + * 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 : + From Uri Blumenthal : * src/racoon/{ipsec_doi.c|Makefile.am}: Linux build fixes * src/racoon/oakley.c: pkcs7 support @@ -267,18 +594,17 @@ src/racoon/{sockmisc.c|sockmisc.h}: de-lint signed/unsigned, size_t/int and lint constants -2005-06-29 Emmanuel Dreyfus +2005-06-24 Yvan Vanhullebus - From Uri 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/racoon/handler.c: Fixed phase2 enc algo check when reloading + conf (could flush a phase2 handler when not needed). ---------------------------------------------- - - 0.6 released +2005-06-19 Emmanuel Dreyfus -2005-06-22 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 @@ -287,23 +613,33 @@ on phase 2 initiation retries when the phase 2 had been queued for a phase 1. ---------------------------------------------- - - 0.6rc1 released + 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-15 Emmanuel Dreyfus +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 - From Frederic Senault - * src/racoon/privsep.c: fix Xauth login with PAM authentication - 2005-06-05 Emmanuel Dreyfus From Thomas Klausner @@ -315,13 +651,18 @@ * src/racoon/ipsec_doi.c: Inserted missing 0th element of rm_idtype2doi array. Bug #1199700 fix. -2005-05-23 Emmanuel Dreyfus +2005-05-30 Frederic Senault - * src/racoon/admin.c: build fix + * 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. - 0.6b3 released +2005-05-23 Emmanuel Dreyfus + + * src/racoon/admin.c: build fix 2005-05-20 Emmanuel Dreyfus @@ -334,17 +675,31 @@ * src/racoon/proposal.c: fix SPI size test for IPcomp From Larry Baird - * src/racoon/{handler.c|ipsec_doi.c|remoteconf.h|remoteconf.c}: When - altering lifetime, duplicate the proposal instead of modifying - the configured one. + * 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). - From Frederic Senault * 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 bug in IPsec policies + * src/libipsec/policy_parse.y: Fix parse problem 2005-05-14 Aidas Kasparas @@ -353,10 +708,7 @@ 2005-05-13 Emmanuel Dreyfus - * src/racoon/isakmp.c: For acquire messages, when NAT-T is in use, - consider null port as a wildcard and use IKE port - - * src/racoon/isakmp.c: Build fix + * src/racoon/isakmp_inf.c: fix build problem 2005-05-13 Yvan Vanhullebus @@ -365,37 +717,46 @@ 2005-05-12 Emmanuel Dreyfus - * src/racoon/{proposal.c|proposal.h|isakmp_quick.c}: fix build problem - ---------------------------------------------- + * src/racoon/isakmp_quick.c: fix build problem on some platforms - 0.6b2 released + * 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/client/racoon.conf - src/racoon/samples/roadwarrior/server/{racoon.conf|racoon.conf-radius} + * src/racoon/samples/roadwarrior/server/{racoon.conf|racoon.conf-radius} src/racoon/samples/roadwarrior/server/phase1-down.sh: removed file - src/racoon/samples/roadwarrior/README: update config files to - higher security settings. Remove now useless phase 1 down + 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-10 Emmanuel Dreyfus +2005-05-09 Emmanuel Dreyfus - * src/racoon/ipsec_doi.c: check for lifebyte in proposals - * src/racoon/ipsec_doi.c: fix a bug in proposal_check claim for phase 1 - - * src/racoon/{cfparse.y|cftoken.l|racoon.conf.5|isakmp_cfg.c} - src/racoon/{isakmp_cfg.h|isakmp_unity.c}: add Cisco extensions for - sending PFS group and save password through ISAKMP mode config. + * 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 - * configure.ac src/racoon/isakmp_xauth.c: Support shadow passwords + * 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 - * src/racoon/{admin.c|isakmp.c|isakmp_inf.c}: factor various + * 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 @@ -406,6 +767,24 @@ * 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 @@ -417,6 +796,11 @@ 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 @@ -430,33 +814,63 @@ * configure.ac: Revert GLIBC_BUGS change from 2005-04-15 -2005-05-03 Emmanuel Dreyfus +2005-05-03 Frederic Senault - From Patrick McHardy - * src/racoon/{pfkey.c|handler.h|hendler.c}: on phase 2 acquire, - lookup phase 2 by (src, dst, policy id) so that multiple SA can - be used in transport mode + * 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 initiator problem + * 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/libipsec/{ipsec_dump_policy.c|pfkey_dump.c|libpfkey.h}: + * 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/{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. * 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. + NAT-T fixes for interoperability with greenbow VPN client. 2005-04-21 Aidas Kasparas @@ -467,8 +881,8 @@ 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) + src/racoon/sockmisc.h, src/racoon/racoonctl.c: made compile + with gcc-4.0 (20050410 prerelease) 2005-04-20 Aidas Kasparas @@ -477,13 +891,7 @@ 2005-04-19 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() + * src/racoon/remoteconf.c: fixed dupisakmpsa() and dhgroup. 2005-04-18 Aidas Kasparas @@ -491,6 +899,8 @@ * 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} @@ -507,6 +917,32 @@ 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 : @@ -515,13 +951,85 @@ - --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_agg.c: fix a memory leak when using hybrid auth - * src/libipsec/{pfkey.c|pfkey_dump.c} - src/setkey/{token.l|parse.y|setkey.8}: missing bits for TCP_MD5 - support, from KAME + * 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 @@ -531,10 +1039,6 @@ * configure.ac: Don't compile with NAT-T by default (according to documentation, finally :-) - * 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-03-27 Michal Ludvig @@ -545,26 +1049,20 @@ * acracoon.m4(RACOON_CHECK_VA_COPY): Allow cross-compilation. (RACOON_CHECK_BUGGY_GETADDRINFO): Ditto. ---------------------------------------------- - - 0.6b1 released - -2005-03-22 Emmanuel Dreyfus - - * src/racoon/privsep.c: fix the build without --with-libpam - 2005-03-16 Emmanuel Dreyfus - * src/racoon/{cftoken.l|localconf.h|privsep.c|racoon.conf.5} - src/racoon/remoteconf.c: When running in privsep mode, check that - private key and script paths match those given in the path section. + * src/racoon/privsep.c: check for NULL path in unsafe_path() + * src/racoon/privsep.c: missing space 2005-03-15 Emmanuel Dreyfus - * src/racoon/{isakmp_cfg|isakmp_cfg.h|isakmp_xauth.c}: initialize - RADIUS accounting at startup - * src/racoon/privsep.c: fix minor bug in PAM cleanup - * src/racoon/isakmp_cfg.c: only call cleanup_pam if PAM is used + * 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 @@ -575,10 +1073,30 @@ * 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 @@ -589,34 +1107,35 @@ * 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 + + * src/racoon/privsep.c: safety check port numbers given by the unprivilegied instance. - * src/libipsec/libpfkey.h: prefer __inline to inline * src/racoon/racoonctl.8: display fixes in racoonctl(8) - * src/racoon/{cfparse.y|cftoken.l|localconf.c|localconf.h|privsep.c} - src/racoon/racoon.conf.5: Add chroot capability - + 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 + * 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 Yvan Vanhullebus +2005-02-18 Michal Ludvig - * src/racoon/isakmp_inf.c: Purge generated SPDs when getting a - related DELETE_SA - * src/racoon/pfkey.c: do NOT unbindph12() when SA acquire + * 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 @@ -627,6 +1146,12 @@ * 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 diff --git a/crypto/dist/ipsec-tools/Makefile.am b/crypto/dist/ipsec-tools/Makefile.am index e3b1abf0f44ac..4f76e6e70fd6f 100644 --- a/crypto/dist/ipsec-tools/Makefile.am +++ b/crypto/dist/ipsec-tools/Makefile.am @@ -1,3 +1,5 @@ SUBDIRS = src @RPM@ +DIST_SUBDIRS = src rpm + EXTRA_DIST = bootstrap README NEWS depcomp diff --git a/crypto/dist/ipsec-tools/NEWS b/crypto/dist/ipsec-tools/NEWS index c0716156513d7..3ce98020ceb1f 100644 --- a/crypto/dist/ipsec-tools/NEWS +++ b/crypto/dist/ipsec-tools/NEWS @@ -1,17 +1,15 @@ Version history: ---------------- -0.6.3 - 21 November 2005 - o Various bug fixes - -0.6.2 - 14 October 2005 - o ISAKMP mode config works without Xauth - -0.6.1 - 10 august 2005 - o NAT-T fixes for situations where NAT-T is not used - o OpenSSL 0.9.8 support - o keys are not restricted to OpenSSL default size anymore - o PKCS7 support +0.7??? - ?? + 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 0.6 - 27 June 2005 o Generated policies are now correctly flushed @@ -23,7 +21,7 @@ Version history: 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 + o Fixed single DES support; single DES users MUST UPGRADE. 0.5 - 10 April 2005 o Rewritten buildsystem. Now completely autoconfed, automaked, diff --git a/crypto/dist/ipsec-tools/bootstrap b/crypto/dist/ipsec-tools/bootstrap index 9a680c7be34e7..1f2bdb66d9af8 100755 --- a/crypto/dist/ipsec-tools/bootstrap +++ b/crypto/dist/ipsec-tools/bootstrap @@ -2,12 +2,20 @@ 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 +${LIBTOOLIZE} --force --copy || exit 1 automake --foreign --add-missing --copy || exit 1 autoconf || exit 1 diff --git a/crypto/dist/ipsec-tools/configure.ac b/crypto/dist/ipsec-tools/configure.ac index 8b9c27cee5e21..f151c3aab0a5e 100644 --- a/crypto/dist/ipsec-tools/configure.ac +++ b/crypto/dist/ipsec-tools/configure.ac @@ -1,8 +1,8 @@ dnl -*- mode: m4 -*- -dnl Id: configure.ac,v 1.47.2.31 2005/11/21 11:11:41 manubsd Exp +dnl Id: configure.ac,v 1.77 2006/07/20 19:19:27 manubsd Exp AC_PREREQ(2.52) -AC_INIT(ipsec-tools, 0.6.3) +AC_INIT(ipsec-tools, CVS) AC_CONFIG_SRCDIR([configure.ac]) AM_CONFIG_HEADER(config.h) @@ -34,6 +34,9 @@ case $host in AC_SUBST(INCLUDE_GLIBC) AC_SUBST(RPM) ;; +*darwin*) + LIBS="$LIBS -lresolv" + ;; esac # Look up some IPsec-related headers @@ -122,7 +125,10 @@ AC_TRY_COMPILE([ printf("%zu\n", (size_t)-1); ], [AC_MSG_RESULT(yes)], - [AC_MSG_RESULT(no); CFLAGS_ADD="$CFLAGS_ADD -Wno-format"]) + [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? @@ -208,6 +214,9 @@ 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; @@ -263,54 +272,33 @@ AC_SUBST(EXTRA_CRYPTO) # For dynamic libradius RACOON_PATH_LIBS([MD5_Init], [crypto]) -# Check for Kerberos5 support -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`" +# 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 - # 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 + 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 $krb5_libs" - CPPFLAGS_ADD="$krb5_incdir $CPPFLAGS_ADD" - AC_DEFINE([HAVE_GSSAPI], [], [Enable GSS API]) - - # Check if iconv 2nd argument needs const - 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]) - saved_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS -Wall -Werror" - 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 + 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]) @@ -320,7 +308,13 @@ AC_ARG_ENABLE(hybrid, AC_MSG_RESULT($enable_hybrid) if test "x$enable_hybrid" = "xyes"; then - LIBS="$LIBS -lcrypt"; + 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]) @@ -333,7 +327,13 @@ AC_ARG_ENABLE(frag, AC_MSG_RESULT($enable_frag) if test "x$enable_frag" = "xyes"; then - LIBS="$LIBS -lcrypt"; + case $host in + *darwin*) + ;; + *) + LIBS="$LIBS -lcrypt"; + ;; + esac FRAG_OBJS="isakmp_frag.o" AC_SUBST(FRAG_OBJS) AC_DEFINE([ENABLE_FRAG], [], [IKE fragmentation support]) @@ -391,6 +391,135 @@ if test "$libpam_dir" != "no"; then 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], @@ -409,6 +538,15 @@ if test "x$enable_dpd" = "xyes"; then fi AC_MSG_RESULT($enable_dpd) +AC_MSG_CHECKING(if --enable-fastquit option is specified) +AC_ARG_ENABLE(fastquit, + [ --enable-fastquit enable new faster code to flush SAs when stopping racoon], + [], [enable_fastquit=no]) +if test "x$enable_fastquit" = "xyes"; then + AC_DEFINE([ENABLE_FASTQUIT], [], [Enable fast SA flush code]) +fi +AC_MSG_RESULT($enable_fastquit) + AC_MSG_CHECKING(if --enable-samode-unspec option is specified) AC_ARG_ENABLE(samode-unspec, @@ -559,6 +697,15 @@ 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*) @@ -585,6 +732,41 @@ AC_CHECK_TYPE([ipsec_policy_t], #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_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 + AC_DEFINE([HAVE_SECCTX], [], [Enable Security Context]) + SECCTX_OBJS="security.o" + AC_SUBST(SECCTX_OBJS) + fi +fi + CFLAGS="$CFLAGS $CFLAGS_ADD" CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD" diff --git a/crypto/dist/ipsec-tools/src/Makefile.am b/crypto/dist/ipsec-tools/src/Makefile.am index b28e4d66a2721..6d0d7802e74ef 100644 --- a/crypto/dist/ipsec-tools/src/Makefile.am +++ b/crypto/dist/ipsec-tools/src/Makefile.am @@ -1 +1,3 @@ SUBDIRS = @INCLUDE_GLIBC@ libipsec setkey racoon + +DIST_SUBDIRS = include-glibc libipsec setkey racoon diff --git a/crypto/dist/ipsec-tools/src/libipsec/ipsec_dump_policy.c b/crypto/dist/ipsec-tools/src/libipsec/ipsec_dump_policy.c index 78100b95d1785..21e842356bf0f 100644 --- a/crypto/dist/ipsec-tools/src/libipsec/ipsec_dump_policy.c +++ b/crypto/dist/ipsec-tools/src/libipsec/ipsec_dump_policy.c @@ -1,6 +1,6 @@ -/* $NetBSD: ipsec_dump_policy.c,v 1.1.1.3 2005/08/07 08:49:16 manu Exp $ */ +/* $NetBSD: ipsec_dump_policy.c,v 1.1.1.4 2006/09/09 16:11:30 manu Exp $ */ -/* Id: ipsec_dump_policy.c,v 1.7.4.2 2005/06/29 13:01:27 manubsd 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. diff --git a/crypto/dist/ipsec-tools/src/libipsec/key_debug.c b/crypto/dist/ipsec-tools/src/libipsec/key_debug.c index b0aa468ef60cc..e2c1d0bf89562 100644 --- a/crypto/dist/ipsec-tools/src/libipsec/key_debug.c +++ b/crypto/dist/ipsec-tools/src/libipsec/key_debug.c @@ -1,4 +1,4 @@ -/* $NetBSD: key_debug.c,v 1.1.1.4 2005/08/20 00:40:53 manu Exp $ */ +/* $NetBSD: key_debug.c,v 1.1.1.5 2006/09/09 16:11:34 manu Exp $ */ /* $KAME: key_debug.c,v 1.29 2001/08/16 14:25:41 itojun Exp $ */ @@ -46,6 +46,10 @@ #endif #endif +#if HAVE_STDINT_H +#include +#endif + #include #include #ifdef _KERNEL @@ -87,6 +91,10 @@ 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 _KERNEL static void kdebug_secreplay __P((struct secreplay *)); #endif @@ -184,6 +192,11 @@ kdebug_sadb(base) 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 default: printf("kdebug_sadb: invalid ext_type %u was passed.\n", @@ -527,6 +540,27 @@ kdebug_sadb_x_nat_t_port(struct sadb_ext *ext) } #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 _KERNEL /* %%%: about SPD and SAD */ void diff --git a/crypto/dist/ipsec-tools/src/libipsec/libpfkey.h b/crypto/dist/ipsec-tools/src/libipsec/libpfkey.h index bc1badfa74cb4..858e325c5e1ca 100644 --- a/crypto/dist/ipsec-tools/src/libipsec/libpfkey.h +++ b/crypto/dist/ipsec-tools/src/libipsec/libpfkey.h @@ -1,6 +1,6 @@ -/* $NetBSD: libpfkey.h,v 1.1.1.4 2005/08/07 08:49:20 manu Exp $ */ +/* $NetBSD: libpfkey.h,v 1.1.1.5 2006/09/09 16:11:34 manu Exp $ */ -/* Id: libpfkey.h,v 1.8.2.3 2005/06/29 13:01:28 manubsd Exp */ +/* Id: libpfkey.h,v 1.13 2005/12/04 20:26:43 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -46,6 +46,7 @@ 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 *)); @@ -134,6 +135,10 @@ 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 *, u_int, + struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t)); +#endif int pfkey_open __P((void)); void pfkey_close __P((int)); diff --git a/crypto/dist/ipsec-tools/src/libipsec/pfkey.c b/crypto/dist/ipsec-tools/src/libipsec/pfkey.c index f4d5c31505015..1701c937eaf79 100644 --- a/crypto/dist/ipsec-tools/src/libipsec/pfkey.c +++ b/crypto/dist/ipsec-tools/src/libipsec/pfkey.c @@ -1,4 +1,4 @@ -/* $NetBSD: pfkey.c,v 1.1.1.6 2005/11/21 14:12:18 manu Exp $ */ +/* $NetBSD: pfkey.c,v 1.1.1.7 2006/09/09 16:11:33 manu Exp $ */ /* $KAME: pfkey.c,v 1.47 2003/10/02 19:52:12 itojun Exp $ */ @@ -1198,6 +1198,100 @@ pfkey_send_spddump(so) 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(so, src, prefs, dst, prefd, proto, policy, policylen, seq) + int so; + struct sockaddr *src, *dst; + u_int prefs, prefd, 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; + } + + 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(src->sa_len) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(src->sa_len) + + 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; + } + 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(so, type, satype, mode, src, dst, spi, reqid, wsize, @@ -1971,7 +2065,9 @@ pfkey_align(msg, mhp) #ifdef SADB_X_EXT_PACKET case SADB_X_EXT_PACKET: #endif - +#ifdef SADB_X_EXT_SEC_CTX + case SADB_X_EXT_SEC_CTX: +#endif mhp[ext->sadb_ext_type] = (void *)ext; break; default: diff --git a/crypto/dist/ipsec-tools/src/libipsec/pfkey_dump.c b/crypto/dist/ipsec-tools/src/libipsec/pfkey_dump.c index d2192c32f0ed3..4959eba2b23bd 100644 --- a/crypto/dist/ipsec-tools/src/libipsec/pfkey_dump.c +++ b/crypto/dist/ipsec-tools/src/libipsec/pfkey_dump.c @@ -1,4 +1,4 @@ -/* $NetBSD: pfkey_dump.c,v 1.1.1.5 2005/10/14 13:21:44 manu Exp $ */ +/* $NetBSD: pfkey_dump.c,v 1.1.1.6 2006/09/09 16:11:31 manu Exp $ */ /* $KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $ */ @@ -107,10 +107,12 @@ do { \ } 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 { @@ -210,9 +212,25 @@ static struct val2str str_alg_comp[] = { /* * 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; @@ -227,6 +245,9 @@ pfkey_sadump(m) 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; @@ -234,6 +255,7 @@ pfkey_sadump(m) int use_natt = 0; #endif + struct sockaddr *sa; /* check pfkey message. */ if (pfkey_align(m, mhp)) { @@ -262,6 +284,9 @@ pfkey_sadump(m) 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]; @@ -276,7 +301,11 @@ pfkey_sadump(m) printf("no ADDRESS_SRC extension.\n"); return; } - printf("%s", str_ipaddr((void *)(m_saddr + 1))); + 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)); @@ -288,7 +317,11 @@ pfkey_sadump(m) printf(" no ADDRESS_DST extension.\n"); return; } - printf("%s", str_ipaddr((void *)(m_daddr + 1))); + 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)); @@ -408,6 +441,19 @@ pfkey_sadump(m) 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); @@ -445,6 +491,9 @@ pfkey_spdump1(m, withports) #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; @@ -467,6 +516,9 @@ pfkey_spdump1(m, withports) 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 @@ -571,6 +623,18 @@ pfkey_spdump1(m, withports) (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, @@ -602,6 +666,26 @@ str_ipaddr(sa) 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. */ diff --git a/crypto/dist/ipsec-tools/src/libipsec/policy_token.l b/crypto/dist/ipsec-tools/src/libipsec/policy_token.l index ff1046d0946ff..f24371511708f 100644 --- a/crypto/dist/ipsec-tools/src/libipsec/policy_token.l +++ b/crypto/dist/ipsec-tools/src/libipsec/policy_token.l @@ -1,6 +1,6 @@ -/* $NetBSD: policy_token.l,v 1.1.1.3 2005/08/07 08:49:25 manu Exp $ */ +/* $NetBSD: policy_token.l,v 1.1.1.4 2006/09/09 16:11:35 manu Exp $ */ -/* Id: policy_token.l,v 1.10.4.1 2005/05/07 14:30:38 manubsd 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. @@ -55,7 +55,8 @@ #include "libpfkey.h" -#if !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(__linux__) +#if !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(__linux__) && \ +!defined(__APPLE__) && !defined(__MACH__) #include "y.tab.h" #else #include "policy_parse.h" diff --git a/crypto/dist/ipsec-tools/src/racoon/Makefile.am b/crypto/dist/ipsec-tools/src/racoon/Makefile.am index c8b63c02b38dd..181e895c72086 100644 --- a/crypto/dist/ipsec-tools/src/racoon/Makefile.am +++ b/crypto/dist/ipsec-tools/src/racoon/Makefile.am @@ -1,4 +1,4 @@ -# Id: Makefile.am,v 1.19.2.4 2005/07/01 09:11:59 manubsd Exp +# Id: Makefile.am,v 1.23 2005/07/01 08:57:50 manubsd Exp sbin_PROGRAMS = racoon racoonctl plainrsa-gen noinst_PROGRAMS = eaytest diff --git a/crypto/dist/ipsec-tools/src/racoon/admin.c b/crypto/dist/ipsec-tools/src/racoon/admin.c index 30f180998d84b..c77845f923da2 100644 --- a/crypto/dist/ipsec-tools/src/racoon/admin.c +++ b/crypto/dist/ipsec-tools/src/racoon/admin.c @@ -1,6 +1,6 @@ -/* $NetBSD: admin.c,v 1.1.1.3 2005/08/07 08:46:18 manu Exp $ */ +/* $NetBSD: admin.c,v 1.1.1.4 2006/09/09 16:11:36 manu Exp $ */ -/* Id: admin.c,v 1.17.2.4 2005/07/12 11:49:44 manubsd Exp */ +/* Id: admin.c,v 1.25 2006/04/06 14:31:04 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -58,6 +58,9 @@ #ifdef HAVE_UNISTD_H #include #endif +#ifdef ENABLE_HYBRID +#include +#endif #include "var.h" #include "misc.h" @@ -80,6 +83,9 @@ #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" @@ -193,13 +199,18 @@ admin_process(so2, combuf) { caddr_t p; int len; - if (sched_dump(&p, &len) == -1) + if (sched_dump(&p, &len) == -1) { com->ac_errno = -1; + break; + } + buf = vmalloc(len); - if (buf == NULL) + if (buf == NULL) { com->ac_errno = -1; - else - memcpy(buf->v, p, len); + break; + } + + memcpy(buf->v, p, len); } break; @@ -280,16 +291,10 @@ admin_process(so2, combuf) &((struct admin_com_indexes *) ((caddr_t)com + sizeof(*com)))->dst; - if ((loc = strdup(saddrwop2str(src))) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "cannot allocate memory\n"); - break; - } - if ((rem = strdup(saddrwop2str(dst))) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "cannot allocate memory\n"); - break; - } + loc = racoon_strdup(saddrwop2str(src)); + rem = racoon_strdup(saddrwop2str(dst)); + STRDUP_FATAL(loc); + STRDUP_FATAL(rem); if ((iph1 = getph1byaddrwop(src, dst)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, @@ -306,6 +311,27 @@ admin_process(so2, combuf) break; } +#ifdef ENABLE_HYBRID + case ADMIN_LOGOUT_USER: { + struct ph1handle *iph1; + char *user; + int found = 0; + + if (com->ac_len > sizeof(com) + LOGINLEN + 1) { + plog(LLV_ERROR, LOCATION, NULL, + "malformed message (login too long)\n"); + break; + } + + user = (char *)(com + 1); + 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; @@ -315,21 +341,15 @@ admin_process(so2, combuf) &((struct admin_com_indexes *) ((caddr_t)com + sizeof(*com)))->dst; - if ((rem = strdup(saddrwop2str(dst))) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "cannot allocate memory\n"); - break; - } + rem = racoon_strdup(saddrwop2str(dst)); + STRDUP_FATAL(rem); plog(LLV_INFO, LOCATION, NULL, "Flushing all SAs for peer %s\n", rem); while ((iph1 = getph1bydstaddrwop(dst)) != NULL) { - if ((loc = strdup(saddrwop2str(iph1->local))) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "cannot allocate memory\n"); - break; - } + loc = racoon_strdup(saddrwop2str(iph1->local)); + STRDUP_FATAL(loc); if (iph1->status == PHASE1ST_ESTABLISHED) isakmp_info_send_d1(iph1); @@ -453,21 +473,27 @@ admin_process(so2, combuf) break; } +#ifdef ENABLE_HYBRID /* Set the id and key */ if (id && key) { - if (rmconf->idv != NULL) { - vfree(rmconf->idv); - rmconf->idv = NULL; + if (xauth_rmconf_used(&rmconf->xauth) == -1) { + com->ac_errno = -1; + break; } - if (rmconf->key != NULL) { - vfree(rmconf->key); - rmconf->key = NULL; + + 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->idvtype = idtype; - rmconf->idv = id; - rmconf->key = key; + rmconf->xauth->login = id; + rmconf->xauth->pass = key; } +#endif plog(LLV_INFO, LOCATION, NULL, "accept a request to establish IKE-SA: " @@ -636,3 +662,4 @@ admin_close() return 0; } #endif + diff --git a/crypto/dist/ipsec-tools/src/racoon/admin.h b/crypto/dist/ipsec-tools/src/racoon/admin.h index 964b23a56481f..aac4b3c8cddf4 100644 --- a/crypto/dist/ipsec-tools/src/racoon/admin.h +++ b/crypto/dist/ipsec-tools/src/racoon/admin.h @@ -1,6 +1,6 @@ -/* $NetBSD: admin.h,v 1.1.1.2 2005/02/23 14:54:10 manu Exp $ */ +/* $NetBSD: admin.h,v 1.1.1.3 2006/09/09 16:11:37 manu Exp $ */ -/* Id: admin.h,v 1.10 2004/12/30 13:45:49 manubsd Exp */ +/* Id: admin.h,v 1.11 2005/06/19 22:37:47 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -77,6 +77,11 @@ struct admin_com { */ #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 */ diff --git a/crypto/dist/ipsec-tools/src/racoon/algorithm.c b/crypto/dist/ipsec-tools/src/racoon/algorithm.c index abd156e154d28..bb607929e2626 100644 --- a/crypto/dist/ipsec-tools/src/racoon/algorithm.c +++ b/crypto/dist/ipsec-tools/src/racoon/algorithm.c @@ -1,6 +1,6 @@ -/* $NetBSD: algorithm.c,v 1.1.1.3 2005/08/07 08:46:20 manu Exp $ */ +/* $NetBSD: algorithm.c,v 1.1.1.4 2006/09/09 16:11:37 manu Exp $ */ -/* Id: algorithm.c,v 1.11.4.1 2005/06/28 22:38:02 manubsd Exp */ +/* Id: algorithm.c,v 1.15 2006/05/23 20:23:09 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -215,22 +215,46 @@ static struct misc_algorithm ipsec_compdef[] = { { "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, }, +{ "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_I, }, -{ "hybrid_dss_server", algtype_hybrid_dss_s, - OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I, }, -{ "hybrid_rsa_client", algtype_hybrid_rsa_c, - OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, }, -{ "hybrid_dss_client", algtype_hybrid_dss_c, - OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, }, +{ "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 }; @@ -396,7 +420,7 @@ alg_oakley_hmacdef_one(doi, key, buf) #ifdef ENABLE_STATS gettimeofday(&end, NULL); - syslog(LOG_NOTICE, "%s(%s size=%d): %8.6f", __func__, + syslog(LOG_NOTICE, "%s(%s size=%zu): %8.6f", __func__, f->name, buf->l, timedelta(&start, &end)); #endif @@ -508,7 +532,7 @@ alg_oakley_encdef_decrypt(doi, buf, key, iv) #ifdef ENABLE_STATS gettimeofday(&end, NULL); - syslog(LOG_NOTICE, "%s(%s klen=%d size=%d): %8.6f", __func__, + 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; @@ -537,7 +561,7 @@ alg_oakley_encdef_encrypt(doi, buf, key, iv) #ifdef ENABLE_STATS gettimeofday(&end, NULL); - syslog(LOG_NOTICE, "%s(%s klen=%d size=%d): %8.6f", __func__, + 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; diff --git a/crypto/dist/ipsec-tools/src/racoon/algorithm.h b/crypto/dist/ipsec-tools/src/racoon/algorithm.h index 09a7c78d74e85..61eb290e35b05 100644 --- a/crypto/dist/ipsec-tools/src/racoon/algorithm.h +++ b/crypto/dist/ipsec-tools/src/racoon/algorithm.h @@ -1,6 +1,6 @@ -/* $NetBSD: algorithm.h,v 1.1.1.2 2005/02/23 14:54:11 manu Exp $ */ +/* $NetBSD: algorithm.h,v 1.1.1.3 2006/09/09 16:11:38 manu Exp $ */ -/* Id: algorithm.h,v 1.8 2004/11/18 15:14:44 ludvigm Exp */ +/* Id: algorithm.h,v 1.10 2005/04/09 16:25:23 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -118,6 +118,10 @@ enum algtype { 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 }; diff --git a/crypto/dist/ipsec-tools/src/racoon/backupsa.c b/crypto/dist/ipsec-tools/src/racoon/backupsa.c index 533ff86451982..af8d6546e7860 100644 --- a/crypto/dist/ipsec-tools/src/racoon/backupsa.c +++ b/crypto/dist/ipsec-tools/src/racoon/backupsa.c @@ -1,4 +1,4 @@ -/* $NetBSD: backupsa.c,v 1.1.1.2 2005/02/23 14:54:11 manu Exp $ */ +/* $NetBSD: backupsa.c,v 1.1.1.3 2006/09/09 16:11:38 manu Exp $ */ /* $KAME: backupsa.c,v 1.16 2001/12/31 20:13:40 thorpej Exp $ */ @@ -176,9 +176,9 @@ backupsa_to_file(satype, mode, src, dst, spi, reqid, wsize, k = val2str(keymat, e_keylen + a_keylen); l = snprintf(p, len, " %s", k); + racoon_free(k); if (l < 0 || l >= len) goto err; - racoon_free(k); p += l; len -= l; if (len < 0) diff --git a/crypto/dist/ipsec-tools/src/racoon/cfparse.y b/crypto/dist/ipsec-tools/src/racoon/cfparse.y index 2929409debd65..b353d4713a550 100644 --- a/crypto/dist/ipsec-tools/src/racoon/cfparse.y +++ b/crypto/dist/ipsec-tools/src/racoon/cfparse.y @@ -1,6 +1,6 @@ -/* $NetBSD: cfparse.y,v 1.1.1.7 2005/11/21 14:12:15 manu Exp $ */ +/* $NetBSD: cfparse.y,v 1.1.1.8 2006/09/09 16:11:40 manu Exp $ */ -/* Id: cfparse.y,v 1.37.2.6 2005/10/17 16:23:50 monas Exp */ +/* Id: cfparse.y,v 1.66 2006/08/22 18:17:17 manubsd Exp */ %{ /* @@ -83,6 +83,8 @@ #include "handler.h" #include "isakmp.h" #ifdef ENABLE_HYBRID +#include "resolv.h" +#include "isakmp_unity.h" #include "isakmp_xauth.h" #include "isakmp_cfg.h" #endif @@ -149,6 +151,7 @@ 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 proposalspec *newprspec __P((void)); static void insprspec __P((struct proposalspec *, struct proposalspec **)); @@ -192,11 +195,16 @@ static int fix_lifebyte __P((u_long)); %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 /* modecfg */ -%token MODECFG CFG_NET4 CFG_MASK4 CFG_DNS4 CFG_NBNS4 -%token CFG_AUTH_SOURCE CFG_SYSTEM CFG_RADIUS CFG_PAM CFG_LOCAL CFG_NONE -%token CFG_ACCOUNTING CFG_CONF_SOURCE CFG_MOTD CFG_POOL_SIZE CFG_AUTH_THROTTLE +%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 @@ -209,18 +217,19 @@ static int fix_lifebyte __P((u_long)); %token EXCHANGE_MODE EXCHANGETYPE DOI DOITYPE SITUATION SITUATIONTYPE %token CERTIFICATE_TYPE CERTTYPE PEERS_CERTFILE CA_TYPE %token VERIFY_CERT SEND_CERT SEND_CR -%token IDENTIFIERTYPE MY_IDENTIFIER PEERS_IDENTIFIER VERIFY_IDENTIFIER +%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 NAT_TRAVERSAL_LEVEL %token PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL -%token GENERATE_POLICY SUPPORT_PROXY +%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 XAUTH_LOGIN +%token XAUTH_LOGIN WEAK_PHASE1_CHECK %token PREFIX PORT PORTANY UL_PROTO ANY IKE_FRAG ESP_FRAG MODE_CFG %token PFS_GROUP LIFETIME LIFETYPE_TIME LIFETYPE_BYTE STRENGTH @@ -228,21 +237,21 @@ static int fix_lifebyte __P((u_long)); %token SCRIPT PHASE1_UP PHASE1_DOWN %token NUMBER SWITCH BOOLEAN -%token HEXSTRING QUOTEDSTRING ADDRSTRING +%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 LOGLEV GSS_ID_ENCTYPE +%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 NAT_TRAVERSAL_LEVEL +%type CERTTYPE CERT_X509 CERT_PLAINRSA PROPOSAL_CHECK_LEVEL NAT_TRAVERSAL_LEVEL GENERATE_LEVEL %type unittype_time unittype_byte -%type QUOTEDSTRING HEXSTRING ADDRSTRING sainfo_id +%type QUOTEDSTRING HEXSTRING ADDRSTRING ADDRRANGE sainfo_id %type identifierstring %type remote_index ike_addrinfo_port %type algorithm @@ -262,6 +271,7 @@ statement | logging_statement | padding_statement | listen_statement + | ldapcfg_statement | modecfg_statement | timer_statement | sainfo_statement @@ -283,7 +293,7 @@ privsep_stmt struct passwd *pw; if ((pw = getpwnam($2->v)) == NULL) { - yyerror("unkown user \"%s\"", $2->v); + yyerror("unknown user \"%s\"", $2->v); return -1; } lcconf->uid = pw->pw_uid; @@ -295,7 +305,7 @@ privsep_stmt struct group *gr; if ((gr = getgrnam($2->v)) == NULL) { - yyerror("unkown group \"%s\"", $2->v); + yyerror("unknown group \"%s\"", $2->v); return -1; } lcconf->gid = gr->gr_gid; @@ -319,7 +329,8 @@ path_statement racoon_free(lcconf->pathinfo[$2]); /* set new pathinfo */ - lcconf->pathinfo[$2] = strdup($3->v); + lcconf->pathinfo[$2] = racoon_strdup($3->v); + STRDUP_FATAL(lcconf->pathinfo[$2]); vfree($3); } EOS @@ -356,7 +367,7 @@ gssenc_statement } ; - /* self infomation */ + /* self information */ identifier_statement : IDENTIFIER identifier_stmt ; @@ -397,11 +408,12 @@ log_level | LOGLEV { /* - * set the loglevel by configuration file only when - * the command line did not specify any loglevel. + * set the loglevel to the value specified + * in the configuration file plus the number + * of -d options specified on the command line */ - if (loglevel <= LLV_BASE) - loglevel += $1; + loglevel += $1 - oldloglevel; + oldloglevel = $1; } ; @@ -494,6 +506,155 @@ ike_port : /* nothing */ { $$ = PORT_ISAKMP; } | PORT { $$ = $1; } ; + + /* 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 @@ -506,9 +667,9 @@ 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."); + 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 @@ -525,23 +686,42 @@ modecfg_stmt #endif } EOS - | CFG_DNS4 ADDRSTRING + | CFG_DNS4 addrdnslist + EOS + | CFG_NBNS4 addrwinslist + EOS + | CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL splitnetlist { #ifdef ENABLE_HYBRID - if (inet_pton(AF_INET, $2->v, - &isakmp_cfg_config.dns4) != 1) - yyerror("bad IPv4 DNS address."); + isakmp_cfg_config.splitnet_type = UNITY_LOCAL_LAN; #else yyerror("racoon not configured with --enable-hybrid"); #endif } EOS - | CFG_NBNS4 ADDRSTRING + | CFG_SPLIT_NETWORK CFG_SPLIT_INCLUDE splitnetlist { #ifdef ENABLE_HYBRID - if (inet_pton(AF_INET, $2->v, - &isakmp_cfg_config.nbns4) != 1) - yyerror("bad IPv4 WINS address."); + 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 @@ -577,6 +757,48 @@ modecfg_stmt #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 */ @@ -588,6 +810,15 @@ modecfg_stmt 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 @@ -620,15 +851,8 @@ modecfg_stmt | CFG_POOL_SIZE NUMBER { #ifdef ENABLE_HYBRID - size_t len; - - isakmp_cfg_config.pool_size = $2; - - len = $2 * sizeof(*isakmp_cfg_config.port_pool); - isakmp_cfg_config.port_pool = racoon_malloc(len); - if (isakmp_cfg_config.port_pool == NULL) + if (isakmp_cfg_resize_pool($2) != 0) yyerror("cannot allocate memory for pool"); - bzero(isakmp_cfg_config.port_pool, len); #else /* ENABLE_HYBRID */ yyerror("racoon not configured with --enable-hybrid"); #endif /* ENABLE_HYBRID */ @@ -678,6 +902,19 @@ modecfg_stmt #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 */ @@ -696,6 +933,144 @@ modecfg_stmt 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; + + 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"); + + groupname = racoon_malloc($1->l+1); + if (groupname == NULL) + yyerror("unable to allocate auth group name"); + + 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"); + 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"); + 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 @@ -751,7 +1126,7 @@ sainfo_statement return -1; } } - sainfo_name sainfo_peer BOC sainfo_specs + sainfo_name sainfo_param BOC sainfo_specs { struct sainfo *check; @@ -791,6 +1166,16 @@ sainfo_name cur_sainfo->idsrc = NULL; cur_sainfo->iddst = NULL; } + | ANONYMOUS sainfo_id + { + cur_sainfo->idsrc = NULL; + cur_sainfo->iddst = $2; + } + | sainfo_id ANONYMOUS + { + cur_sainfo->idsrc = $1; + cur_sainfo->iddst = NULL; + } | sainfo_id sainfo_id { cur_sainfo->idsrc = $1; @@ -851,6 +1236,71 @@ sainfo_id 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; @@ -878,12 +1328,11 @@ sainfo_id memcpy($$->v + sizeof(*id_b), $2->v, $2->l); } ; -sainfo_peer +sainfo_param : /* nothing */ { cur_sainfo->id_i = NULL; } - | FROM IDENTIFIERTYPE identifierstring { struct ipsecdoi_id_b *id_b; @@ -909,6 +1358,18 @@ sainfo_peer 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 */ @@ -1195,7 +1656,11 @@ remote_spec yywarn("This directive without certtype will be removed!\n"); yywarn("Please use 'peers_certfile x509 \"%s\";' instead\n", $2->v); cur_rmconf->getcert_method = ISAKMP_GETCERT_LOCALFILE; - cur_rmconf->peerscertfile = strdup($2->v); + + if (cur_rmconf->peerscertfile != NULL) + racoon_free(cur_rmconf->peerscertfile); + cur_rmconf->peerscertfile = racoon_strdup($2->v); + STRDUP_FATAL(cur_rmconf->peerscertfile); vfree($2); } EOS @@ -1203,14 +1668,20 @@ remote_spec { cur_rmconf->cacerttype = $2; cur_rmconf->getcacert_method = ISAKMP_GETCERT_LOCALFILE; - cur_rmconf->cacertfile = strdup($3->v); + if (cur_rmconf->cacertfile != NULL) + racoon_free(cur_rmconf->cacertfile); + cur_rmconf->cacertfile = racoon_strdup($3->v); + STRDUP_FATAL(cur_rmconf->cacertfile); vfree($3); } EOS | PEERS_CERTFILE CERT_X509 QUOTEDSTRING { cur_rmconf->getcert_method = ISAKMP_GETCERT_LOCALFILE; - cur_rmconf->peerscertfile = strdup($3->v); + if (cur_rmconf->peerscertfile != NULL) + racoon_free(cur_rmconf->peerscertfile); + cur_rmconf->peerscertfile = racoon_strdup($3->v); + STRDUP_FATAL(cur_rmconf->peerscertfile); vfree($3); } EOS @@ -1259,16 +1730,27 @@ remote_spec 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 */ - cur_rmconf->idvtype = IDTYPE_LOGIN; - if (set_identifier(&cur_rmconf->idv, IDTYPE_LOGIN, $2) != 0) { + 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; } - /* cur_rmconf->use_xauth = 1; */ #else yyerror("racoon not configured with --enable-hybrid"); #endif @@ -1291,6 +1773,23 @@ remote_spec 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 @@ -1309,15 +1808,25 @@ remote_spec #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 | 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 @@ -1430,9 +1939,15 @@ cert_spec : CERT_X509 QUOTEDSTRING QUOTEDSTRING { cur_rmconf->certtype = $1; - cur_rmconf->mycertfile = strdup($2->v); + if (cur_rmconf->mycertfile != NULL) + racoon_free(cur_rmconf->mycertfile); + cur_rmconf->mycertfile = racoon_strdup($2->v); + STRDUP_FATAL(cur_rmconf->mycertfile); vfree($2); - cur_rmconf->myprivfile = strdup($3->v); + if (cur_rmconf->myprivfile != NULL) + racoon_free(cur_rmconf->myprivfile); + cur_rmconf->myprivfile = racoon_strdup($3->v); + STRDUP_FATAL(cur_rmconf->myprivfile); vfree($3); } EOS @@ -1519,7 +2034,11 @@ isakmpproposal_spec yyerror("wrong Vendor ID for gssapi_id"); return -1; } - cur_rmconf->prhead->spspec->gssid = strdup($2->v); + if (cur_rmconf->prhead->spspec->gssid != NULL) + racoon_free(cur_rmconf->prhead->spspec->gssid); + cur_rmconf->prhead->spspec->gssid = + racoon_strdup($2->v); + STRDUP_FATAL(cur_rmconf->prhead->spspec->gssid); } EOS | ALGORITHM_CLASS ALGORITHMTYPE keylength @@ -1866,7 +2385,10 @@ expand_isakmpspec(prop_no, trns_no, types, #ifdef HAVE_GSSAPI if (new->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { if (gssid != NULL) { - new->gssid = vmalloc(strlen(gssid)); + if ((new->gssid = vmalloc(strlen(gssid))) == NULL) { + yyerror("failed to allocate gssid"); + return -1; + } memcpy(new->gssid->v, gssid, new->gssid->l); racoon_free(gssid); } else { @@ -1934,8 +2456,12 @@ cfparse() yycf_init_buffer(); - if (yycf_switch_buffer(lcconf->racoon_conf) != 0) + 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) { diff --git a/crypto/dist/ipsec-tools/src/racoon/cftoken.l b/crypto/dist/ipsec-tools/src/racoon/cftoken.l index 56de6daf4f5ab..39f32eb1b82b1 100644 --- a/crypto/dist/ipsec-tools/src/racoon/cftoken.l +++ b/crypto/dist/ipsec-tools/src/racoon/cftoken.l @@ -1,6 +1,6 @@ -/* $NetBSD: cftoken.l,v 1.1.1.6 2005/11/21 14:12:15 manu Exp $ */ +/* $NetBSD: cftoken.l,v 1.1.1.7 2006/09/09 16:11:41 manu Exp $ */ -/* Id: cftoken.l,v 1.31.2.7 2005/11/06 17:18:26 monas Exp */ +/* Id: cftoken.l,v 1.53 2006/08/22 18:17:17 manubsd Exp */ %{ /* @@ -74,6 +74,7 @@ #include "ipsec_doi.h" #include "proposal.h" #include "nattraversal.h" +#include "remoteconf.h" #ifdef GC #include "gcmalloc.h" #endif @@ -124,6 +125,7 @@ bcl \{ ecl \} blcl \[ elcl \] +hyphen \- percent \% semi \; comment \#.* @@ -134,7 +136,7 @@ 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_INF S_LOG S_PAD S_LST S_RTRY S_CFG +%s S_INI S_PRIV S_PTH S_INF S_LOG S_PAD S_LST S_RTRY S_CFG S_LDAP %s S_ALGST S_ALGCL %s S_SAINF S_SAINFS %s S_RMT S_RMTS S_RMTP @@ -165,7 +167,7 @@ hexstring 0x{hexdigit}+ return(PATHTYPE); } certificate { YYD; yylval.num = LC_PATHTYPE_CERT; return(PATHTYPE); } -script { YYD; yylval.num = LC_PATHTYPE_SCRIPT; +script { YYD; yylval.num = LC_PATHTYPE_SCRIPT; return(PATHTYPE); } backupsa { YYD; yylval.num = LC_PATHTYPE_BACKUPSA; return(PATHTYPE); } @@ -185,12 +187,14 @@ hexstring 0x{hexdigit}+ /* logging */ log { BEGIN S_LOG; YYDB; return(LOGGING); } -info { YYD; yywarn("it is obsoleted. use \"notify\""); yylval.num = 0; return(LOGLEV); } -notify { YYD; yylval.num = 0; return(LOGLEV); } -debug { YYD; yylval.num = 1; return(LOGLEV); } -debug2 { YYD; yylval.num = 2; return(LOGLEV); } -debug3 { YYD; yywarn("it is osboleted. use \"debug2\""); yylval.num = 2; return(LOGLEV); } -debug4 { YYD; yywarn("it is obsoleted. use \"debug2\""); yylval.num = 2; return(LOGLEV); } +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); } +debug3 { YYD; yywarn("it is obsoleted. use \"debug2\""); yylval.num = LLV_DEBUG2; return(LOGLEV); } +debug4 { YYD; yywarn("it is obsoleted. use \"debug2\""); yylval.num = LLV_DEBUG2; return(LOGLEV); } {semi} { BEGIN S_INI; return(EOS); } /* padding */ @@ -214,6 +218,23 @@ hexstring 0x{hexdigit}+ strict_address { YYD; return(STRICT_ADDRESS); } {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); } @@ -221,7 +242,10 @@ hexstring 0x{hexdigit}+ netmask4 { YYD; return(CFG_MASK4); } dns4 { YYD; return(CFG_DNS4); } 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); } @@ -229,11 +253,17 @@ hexstring 0x{hexdigit}+ 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 */ @@ -253,6 +283,7 @@ hexstring 0x{hexdigit}+ {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); } @@ -303,6 +334,8 @@ hexstring 0x{hexdigit}+ 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_mip6 { YYD; yywarn("it is obsoleted. use \"support_proxy\"."); return(SUPPORT_PROXY); } support_proxy { YYD; return(SUPPORT_PROXY); } initial_contact { YYD; return(INITIAL_CONTACT); } @@ -328,6 +361,7 @@ hexstring 0x{hexdigit}+ phase1_up { YYD; return(PHASE1_UP); } phase1_down { YYD; return(PHASE1_DOWN); } mode_cfg { YYD; return(MODE_CFG); } +weak_phase1_check { YYD; return(WEAK_PHASE1_CHECK); } /* remote proposal */ proposal { BEGIN S_RMTP; YYDB; return(PROPOSAL); } {bcl} { return(BOC); } @@ -373,6 +407,19 @@ off { YYD; yylval.num = FALSE; return(SWITCH); } 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); } @@ -464,6 +511,34 @@ hybrid_dss_client { #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 } @@ -477,6 +552,10 @@ subnet { YYD; yylval.num = IDTYPE_SUBNET; return(IDENTIFIERTYPE); } asn1dn { YYD; yylval.num = IDTYPE_ASN1DN; return(IDENTIFIERTYPE); } certname { YYD; yywarn("certname will be obsoleted in near future."); 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); } @@ -637,7 +716,7 @@ yycf_switch_buffer(path) 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"); + "glob found no matches for path \"%s\"\n", path); return -1; } incstack[incstackp].matchon = 0; @@ -679,7 +758,10 @@ yycf_set_buffer(path) /* initialize */ incstack[incstackp].fp = yyin; - incstack[incstackp].path = strdup(path); + 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); diff --git a/crypto/dist/ipsec-tools/src/racoon/crypto_openssl.c b/crypto/dist/ipsec-tools/src/racoon/crypto_openssl.c index e0e7c2732ec51..819d2fb05e605 100644 --- a/crypto/dist/ipsec-tools/src/racoon/crypto_openssl.c +++ b/crypto/dist/ipsec-tools/src/racoon/crypto_openssl.c @@ -1,6 +1,6 @@ -/* $NetBSD: crypto_openssl.c,v 1.1.1.3 2005/08/07 08:46:28 manu Exp $ */ +/* $NetBSD: crypto_openssl.c,v 1.1.1.4 2006/09/09 16:11:43 manu Exp $ */ -/* Id: crypto_openssl.c,v 1.40.4.5 2005/07/12 11:50:15 manubsd 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. @@ -594,37 +594,36 @@ eay_get_x509asn1subjectname(cert) u_char *bp; vchar_t *name = NULL; int len; - int error = -1; bp = (unsigned char *) cert->v; x509 = mem2x509(cert); if (x509 == NULL) - goto end; + goto error; /* get the length of the name */ len = i2d_X509_NAME(x509->cert_info->subject, NULL); name = vmalloc(len); if (!name) - goto end; + goto error; /* get the name */ bp = (unsigned char *) name->v; len = i2d_X509_NAME(x509->cert_info->subject, &bp); - error = 0; + X509_free(x509); - end: - if (error) { - plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror()); - if (name) { - vfree(name); - name = NULL; - } - } - if (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 name; + return NULL; } /* diff --git a/crypto/dist/ipsec-tools/src/racoon/debugrm.c b/crypto/dist/ipsec-tools/src/racoon/debugrm.c index 89799d24a3e0f..d31538d27006e 100644 --- a/crypto/dist/ipsec-tools/src/racoon/debugrm.c +++ b/crypto/dist/ipsec-tools/src/racoon/debugrm.c @@ -1,4 +1,4 @@ -/* $NetBSD: debugrm.c,v 1.1.1.2 2005/02/23 14:54:13 manu Exp $ */ +/* $NetBSD: debugrm.c,v 1.1.1.3 2006/09/09 16:11:44 manu Exp $ */ /* $KAME: debugrm.c,v 1.6 2001/12/13 16:07:46 sakane Exp $ */ @@ -206,6 +206,25 @@ DRM_free(file, line, func, ptr) free(ptr); } +char * +DRM_strdup(file, line, func, str) + char *file, *func; + int line; + const char *str; +{ + char *p; + + p = strdup(str); + + if (p) { + char buf[1024]; + DRM_setmsg(buf, sizeof(buf), p, size, file, line, func); + DRM_add(p, buf); + } + + return p; +} + /* * mask vmbuf.c functions. */ diff --git a/crypto/dist/ipsec-tools/src/racoon/debugrm.h b/crypto/dist/ipsec-tools/src/racoon/debugrm.h index 6c87807d17dd7..1799aa699fe36 100644 --- a/crypto/dist/ipsec-tools/src/racoon/debugrm.h +++ b/crypto/dist/ipsec-tools/src/racoon/debugrm.h @@ -1,6 +1,6 @@ -/* $NetBSD: debugrm.h,v 1.1.1.2 2005/02/23 14:54:13 manu Exp $ */ +/* $NetBSD: debugrm.h,v 1.1.1.3 2006/09/09 16:11:43 manu Exp $ */ -/* Id: debugrm.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */ +/* Id: debugrm.h,v 1.4 2006/04/06 14:00:06 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -49,6 +49,9 @@ #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) \ @@ -66,6 +69,10 @@ #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)); @@ -74,6 +81,7 @@ 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) \ diff --git a/crypto/dist/ipsec-tools/src/racoon/dnssec.c b/crypto/dist/ipsec-tools/src/racoon/dnssec.c index 4d1f1bf1ad1b6..de5937eab8468 100644 --- a/crypto/dist/ipsec-tools/src/racoon/dnssec.c +++ b/crypto/dist/ipsec-tools/src/racoon/dnssec.c @@ -1,4 +1,4 @@ -/* $NetBSD: dnssec.c,v 1.1.1.3 2005/08/20 00:41:13 manu Exp $ */ +/* $NetBSD: dnssec.c,v 1.1.1.4 2006/09/09 16:11:44 manu Exp $ */ /* $KAME: dnssec.c,v 1.2 2001/08/05 18:46:07 itojun Exp $ */ @@ -96,7 +96,7 @@ dnssec_getcert(id) "inpropper ID type passed %s " "though getcert method is dnssec.\n", s_ipsecdoi_ident(id_b->type)); - return NULL; + goto err; } /* check response */ @@ -145,7 +145,10 @@ dnssec_getcert(id) err: if (name) racoon_free(name); - if (cert) + if (cert) { oakley_delcert(cert); + cert = NULL; + } + goto end; } diff --git a/crypto/dist/ipsec-tools/src/racoon/doc/FAQ b/crypto/dist/ipsec-tools/src/racoon/doc/FAQ index 924c73f696bea..0ab49f0003645 100644 --- a/crypto/dist/ipsec-tools/src/racoon/doc/FAQ +++ b/crypto/dist/ipsec-tools/src/racoon/doc/FAQ @@ -39,6 +39,14 @@ A: 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 diff --git a/crypto/dist/ipsec-tools/src/racoon/eaytest.c b/crypto/dist/ipsec-tools/src/racoon/eaytest.c index de978a6dacb53..17f197b38397e 100644 --- a/crypto/dist/ipsec-tools/src/racoon/eaytest.c +++ b/crypto/dist/ipsec-tools/src/racoon/eaytest.c @@ -1,6 +1,6 @@ -/* $NetBSD: eaytest.c,v 1.1.1.3 2005/08/07 08:46:33 manu Exp $ */ +/* $NetBSD: eaytest.c,v 1.1.1.4 2006/09/09 16:11:42 manu Exp $ */ -/* Id: eaytest.c,v 1.20.4.2 2005/06/28 22:38:02 manubsd Exp */ +/* Id: eaytest.c,v 1.22 2005/06/19 18:02:54 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. diff --git a/crypto/dist/ipsec-tools/src/racoon/evt.c b/crypto/dist/ipsec-tools/src/racoon/evt.c index c3540ab478214..989b33f46ebf7 100644 --- a/crypto/dist/ipsec-tools/src/racoon/evt.c +++ b/crypto/dist/ipsec-tools/src/racoon/evt.c @@ -1,6 +1,6 @@ -/* $NetBSD: evt.c,v 1.1.1.3 2005/10/14 13:21:45 manu Exp $ */ +/* $NetBSD: evt.c,v 1.1.1.4 2006/09/09 16:11:44 manu Exp $ */ -/* Id: evt.c,v 1.2.4.1 2005/09/26 17:49:38 manubsd Exp */ +/* Id: evt.c,v 1.5 2006/06/22 20:11:35 manubsd Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -45,10 +45,11 @@ #include "vmbuf.h" #include "plog.h" #include "misc.h" +#include "admin.h" #include "gcmalloc.h" #include "evt.h" - +#ifdef ENABLE_ADMINPORT struct evtlist evtlist = TAILQ_HEAD_INITIALIZER(evtlist); int evtlist_len = 0; @@ -63,6 +64,10 @@ evt_push(src, dst, type, optdata) struct evt *evt; size_t len; + /* If admin socket is disabled, silently discard anything */ + if (adminsock_path == NULL) + return; + /* If we are above the limit, don't record anything */ if (evtlist_len > EVTLIST_MAX) { plog(LLV_DEBUG, LOCATION, NULL, @@ -149,3 +154,5 @@ evt_dump(void) { return buf; } + +#endif /* ENABLE_ADMINPORT */ diff --git a/crypto/dist/ipsec-tools/src/racoon/evt.h b/crypto/dist/ipsec-tools/src/racoon/evt.h index 2573cb56c8b9a..1cf4fe24eef3f 100644 --- a/crypto/dist/ipsec-tools/src/racoon/evt.h +++ b/crypto/dist/ipsec-tools/src/racoon/evt.h @@ -1,6 +1,6 @@ -/* $NetBSD: evt.h,v 1.1.1.2 2005/02/23 14:54:14 manu Exp $ */ +/* $NetBSD: evt.h,v 1.1.1.3 2006/09/09 16:11:45 manu Exp $ */ -/* Id: evt.h,v 1.3 2004/11/29 23:30:39 manubsd Exp */ +/* Id: evt.h,v 1.5 2006/01/19 10:24:09 fredsen Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -61,6 +61,8 @@ struct evtdump { #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 */ struct evt { struct evtdump *dump; diff --git a/crypto/dist/ipsec-tools/src/racoon/gcmalloc.h b/crypto/dist/ipsec-tools/src/racoon/gcmalloc.h index d1f01733b5973..0a1de700c6acc 100644 --- a/crypto/dist/ipsec-tools/src/racoon/gcmalloc.h +++ b/crypto/dist/ipsec-tools/src/racoon/gcmalloc.h @@ -1,4 +1,4 @@ -/* $NetBSD: gcmalloc.h,v 1.1.1.2 2005/02/23 14:54:14 manu Exp $ */ +/* $NetBSD: gcmalloc.h,v 1.1.1.3 2006/09/09 16:11:44 manu Exp $ */ /* $KAME: gcmalloc.h,v 1.4 2001/11/16 04:34:57 sakane Exp $ */ @@ -79,12 +79,20 @@ 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 */ @@ -111,6 +119,9 @@ free(void *ptr) #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/crypto/dist/ipsec-tools/src/racoon/getcertsbyname.c b/crypto/dist/ipsec-tools/src/racoon/getcertsbyname.c index 490296d37640f..d4e1733268e70 100644 --- a/crypto/dist/ipsec-tools/src/racoon/getcertsbyname.c +++ b/crypto/dist/ipsec-tools/src/racoon/getcertsbyname.c @@ -1,4 +1,4 @@ -/* $NetBSD: getcertsbyname.c,v 1.1.1.3 2005/08/07 08:46:35 manu Exp $ */ +/* $NetBSD: getcertsbyname.c,v 1.1.1.4 2006/09/09 16:11:45 manu Exp $ */ /* $KAME: getcertsbyname.c,v 1.7 2001/11/16 04:12:59 sakane Exp $ */ @@ -39,6 +39,9 @@ #include #include +#if (defined(__APPLE__) && defined(__MACH__)) +# include +#endif #include #ifdef HAVE_LWRES_GETRRSETBYNAME #include diff --git a/crypto/dist/ipsec-tools/src/racoon/grabmyaddr.c b/crypto/dist/ipsec-tools/src/racoon/grabmyaddr.c index 3b511db8953da..a5872e93534be 100644 --- a/crypto/dist/ipsec-tools/src/racoon/grabmyaddr.c +++ b/crypto/dist/ipsec-tools/src/racoon/grabmyaddr.c @@ -1,6 +1,6 @@ -/* $NetBSD: grabmyaddr.c,v 1.1.1.3 2005/08/07 08:46:36 manu Exp $ */ +/* $NetBSD: grabmyaddr.c,v 1.1.1.4 2006/09/09 16:11:46 manu Exp $ */ -/* Id: grabmyaddr.c,v 1.23.4.2 2005/07/16 04:41:01 monas Exp */ +/* Id: grabmyaddr.c,v 1.27 2006/04/06 16:27:05 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -42,7 +42,8 @@ #if defined(__FreeBSD__) && __FreeBSD__ >= 3 #include #endif -#if defined(__NetBSD__) || defined(__FreeBSD__) +#if defined(__NetBSD__) || defined(__FreeBSD__) || \ + (defined(__APPLE__) && defined(__MACH__)) #include #include #endif @@ -804,6 +805,12 @@ dupmyaddr(struct myaddrs *old) /* Copy the whole structure and set the differences. */ memcpy (new, old, sizeof (*new)); new->addr = dupsaddr (old->addr); + if (new->addr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer for myaddrs.\n"); + racoon_free(new); + return NULL; + } new->next = old->next; old->next = new; diff --git a/crypto/dist/ipsec-tools/src/racoon/gssapi.c b/crypto/dist/ipsec-tools/src/racoon/gssapi.c index 72f5a77fc4126..ba51b36829558 100644 --- a/crypto/dist/ipsec-tools/src/racoon/gssapi.c +++ b/crypto/dist/ipsec-tools/src/racoon/gssapi.c @@ -1,4 +1,4 @@ -/* $NetBSD: gssapi.c,v 1.1.1.2 2005/02/23 14:54:14 manu Exp $ */ +/* $NetBSD: gssapi.c,v 1.1.1.3 2006/09/09 16:11:48 manu Exp $ */ /* $KAME: gssapi.c,v 1.19 2001/04/03 15:51:55 thorpej Exp $ */ @@ -155,6 +155,7 @@ 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; @@ -163,8 +164,9 @@ gssapi_get_default_name(struct ph1handle *iph1, int remote, gss_name_t *service) if (getnameinfo(sa, sysdep_sa_len(sa), name, NI_MAXHOST, NULL, 0, 0) != 0) return -1; - name_token.length = asprintf((char **)&name_token.value, - "%s@%s", GSSAPI_DEF_NAME, name); + 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)) { @@ -290,7 +292,7 @@ gssapi_get_itoken(struct ph1handle *iph1, int *lenp) if (iph1->approval != NULL && iph1->approval->gssid != NULL) { plog(LLV_DEBUG, LOCATION, NULL, "using provided service '%.*s'\n", - iph1->approval->gssid->l, iph1->approval->gssid->v); + (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, @@ -468,7 +470,7 @@ gssapi_get_itokens(struct ph1handle *iph1, vchar_t **tokens) *tokens = toks; plog(LLV_DEBUG, LOCATION, NULL, - "%d itokens of length %d\n", gps->gsscnt, (*tokens)->l); + "%d itokens of length %zu\n", gps->gsscnt, (*tokens)->l); return 0; } @@ -549,7 +551,7 @@ gssapi_wraphash(struct ph1handle *iph1) return NULL; } - plog(LLV_DEBUG, LOCATION, NULL, "wrapped HASH, ilen %d olen %d\n", + 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); @@ -591,7 +593,7 @@ gssapi_unwraphash(struct ph1handle *iph1) 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 %d\n", + 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, diff --git a/crypto/dist/ipsec-tools/src/racoon/handler.c b/crypto/dist/ipsec-tools/src/racoon/handler.c index 2afdc23a89015..30ecba47731d5 100644 --- a/crypto/dist/ipsec-tools/src/racoon/handler.c +++ b/crypto/dist/ipsec-tools/src/racoon/handler.c @@ -1,6 +1,6 @@ -/* $NetBSD: handler.c,v 1.1.1.3 2005/08/07 08:46:39 manu Exp $ */ +/* $NetBSD: handler.c,v 1.1.1.4 2006/09/09 16:11:49 manu Exp $ */ -/* Id: handler.c,v 1.13.4.4 2005/07/14 12:00:36 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. @@ -50,6 +50,10 @@ #include "sockmisc.h" #include "debug.h" +#ifdef ENABLE_HYBRID +#include +#endif + #include "schedule.h" #include "grabmyaddr.h" #include "algorithm.h" @@ -71,6 +75,8 @@ #include "gcmalloc.h" #include "nattraversal.h" +#include "sainfo.h" + #ifdef HAVE_GSSAPI #include "gssapi.h" #endif @@ -110,6 +116,7 @@ getph1byindex(index) return NULL; } + /* * search for isakmp handler by i_ck in index. */ @@ -261,9 +268,11 @@ void delph1(iph1) struct ph1handle *iph1; { + if (iph1 == NULL) + return; + /* SA down shell script hook */ - if (iph1 != NULL) - script_hook(iph1, SCRIPT_PHASE1_DOWN); + script_hook(iph1, SCRIPT_PHASE1_DOWN); EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL); @@ -277,6 +286,11 @@ delph1(iph1) } #endif +#ifdef ENABLE_HYBRID + if (iph1->mode_cfg) + isakmp_cfg_rmstate(iph1); +#endif + #ifdef ENABLE_DPD if (iph1->dpd_r_u != NULL) SCHED_KILL(iph1->dpd_r_u); @@ -290,17 +304,11 @@ delph1(iph1) racoon_free(iph1->local); iph1->local = NULL; } - if (iph1->approval) { delisakmpsa(iph1->approval); iph1->approval = NULL; } -#ifdef ENABLE_HYBRID - if (iph1->mode_cfg) - isakmp_cfg_rmstate(iph1); -#endif - VPTRINIT(iph1->authstr); sched_scrub_param(iph1); @@ -334,6 +342,9 @@ delph1(iph1) VPTRINIT(iph1->id); VPTRINIT(iph1->id_p); + if(iph1->approval != NULL) + delisakmpsa(iph1->approval); + if (iph1->ivm) { oakley_delivm(iph1->ivm); iph1->ivm = NULL; @@ -774,6 +785,12 @@ inscontacted(remote) 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); @@ -1013,3 +1030,480 @@ exclude_cfg_addr(addr) 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; + + /* + * 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); + } + 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 && iph2->ph1->rmconf != NULL) { + check_level = iph2->ph1->rmconf->pcheck_level; + } else { + plog(LLV_DEBUG, LOCATION, NULL, + "No phase1 rmconf 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 (sainfo->lifebyte < approval->lifebyte) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: lifebyte mismatch\n"); + return 0; + } + + 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 || + sainfo->lifebyte != approval->lifebyte || + 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{ + unbindph12(iph2); + 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){ + for (iph2 = LIST_FIRST(&iph1->ph2tree); iph2; iph2 = iph2_next) { + iph2_next = LIST_NEXT(iph2, chain); + remove_ph2(iph2); + } + isakmp_info_send_d1(iph1); + } + iph1->status = PHASE1ST_EXPIRED; + iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1); +} + + +static int revalidate_ph1tree_rmconf(void){ + struct ph1handle *p, *next; + struct remoteconf *newrmconf; + + for (p = LIST_FIRST(&ph1tree); p; p = next) { + next = LIST_NEXT(p, chain); + + if (p->status == PHASE1ST_EXPIRED) + continue; + + newrmconf=getrmconf(p->remote); + if(newrmconf == NULL){ + p->rmconf = NULL; + remove_ph1(p); + }else{ + /* Do not free old rmconf, it is just a pointer to an entry in rmtree + */ + p->rmconf=newrmconf; + if(p->approval != NULL){ + struct isakmpsa *tmpsa; + + tmpsa=dupisakmpsa(p->approval); + if(tmpsa != NULL){ + delisakmpsa(p->approval); + p->approval=tmpsa; + p->approval->rmconf=newrmconf; + } + } + } + } + + return 1; +} + + +/* rmconf is already updated here + */ +static int revalidate_ph1(struct ph1handle *iph1){ + struct isakmpsa *p, *approval; + struct etypes *e; + + if(iph1 == NULL || + iph1->approval == NULL || + iph1->rmconf == NULL) + return 0; + + approval=iph1->approval; + + for (e = iph1->rmconf->etypes; e != NULL; e = e->next){ + if (iph1->etype == e->type) + break; + } + + if (e == NULL){ + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: Exchange type mismatch\n"); + return 0; + } + + if (iph1->etype == ISAKMP_ETYPE_AGG && + approval->dh_group != iph1->rmconf->dh_group){ + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: DH mismatch\n"); + return 0; + } + + for (p=iph1->rmconf->proposal; p != NULL; p=p->next){ + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: Trying next proposal...\n"); + + if(approval->authmethod != p->authmethod){ + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: Authmethod mismatch\n"); + continue; + } + + if(approval->enctype != p->enctype){ + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: enctype mismatch\n"); + continue; + } + + switch (iph1->rmconf->pcheck_level) { + case PROP_CHECK_OBEY: + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: OBEY pcheck level, ok...\n"); + return 1; + break; + + case PROP_CHECK_CLAIM: + /* FALLTHROUGH */ + case PROP_CHECK_STRICT: + if (approval->encklen < p->encklen) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: encklen mismatch\n"); + continue; + } + + if (approval->lifetime > p->lifetime) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: lifetime mismatch\n"); + continue; + } + + if (approval->lifebyte > p->lifebyte) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: lifebyte mismatch\n"); + continue; + } + break; + + case PROP_CHECK_EXACT: + if (approval->encklen != p->encklen) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: encklen mismatch\n"); + continue; + } + + if (approval->lifetime != p->lifetime) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: lifetime mismatch\n"); + continue; + } + + if (approval->lifebyte != p->lifebyte) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: lifebyte mismatch\n"); + continue; + } + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "unexpected check_level\n"); + continue; + break; + } + + if (approval->hashtype != p->hashtype) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: hashtype mismatch\n"); + continue; + } + + if (iph1->etype != ISAKMP_ETYPE_AGG && + approval->dh_group != p->dh_group) { + plog(LLV_DEBUG, LOCATION, NULL, + "Reload: dhgroup mismatch\n"); + continue; + } + + plog(LLV_DEBUG, LOCATION, NULL, "Reload: Conf ok\n"); + return 1; + } + + plog(LLV_DEBUG, LOCATION, NULL, "Reload: No valid conf found\n"); + return 0; +} + + +static int revalidate_ph1tree(void){ + struct ph1handle *p, *next; + + for (p = LIST_FIRST(&ph1tree); p; p = next) { + next = LIST_NEXT(p, chain); + + if (p->status == PHASE1ST_EXPIRED) + continue; + + if(!revalidate_ph1(p)) + remove_ph1(p); + } + + 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(); + revalidate_ph1tree(); + + 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; + int found = 0; + + LIST_FOREACH(p, &ph1tree, chain) { + if (p->mode_cfg == NULL) + continue; + if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0) { + if (p->status == PHASE1ST_ESTABLISHED) + isakmp_info_send_d1(p); + purge_remote(p); + found++; + } + } + + return found; +} +#endif diff --git a/crypto/dist/ipsec-tools/src/racoon/handler.h b/crypto/dist/ipsec-tools/src/racoon/handler.h index 94dd6223454a9..8155bb4fd7661 100644 --- a/crypto/dist/ipsec-tools/src/racoon/handler.h +++ b/crypto/dist/ipsec-tools/src/racoon/handler.h @@ -1,6 +1,6 @@ -/* $NetBSD: handler.h,v 1.1.1.3 2005/08/07 08:46:40 manu Exp $ */ +/* $NetBSD: handler.h,v 1.1.1.4 2006/09/09 16:11:49 manu Exp $ */ -/* Id: handler.h,v 1.11.4.3 2005/05/07 17:26:05 manubsd Exp */ +/* Id: handler.h,v 1.19 2006/02/25 08:25:12 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -131,8 +131,10 @@ struct ph1handle { u_int8_t flags; /* Flags */ u_int32_t msgid; /* message id */ +#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 */ @@ -167,7 +169,7 @@ struct ph1handle { 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. strut ipsecdoi_id_b*. */ + /* i.e. struct ipsecdoi_id_b*. */ struct isakmp_ivm *ivm; /* IVs */ vchar_t *sa; /* whole SA payload to send/to be sent*/ @@ -193,11 +195,13 @@ struct ph1handle { struct timeval end; #endif +#ifdef ENABLE_DPD int dpd_support; /* Does remote supports DPD ? */ time_t dpd_lastack; /* Last ack received */ u_int16_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 */ @@ -426,6 +430,10 @@ extern struct ph1handle *getph1byaddr __P((struct sockaddr *, extern struct ph1handle *getph1byaddrwop __P((struct sockaddr *, struct sockaddr *)); extern struct ph1handle *getph1bydstaddrwop __P((struct sockaddr *)); +#ifdef ENABLE_HYBRID +struct ph1handle *getph1bylogin __P((char *)); +int purgeph1bylogin __P((char *)); +#endif extern vchar_t *dumpph1 __P((void)); extern struct ph1handle *newph1 __P((void)); extern void delph1 __P((struct ph1handle *)); @@ -470,4 +478,6 @@ extern void init_recvdpkt __P((void)); extern int exclude_cfg_addr __P((const struct sockaddr *)); #endif +extern int revalidate_ph12(void); + #endif /* _HANDLER_H */ diff --git a/crypto/dist/ipsec-tools/src/racoon/ipsec_doi.c b/crypto/dist/ipsec-tools/src/racoon/ipsec_doi.c index 8e2666397445a..5881b372acb80 100644 --- a/crypto/dist/ipsec-tools/src/racoon/ipsec_doi.c +++ b/crypto/dist/ipsec-tools/src/racoon/ipsec_doi.c @@ -1,6 +1,6 @@ -/* $NetBSD: ipsec_doi.c,v 1.1.1.5 2005/11/21 14:12:13 manu Exp $ */ +/* $NetBSD: ipsec_doi.c,v 1.1.1.6 2006/09/09 16:11:53 manu Exp $ */ -/* Id: ipsec_doi.c,v 1.26.2.15 2005/10/17 16:23:50 monas 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. @@ -276,10 +276,12 @@ get_ph1approval(iph1, pair) 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; + racoon_free(sa); return NULL; } @@ -287,7 +289,7 @@ get_ph1approval(iph1, pair) #ifdef HAVE_GSSAPI if (sa->gssid != NULL) plog(LLV_DEBUG, LOCATION, NULL, "gss id in new sa '%.*s'\n", - sa->gssid->l, sa->gssid->v); + (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); @@ -305,16 +307,20 @@ get_ph1approval(iph1, pair) } if (iph1->gi_i != NULL) plog(LLV_DEBUG, LOCATION, NULL, "GIi is %.*s\n", - iph1->gi_i->l, iph1->gi_i->v); + (int)iph1->gi_i->l, iph1->gi_i->v); if (iph1->gi_r != NULL) plog(LLV_DEBUG, LOCATION, NULL, "GIr is %.*s\n", - iph1->gi_r->l, iph1->gi_r->v); + (int)iph1->gi_r->l, iph1->gi_r->v); #else iph1->approval = sa; #endif + if(iph1->approval) { + plog(LLV_DEBUG, LOCATION, NULL, "agreed on %s auth.\n", + s_oakley_attr_method(iph1->approval->authmethod)); + } newsa = get_sabyproppair(p, iph1); - if (newsa == NULL) { + if (newsa == NULL){ delisakmpsa(iph1->approval); iph1->approval = NULL; } @@ -379,7 +385,7 @@ get_ph1approvalx(p, proposal, sap, check_level) tsap->hashtype)); plog(LLV_DEBUG, LOCATION, NULL, "authmethod = %s:%s\n", s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD, - authmethod), + s->authmethod), s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD, tsap->authmethod)); plog(LLV_DEBUG, LOCATION, NULL, "dh_group = %s:%s\n", @@ -437,8 +443,10 @@ get_ph1approvalx(p, proposal, sap, check_level) } found: - if (tsap->dhgrp != NULL) + if (tsap->dhgrp != NULL){ oakley_dhgrp_free(tsap->dhgrp); + tsap->dhgrp = NULL; + } if ((s = dupisakmpsa(s)) != NULL) { switch(check_level) { @@ -463,7 +471,6 @@ get_ph1approvalx(p, proposal, sap, check_level) break; } } - return s; } @@ -533,8 +540,10 @@ print_ph1mismatched(p, proposal) } } - if (sa.dhgrp != NULL) + if (sa.dhgrp != NULL){ oakley_dhgrp_free(sa.dhgrp); + sa.dhgrp=NULL; + } } /* @@ -758,8 +767,8 @@ t2isakmpsa(trns, sa) sa->gssid = vmalloc(len); memcpy(sa->gssid->v, d + 1, len); plog(LLV_DEBUG, LOCATION, NULL, - "received old-style gss id '%.*s' (len %d)\n", - sa->gssid->l, sa->gssid->v, sa->gssid->l); + "received old-style gss id '%.*s' (len %zu)\n", + (int)sa->gssid->l, sa->gssid->v, sa->gssid->l); break; } @@ -813,8 +822,8 @@ t2isakmpsa(trns, sa) sa->gssid->l = (len / 2) - dstleft; plog(LLV_DEBUG, LOCATION, NULL, - "received gss id '%.*s' (len %d)\n", - sa->gssid->l, sa->gssid->v, sa->gssid->l); + "received gss id '%.*s' (len %zu)\n", + (int)sa->gssid->l, sa->gssid->v, sa->gssid->l); break; } #endif /* HAVE_GSSAPI */ @@ -1166,7 +1175,8 @@ get_ph2approvalx(iph2, pp) { struct saproto *sp; - struct prop_pair *p, *n, *x; + struct prop_pair *p, *x; + struct prop_pair *n = NULL; ret = NULL; @@ -1190,8 +1200,11 @@ get_ph2approvalx(iph2, pp) if (!x) goto err; /* XXX */ + if (n != NULL) + racoon_free(n); + n = racoon_calloc(1, sizeof(struct prop_pair)); - if (!n) { + if (n == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to get buffer.\n"); goto err; @@ -1263,7 +1276,7 @@ get_proppair(sa, mode) vchar_t *sa; int mode; { - struct prop_pair **pair; + struct prop_pair **pair = NULL; int num_p = 0; /* number of proposal for use */ int tlen; caddr_t bp; @@ -1277,22 +1290,22 @@ get_proppair(sa, mode) if (sa->l < sizeof(*sab)) { plog(LLV_ERROR, LOCATION, NULL, "Invalid SA length = %zu.\n", sa->l); - return NULL; + goto bad; } /* check DOI */ if (check_doi(ntohl(sab->doi)) < 0) - return NULL; + goto bad; /* check SITUATION */ if (check_situation(ntohl(sab->sit)) < 0) - return NULL; + goto bad; pair = racoon_calloc(1, MAXPROPPAIRLEN * sizeof(*pair)); if (pair == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to get buffer.\n"); - return NULL; + goto bad; } memset(pair, 0, sizeof(pair)); @@ -1307,7 +1320,7 @@ get_proppair(sa, mode) pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_P, (struct isakmp_gen *)bp, tlen); if (pbuf == NULL) - return NULL; + goto bad; for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type != ISAKMP_NPTYPE_NONE; @@ -1317,7 +1330,7 @@ get_proppair(sa, mode) plog(LLV_ERROR, LOCATION, NULL, "Invalid payload type=%u\n", pa->type); vfree(pbuf); - return NULL; + goto bad; } prop = (struct isakmp_pl_p *)pa->ptr; @@ -1330,7 +1343,7 @@ get_proppair(sa, mode) plog(LLV_ERROR, LOCATION, NULL, "invalid proposal with length %d\n", proplen); vfree(pbuf); - return NULL; + goto bad; } /* check Protocol ID */ @@ -1350,7 +1363,7 @@ get_proppair(sa, mode) /* get transform */ if (get_transform(prop, pair, &num_p) < 0) { vfree(pbuf); - return NULL; + goto bad; } } vfree(pbuf); @@ -1412,10 +1425,14 @@ get_proppair(sa, mode) if (num_p <= 0) { plog(LLV_ERROR, LOCATION, NULL, "no Proposal found.\n"); - return NULL; + goto bad; } return pair; +bad: + if (pair != NULL) + racoon_free(pair); + return NULL; } /* @@ -1660,8 +1677,8 @@ get_sabysaprop(pp0, sa0) struct saprop *pp0; vchar_t *sa0; { - struct prop_pair **pair; - vchar_t *newsa; + struct prop_pair **pair = NULL; + vchar_t *newsa = NULL; int newtlen; u_int8_t *np_p = NULL; struct prop_pair *p = NULL; @@ -1674,13 +1691,13 @@ get_sabysaprop(pp0, sa0) /* get proposal pair */ pair = get_proppair(sa0, IPSECDOI_TYPE_PH2); if (pair == NULL) - return NULL; + goto bad; newtlen = sizeof(struct ipsecdoi_sa_b); for (pp = pp0; pp; pp = pp->next) { if (pair[pp->prop_no] == NULL) - return NULL; + goto bad; for (pr = pp->head; pr; pr = pr->next) { newtlen += (sizeof(struct isakmp_pl_p) @@ -1692,7 +1709,7 @@ get_sabysaprop(pp0, sa0) break; } if (p == NULL) - return NULL; + goto bad; newtlen += ntohs(p->trns->h.len); } @@ -1702,7 +1719,7 @@ get_sabysaprop(pp0, sa0) newsa = vmalloc(newtlen); if (newsa == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to get newsa.\n"); - return NULL; + goto bad; } bp = newsa->v; @@ -1723,7 +1740,7 @@ get_sabysaprop(pp0, sa0) break; } if (p == NULL) - return NULL; + goto bad; trnslen = ntohs(p->trns->h.len); @@ -1749,6 +1766,13 @@ get_sabysaprop(pp0, sa0) } return newsa; + +bad: + if (newsa != NULL) + vfree(newsa); + if (pair != NULL) + racoon_free(pair); + return NULL; } /* @@ -2087,20 +2111,32 @@ check_attr_isakmp(trns) case OAKLEY_ATTR_AUTH_METHOD_RSASIG: #ifdef ENABLE_HYBRID case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: -#endif + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: +#if 0 /* Clashes with OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB */ + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: +#endif +#endif case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: break; case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: #ifdef ENABLE_HYBRID - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + 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 %d isn't supported.\n", - lorv); + "auth method %s isn't supported.\n", + s_oakley_attr_method(lorv)); return -1; default: plog(LLV_ERROR, LOCATION, NULL, @@ -2806,8 +2842,8 @@ setph1attr(sa, buf) else attrlen += sa->gssid->l * 2; if (buf) { - plog(LLV_DEBUG, LOCATION, NULL, "gss id attr: len %d, " - "val '%.*s'\n", sa->gssid->l, sa->gssid->l, + 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, @@ -3364,9 +3400,8 @@ ipsecdoi_checkid1(iph1) switch (id->idtype) { case IDTYPE_ASN1DN: - ident.v = (caddr_t)(id_b + 1); - ident.l = iph1->id_p->l - 1; /* had ident.l = ident0->l; but why?? */ - /* is the actual packet contents length sometimes wrong? */ + ident.v = iph1->id_p->v + sizeof(*id_b); + ident.l = iph1->id_p->l - sizeof(*id_b); if (eay_cmp_asn1dn(ident0, &ident) == 0) goto matched; break; @@ -3559,6 +3594,15 @@ 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; @@ -3580,9 +3624,6 @@ set_identifier(vpp, type, value) "Empty %s\n", type == IDTYPE_FQDN ? "fqdn":"user fqdn"); return -1; } -#ifdef ENABLE_HYBRID - case IDTYPE_LOGIN: -#endif /* length is adjusted since QUOTEDSTRING teminates NULL. */ new = vmalloc(value->l - 1); if (new == NULL) @@ -3590,31 +3631,54 @@ set_identifier(vpp, type, value) memcpy(new->v, value->v, new->l); break; case IDTYPE_KEYID: - { - 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; + /* + * 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; + } + break; } - tlen = 0; - while ((len = fread(b, 1, sizeof(b), fp)) != 0) { - new = vrealloc(new, tlen + len); - if (!new) { - fclose(fp); + + 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 + tlen, b, len); - tlen += len; + memcpy(new->v, value->v, new->l); + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "unknown qualifier"); + return -1; } break; - } - case IDTYPE_ADDRESS: - { + + case IDTYPE_ADDRESS: { struct sockaddr *sa; /* length is adjusted since QUOTEDSTRING teminates NULL. */ @@ -3629,9 +3693,12 @@ set_identifier(vpp, type, value) } new = vmalloc(sysdep_sa_len(sa)); - if (new == NULL) + if (new == NULL) { + racoon_free(sa); return -1; + } memcpy(new->v, sa, new->l); + racoon_free(sa); break; } case IDTYPE_ASN1DN: @@ -3818,6 +3885,71 @@ ipsecdoi_sockaddr2id(saddr, prefixlen, ul_proto) 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. @@ -3950,16 +4082,195 @@ ipsecdoi_id2sockaddr(buf, saddr, prefixlen, ul_proto) /* * make printable string from ID payload except of general header. */ -const char * +char * ipsecdoi_id2str(id) const vchar_t *id; { - static char buf[256]; +#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; + struct sockaddr 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: + + saddr.sa_len = sizeof(struct sockaddr_in); + saddr.sa_family = AF_INET; + ((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY; + memcpy(&((struct sockaddr_in *)&saddr)->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: + + saddr.sa_len = sizeof(struct sockaddr_in6); + saddr.sa_family = AF_INET6; + ((struct sockaddr_in6 *)&saddr)->sin6_port = IPSEC_PORT_ANY; + memcpy(&((struct sockaddr_in6 *)&saddr)->sin6_addr, + id->v + sizeof(*id_b), sizeof(struct in6_addr)); + 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)); + 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++) { + if (plen >= max) + break; + plen += 8; + } - /* XXX */ - buf[0] = '\0'; + if (plen < max) { + u_int l = 0; + u_char b = ~(*p); - return buf; + while (b) { + b >>= 1; + l++; + } + + l = 8 - l; + plen += l; + } + + len = snprintf( buf, BUFLEN, "%s/%i", saddrwop2str(&saddr), plen); + } + break; + + case IPSECDOI_ID_IPV4_ADDR_RANGE: + + len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(&saddr)); + + saddr.sa_len = sizeof(struct sockaddr_in); + saddr.sa_family = AF_INET; + ((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY; + memcpy(&((struct sockaddr_in *)&saddr)->sin_addr, + id->v + sizeof(*id_b) + sizeof(struct in_addr), + sizeof(struct in_addr)); + + len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr)); + + break; + +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR_RANGE: + + len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(&saddr)); + + saddr.sa_len = sizeof(struct sockaddr_in6); + saddr.sa_family = AF_INET6; + ((struct sockaddr_in6 *)&saddr)->sin6_port = IPSEC_PORT_ANY; + memcpy(&((struct sockaddr_in6 *)&saddr)->sin6_addr, + id->v + sizeof(*id_b) + sizeof(struct in6_addr), + sizeof(struct in6_addr)); + + len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr)); + + 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: + { + dat = id->v + sizeof(*id_b); + len = id->l - sizeof(*id_b); + + X509_NAME *xn = NULL; + 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; } /* @@ -4218,9 +4529,6 @@ static int rm_idtype2doi[] = { 255, /* IDTYPE_ADDRESS, 4 * it expands into 4 types by another function. */ IPSECDOI_ID_DER_ASN1_DN, /* IDTYPE_ASN1DN, 5 */ -#ifdef ENABLE_HYBRID - 255, /* IDTYPE_LOGIN, 6 */ -#endif }; /* @@ -4276,16 +4584,16 @@ switch_authmethod(authmethod) case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I; break; - /* Those are not implemented */ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_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_RSASIG_R: authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I; break; + /* Those are not implemented */ + 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; diff --git a/crypto/dist/ipsec-tools/src/racoon/ipsec_doi.h b/crypto/dist/ipsec-tools/src/racoon/ipsec_doi.h index 1ba00f073e0be..3cd34377fc1ae 100644 --- a/crypto/dist/ipsec-tools/src/racoon/ipsec_doi.h +++ b/crypto/dist/ipsec-tools/src/racoon/ipsec_doi.h @@ -1,6 +1,6 @@ -/* $NetBSD: ipsec_doi.h,v 1.1.1.4 2005/11/21 14:12:08 manu Exp $ */ +/* $NetBSD: ipsec_doi.h,v 1.1.1.5 2006/09/09 16:11:53 manu Exp $ */ -/* Id: ipsec_doi.h,v 1.9.2.2 2005/10/17 16:23:50 monas 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. @@ -181,8 +181,12 @@ struct ipsecdoi_pl_id { #define IDTYPE_KEYID 3 #define IDTYPE_ADDRESS 4 #define IDTYPE_ASN1DN 5 -#define IDTYPE_LOGIN 6 -#define IDTYPE_SUBNET 7 +#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 @@ -206,11 +210,14 @@ extern vchar_t *get_sabysaprop __P((struct saprop *, vchar_t *)); 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 const char *ipsecdoi_id2str __P((const vchar_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 isakmpsa *)); extern int ipsecdoi_setph2proposal __P((struct ph2handle *)); diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp.c b/crypto/dist/ipsec-tools/src/racoon/isakmp.c index a4d834722e48b..4a8c704f6558f 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp.c +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp.c @@ -1,6 +1,6 @@ -/* $NetBSD: isakmp.c,v 1.1.1.6 2005/10/14 13:21:46 manu Exp $ */ +/* $NetBSD: isakmp.c,v 1.1.1.7 2006/09/09 16:11:55 manu Exp $ */ -/* Id: isakmp.c,v 1.34.2.20 2005/09/26 16:12:20 manubsd Exp */ +/* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -66,7 +66,9 @@ #include #endif #include -#include +#ifdef ENABLE_HYBRID +#include +#endif #include "var.h" #include "misc.h" @@ -86,7 +88,6 @@ #include "oakley.h" #include "evt.h" #include "handler.h" -#include "proposal.h" #include "ipsec_doi.h" #include "pfkey.h" #include "crypto_openssl.h" @@ -98,7 +99,9 @@ #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 @@ -106,17 +109,18 @@ #endif #include "strnames.h" +#include + #ifdef ENABLE_NATT # include "nattraversal.h" # ifdef __linux__ # include -#include - # ifndef SOL_UDP # define SOL_UDP 17 # endif # endif /* __linux__ */ -# if defined(__NetBSD__) || defined(__FreeBSD__) +# if defined(__NetBSD__) || defined(__FreeBSD__) || \ + (defined(__APPLE__) && defined(__MACH__)) # include # include # define SOL_UDP IPPROTO_UDP @@ -303,8 +307,6 @@ isakmp_handler(so_isakmp) memcpy (buf->v, tmpbuf->v + extralen, buf->l); - vfree (tmpbuf); - len -= extralen; if (len != buf->l) { @@ -364,6 +366,8 @@ isakmp_handler(so_isakmp) error = 0; end: + if (tmpbuf != NULL) + vfree(tmpbuf); if (buf != NULL) vfree(buf); @@ -457,10 +461,26 @@ isakmp_main(msg, remote, local) /* 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 @@ -480,8 +500,10 @@ isakmp_main(msg, remote, local) if (cmpsaddrstrict(iph1->remote, remote) != 0) { char *saddr_db, *saddr_act; - saddr_db = strdup(saddr2str(iph1->remote)); - saddr_act = strdup(saddr2str(remote)); + 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", @@ -632,7 +654,13 @@ isakmp_main(msg, remote, local) 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); @@ -818,9 +846,14 @@ ph1_main(iph1, msg) isakmp_ph1expire_stub, iph1); #ifdef ENABLE_HYBRID if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { - switch(iph1->approval->authmethod) { - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + switch(AUTHMETHOD(iph1)) { + 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; @@ -860,8 +893,24 @@ ph1_main(iph1, msg) * case it is done when we receive the configuration. */ if ((iph1->status == PHASE1ST_ESTABLISHED) && - !iph1->rmconf->mode_cfg) - script_hook(iph1, SCRIPT_PHASE1_UP); + !iph1->rmconf->mode_cfg) { + switch (AUTHMETHOD(iph1)) { +#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; @@ -974,8 +1023,11 @@ isakmp_ph1begin_i(rmconf, remote, local) iph1->gssapi_state = NULL; #endif #ifdef ENABLE_HYBRID - if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) + if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { + remph1(iph1); + delph1(iph1); return -1; + } #endif #ifdef ENABLE_FRAG iph1->frag = 0; @@ -984,8 +1036,11 @@ isakmp_ph1begin_i(rmconf, remote, local) iph1->approval = NULL; /* XXX copy remote address */ - if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) + if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) { + remph1(iph1); + delph1(iph1); return -1; + } (void)insph1(iph1); @@ -996,7 +1051,9 @@ isakmp_ph1begin_i(rmconf, remote, local) { char *a; - a = strdup(saddr2str(iph1->local)); + 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)); @@ -1081,8 +1138,11 @@ isakmp_ph1begin_r(msg, remote, local, etype) iph1->gssapi_state = NULL; #endif #ifdef ENABLE_HYBRID - if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) + if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { + remph1(iph1); + delph1(iph1); return -1; + } #endif #ifdef ENABLE_FRAG iph1->frag = 0; @@ -1100,8 +1160,11 @@ isakmp_ph1begin_r(msg, remote, local, etype) #endif /* copy remote address */ - if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) + if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) { + remph1(iph1); + delph1(iph1); return -1; + } (void)insph1(iph1); @@ -1109,7 +1172,9 @@ isakmp_ph1begin_r(msg, remote, local, etype) { char *a; - a = strdup(saddr2str(iph1->local)); + 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)); @@ -1165,7 +1230,9 @@ isakmp_ph2begin_i(iph1, iph2) plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n"); { char *a; - a = strdup(saddr2str(iph2->src)); + 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)); @@ -1235,13 +1302,13 @@ isakmp_ph2begin_r(iph1, msg) } switch (iph2->dst->sa_family) { case AF_INET: -#ifndef ENABLE_NATT +#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in *)iph2->dst)->sin_port = 0; #endif break; #ifdef INET6 case AF_INET6: -#ifndef ENABLE_NATT +#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0; #endif break; @@ -1260,13 +1327,13 @@ isakmp_ph2begin_r(iph1, msg) } switch (iph2->src->sa_family) { case AF_INET: -#ifndef ENABLE_NATT +#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in *)iph2->src)->sin_port = 0; #endif break; #ifdef INET6 case AF_INET6: -#ifndef ENABLE_NATT +#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0; #endif break; @@ -1286,7 +1353,9 @@ isakmp_ph2begin_r(iph1, msg) { char *a; - a = strdup(saddr2str(iph2->src)); + 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)); @@ -1554,6 +1623,10 @@ isakmp_open() goto err_and_next; } + if (fcntl(p->sock, 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 (p->addr->sa_family) { case AF_INET: @@ -1565,7 +1638,8 @@ isakmp_open() #endif (const void *)&yes, sizeof(yes)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt (%s)\n", strerror(errno)); + "setsockopt IP_RECVDSTADDR (%s)\n", + strerror(errno)); goto err_and_next; } break; @@ -1584,12 +1658,8 @@ isakmp_open() (const void *)&yes, sizeof(yes)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt(%d): %s\n", + "setsockopt IPV6_RECVDSTADDR (%d):%s\n", pktinfo, strerror(errno)); - if (fcntl(p->sock, F_SETFL, O_NONBLOCK) == -1) - plog(LLV_WARNING, LOCATION, NULL, - "failed to put socket in non-blocking mode\n"); - goto err_and_next; } break; @@ -1601,7 +1671,8 @@ isakmp_open() setsockopt(p->sock, IPPROTO_IPV6, IPV6_USE_MIN_MTU, (void *)&yes, sizeof(yes)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt (%s)\n", strerror(errno)); + "setsockopt IPV6_USE_MIN_MTU (%s)\n", + strerror(errno)); return -1; } #endif @@ -1635,11 +1706,11 @@ isakmp_open() option = UDP_ENCAP_ESPINUDP_NON_IKE; #endif if(option != -1){ - if (setsockopt (p->sock, SOL_UDP, UDP_ENCAP, - &option, sizeof (option)) < 0) { + if (setsockopt (p->sock, SOL_UDP, + UDP_ENCAP, &option, sizeof (option)) < 0) { plog(LLV_WARNING, LOCATION, NULL, - "setsockopt(%s): %s\n", - option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE", + "setsockopt(%s): UDP_ENCAP %s\n", + option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE", strerror(errno)); goto skip_encap; } @@ -1729,7 +1800,11 @@ isakmp_send(iph1, sbuf) must added just before the packet itself. For this we must allocate a new buffer and release it at the end. */ if (extralen) { - vbuf = vmalloc (sbuf->l + 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); sbuf = vbuf; @@ -1761,6 +1836,7 @@ isakmp_send(iph1, sbuf) { 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"); if ( vbuf != NULL ) @@ -1799,8 +1875,13 @@ isakmp_ph1resend(iph1) return -1; } - if (isakmp_send(iph1, iph1->sendbuf) < 0) + if (isakmp_send(iph1, iph1->sendbuf) < 0){ + iph1->retry_counter--; + + iph1->scr = sched_new(iph1->rmconf->retry_interval, + isakmp_ph1resend_stub, iph1); return -1; + } plog(LLV_DEBUG, LOCATION, NULL, "resend phase1 packet %s\n", @@ -1871,8 +1952,11 @@ isakmp_ph1expire(iph1) SCHED_KILL(iph1->sce); if(iph1->status != PHASE1ST_EXPIRED){ - src = strdup(saddr2str(iph1->local)); - dst = strdup(saddr2str(iph1->remote)); + 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, @@ -1917,8 +2001,11 @@ isakmp_ph1delete(iph1) /* don't re-negosiation when the phase 1 SA expires. */ - src = strdup(saddr2str(iph1->local)); - dst = strdup(saddr2str(iph1->remote)); + 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)); @@ -1954,8 +2041,11 @@ isakmp_ph2expire(iph2) SCHED_KILL(iph2->sce); - src = strdup(saddrwop2str(iph2->src)); - dst = strdup(saddrwop2str(iph2->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); @@ -1985,8 +2075,11 @@ isakmp_ph2delete(iph2) SCHED_KILL(iph2->sce); - src = strdup(saddrwop2str(iph2->src)); - dst = strdup(saddrwop2str(iph2->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); @@ -2012,6 +2105,8 @@ isakmp_post_acquire(iph2) { struct remoteconf *rmconf; struct ph1handle *iph1 = NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "in post_acquire\n"); /* search appropreate configuration with masking port. */ rmconf = getrmconf(iph2->dst); @@ -2817,13 +2912,20 @@ log_ph1established(iph1) { char *src, *dst; - src = strdup(saddr2str(iph1->local)); - dst = strdup(saddr2str(iph1->remote)); + 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_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_UP, NULL); + if(!iph1->rmconf->mode_cfg) + EVT_PUSH(iph1->local, iph1->remote, EVTT_NO_ISAKMP_CFG, NULL); + racoon_free(src); racoon_free(dst); @@ -2853,21 +2955,13 @@ isakmp_plist_append (struct payload_list *plist, vchar_t *payload, int payload_t vchar_t * isakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1) { - struct payload_list *ptr, *first; + struct payload_list *ptr = *plist, *first; size_t tlen = sizeof (struct isakmp), n = 0; - vchar_t *buf; + vchar_t *buf = NULL; char *p; - if (plist == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "in isakmp_plist_set_all: plist == NULL\n"); - return NULL; - } - /* Seek to the first item. */ - ptr = *plist; - while (ptr->prev) - ptr = ptr->prev; + while (ptr->prev) ptr = ptr->prev; first = ptr; /* Compute the whole length. */ @@ -2903,6 +2997,8 @@ isakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1) return buf; end: + if (buf != NULL) + vfree(buf); return NULL; } @@ -2943,7 +3039,9 @@ script_hook(iph1, script) struct sockaddr_in *sin; char **c; - if (iph1->rmconf->script[script] == -1) + if (iph1 == NULL || + iph1->rmconf == NULL || + iph1->rmconf->script[script] == NULL) return; #ifdef ENABLE_HYBRID @@ -2980,7 +3078,7 @@ script_hook(iph1, script) goto out; } - if (privsep_script_exec(iph1->rmconf->script[script], + 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]); @@ -3018,6 +3116,7 @@ script_env_append(envp, envc, name, value) if (newenvp == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory: %s\n", strerror(errno)); + racoon_free(envitem); return -1; } @@ -3031,22 +3130,13 @@ script_env_append(envp, envc, name, value) int script_exec(script, name, envp) - int script; + char *script; int name; char *const envp[]; { char *argv[] = { NULL, NULL, NULL }; - vchar_t **sp; - - if (script_paths == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "privsep_script_exec: script_paths was not initialized\n"); - return -1; - } - sp = (vchar_t **)(script_paths->v); - - argv[0] = sp[script]->v; + argv[0] = script; argv[1] = script_names[name]; argv[2] = NULL; @@ -3066,8 +3156,8 @@ script_exec(script, name, envp) default: break; } - return 0; + } void @@ -3140,7 +3230,11 @@ purge_remote(iph1) continue; } - /* check in/outbound SAs */ + /* + * 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(iph1->remote, dst)) && (CMPSADDR(iph1->local, dst) || CMPSADDR(iph1->remote, src))) { msg = next; @@ -3222,236 +3316,251 @@ void delete_spd(iph2) struct ph2handle *iph2; { + 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) { - struct policyindex spidx; - struct sockaddr_storage addr; - u_int8_t pref; - struct sockaddr *src = iph2->src; - struct sockaddr *dst = iph2->dst; - int error; - int idi2type = 0;/* switch whether copy IDs into id[src,dst]. */ + if (! iph2->generated_spidx ) + return; - plog(LLV_INFO, LOCATION, NULL, - "generated policy, deleting it.\n"); + src = iph2->src; + dst = iph2->dst; + + plog(LLV_INFO, LOCATION, NULL, + "generated policy, deleting it.\n"); - memset(&spidx, 0, sizeof(spidx)); - iph2->spidx_gen = (caddr_t )&spidx; + 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; + /* make inbound policy */ + iph2->src = dst; + iph2->dst = src; + spidx.dir = IPSEC_DIR_INBOUND; + spidx.ul_proto = 0; - /* - * Note: code from get_proposal_r - */ + /* + * 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 + /* + * 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; + /* 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; - } + /* + * 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); + if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR + || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) + idi2type = _XIDT(iph2->id); - } else { + } 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"); + 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; + /* + * 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; - } + 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 + /* 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; + /* 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; - } + /* + * 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 id[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->src_id = - dupsaddr((struct sockaddr *)&spidx.dst); - iph2->dst_id = - dupsaddr((struct sockaddr *)&spidx.src); + /* make id[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->src_id = + dupsaddr((struct sockaddr *)&spidx.dst); + if (iph2->src_id == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "allocation failed\n"); + goto purge; } + iph2->dst_id = + dupsaddr((struct sockaddr *)&spidx.src); + if (iph2->dst_id == 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; + } 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; - } + 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); + 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; + /* + * 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 - /* End of code from get_proposal_r - */ + /* 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(inbound) failed.\n"); + "pfkey spddelete(forward) 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"); - } + "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; + /* 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; + 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) diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp.h b/crypto/dist/ipsec-tools/src/racoon/isakmp.h index 55bf53783e7bc..b5b46c50a2477 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp.h +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp.h @@ -1,6 +1,6 @@ -/* $NetBSD: isakmp.h,v 1.1.1.2 2005/02/23 14:54:18 manu Exp $ */ +/* $NetBSD: isakmp.h,v 1.1.1.3 2006/09/09 16:11:56 manu Exp $ */ -/* Id: isakmp.h,v 1.10 2005/01/29 16:34:25 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. @@ -350,6 +350,8 @@ struct isakmp_pl_n { #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 */ diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp_agg.c b/crypto/dist/ipsec-tools/src/racoon/isakmp_agg.c index c8522f449185f..c583e7205a1f3 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_agg.c +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_agg.c @@ -1,6 +1,6 @@ -/* $NetBSD: isakmp_agg.c,v 1.1.1.5 2005/11/21 14:12:12 manu Exp $ */ +/* $NetBSD: isakmp_agg.c,v 1.1.1.6 2006/09/09 16:11:57 manu Exp $ */ -/* Id: isakmp_agg.c,v 1.20.2.5 2005/11/21 09:46:23 vanhu 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. @@ -61,6 +61,10 @@ #include "schedule.h" #include "debug.h" +#ifdef ENABLE_HYBRID +#include +#endif + #include "localconf.h" #include "remoteconf.h" #include "isakmp_var.h" @@ -110,7 +114,7 @@ agg_i1send(iph1, msg) { struct payload_list *plist = NULL; int need_cr = 0; - vchar_t *cr = NULL, *gsstoken = NULL; + vchar_t *cr = NULL; int error = -1; #ifdef ENABLE_NATT vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL }; @@ -124,6 +128,7 @@ agg_i1send(iph1, msg) vchar_t *vid_frag = NULL; #endif #ifdef HAVE_GSSAPI + vchar_t *gsstoken = NULL; int len; #endif #ifdef ENABLE_DPD @@ -175,9 +180,14 @@ agg_i1send(iph1, msg) #ifdef ENABLE_HYBRID /* Do we need Xauth VID? */ - switch (iph1->rmconf->proposal->authmethod) { - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + switch (RMAUTHMETHOD(iph1)) { + case FICTIVE_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"); @@ -218,10 +228,8 @@ agg_i1send(iph1, msg) 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) { + if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) gssapi_get_itoken(iph1, &len); - } #endif /* set SA payload to propose */ @@ -237,11 +245,10 @@ agg_i1send(iph1, msg) 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 (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { gssapi_get_token_to_send(iph1, &gsstoken); plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); - } else + } #endif /* create isakmp CR payload */ if (need_cr) @@ -293,8 +300,10 @@ agg_i1send(iph1, msg) end: if (cr) vfree(cr); +#ifdef HAVE_GSSAPI if (gsstoken) vfree(gsstoken); +#endif #ifdef ENABLE_FRAG if (vid_frag) vfree(vid_frag); @@ -303,16 +312,16 @@ agg_i1send(iph1, msg) for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++) vfree(vid_natt[i]); #endif -#ifdef ENABLE_DPD - if (vid_dpd != NULL) - vfree(vid_dpd); -#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; } @@ -595,6 +604,10 @@ agg_i2recv(iph1, msg) error = 0; end: +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif if (pbuf) vfree(pbuf); if (satmp) @@ -645,28 +658,35 @@ agg_i2send(iph1, msg) iph1->hash = oakley_ph1hash_common(iph1, GENERATE); if (iph1->hash == NULL) { #ifdef HAVE_GSSAPI - if (gssapi_more_tokens(iph1)) + 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) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: #ifdef ENABLE_HYBRID - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case FICTIVE_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); + 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_I: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: -#endif + 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) @@ -680,14 +700,20 @@ agg_i2send(iph1, msg) /* add CERT payload if there */ if (need_cert) - plist = isakmp_plist_append(plist, iph1->cert->pl, ISAKMP_NPTYPE_CERT); + plist = isakmp_plist_append(plist, + iph1->cert->pl, ISAKMP_NPTYPE_CERT); /* add SIG payload */ - plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG); + 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: @@ -700,37 +726,38 @@ agg_i2send(iph1, msg) goto end; } - plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH); + plist = isakmp_plist_append(plist, + gsshash, ISAKMP_NPTYPE_HASH); break; #endif - default: - plog(LLV_ERROR, LOCATION, NULL, "invalid authmethod %d\n", - iph1->approval->authmethod); - goto end; - break; } #ifdef ENABLE_NATT /* generate NAT-D payloads */ - if (NATT_AVAILABLE(iph1)) - { + if (NATT_AVAILABLE(iph1)) { vchar_t *natd[2] = { NULL, NULL }; - plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n"); + 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)); + "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)); + "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); + 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 @@ -932,6 +959,10 @@ agg_r1recv(iph1, msg) error = 0; end: +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif if (pbuf) vfree(pbuf); if (error) { @@ -976,11 +1007,15 @@ agg_r1send(iph1, msg) #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 */ @@ -1023,8 +1058,7 @@ agg_r1send(iph1, msg) goto end; #ifdef HAVE_GSSAPI - if (iph1->rmconf->proposal->authmethod == - OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) + if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) gssapi_get_rtoken(iph1, &gsslen); #endif @@ -1079,37 +1113,60 @@ agg_r1send(iph1, msg) 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) { + switch (AUTHMETHOD(iph1)) { 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); + 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); + plist = isakmp_plist_append(plist, + iph1->dhpub, ISAKMP_NPTYPE_KE); /* create isakmp NONCE payload */ - plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE); + plist = isakmp_plist_append(plist, + iph1->nonce, ISAKMP_NPTYPE_NONCE); /* create isakmp ID payload */ - plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); + plist = isakmp_plist_append(plist, + iph1->id, ISAKMP_NPTYPE_ID); /* create isakmp HASH payload */ - plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH); + 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); + plist = isakmp_plist_append(plist, + vid, ISAKMP_NPTYPE_VID); /* create isakmp CR payload if needed */ if (need_cr) - plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR); + plist = isakmp_plist_append(plist, + cr, ISAKMP_NPTYPE_CR); 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_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: #endif /* XXX if there is CR or not ? */ @@ -1123,30 +1180,111 @@ agg_r1send(iph1, msg) need_cert = 1; /* set SA payload to reply */ - plist = isakmp_plist_append(plist, iph1->sa_ret, ISAKMP_NPTYPE_SA); + 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); + plist = isakmp_plist_append(plist, + iph1->dhpub, ISAKMP_NPTYPE_KE); /* create isakmp NONCE payload */ - plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE); + plist = isakmp_plist_append(plist, + iph1->nonce, ISAKMP_NPTYPE_NONCE); /* add ID payload */ - plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); + 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->pl, ISAKMP_NPTYPE_CERT); + plist = isakmp_plist_append(plist, + iph1->cert->pl, ISAKMP_NPTYPE_CERT); /* add SIG payload */ - plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG); + plist = isakmp_plist_append(plist, + iph1->sig, ISAKMP_NPTYPE_SIG); /* append vendor id, if needed */ if (vid) - plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); + plist = isakmp_plist_append(plist, + vid, ISAKMP_NPTYPE_VID); + + /* create isakmp CR payload if needed */ + if (need_cr) + plist = isakmp_plist_append(plist, + cr, ISAKMP_NPTYPE_CR); + 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->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 */ + gssapi_get_token_to_send(iph1, &gsstoken); + 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 */ + if (vid) + plist = isakmp_plist_append(plist, + vid, ISAKMP_NPTYPE_VID); + + 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"); @@ -1167,68 +1305,6 @@ agg_r1send(iph1, msg) } #endif - /* create isakmp CR payload if needed */ - if (need_cr) - plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR); - break; - - case OAKLEY_ATTR_AUTH_METHOD_RSAENC: - case OAKLEY_ATTR_AUTH_METHOD_RSAREV: - 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->approval); - else - gss_sa = iph1->sa_ret; - - /* 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 */ - gssapi_get_token_to_send(iph1, &gsstoken); - 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 */ - if (vid) - plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); - - break; -#endif - default: - plog(LLV_ERROR, LOCATION, NULL, "Invalid authmethod %d\n", - iph1->approval->authmethod); - goto end; - break; - } - #ifdef ENABLE_NATT /* append NAT-T payloads */ if (vid_natt) { @@ -1239,6 +1315,12 @@ agg_r1send(iph1, msg) 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); @@ -1282,13 +1364,17 @@ agg_r1send(iph1, msg) vfree(gsstoken); if (gsshash) vfree(gsshash); - if (gss_sa != iph1->sa_ret) + 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; } diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp_base.c b/crypto/dist/ipsec-tools/src/racoon/isakmp_base.c index 61a50a9d1ea85..f3f421f4bfc8d 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_base.c +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_base.c @@ -1,4 +1,4 @@ -/* $NetBSD: isakmp_base.c,v 1.1.1.3 2005/10/14 13:21:47 manu Exp $ */ +/* $NetBSD: isakmp_base.c,v 1.1.1.4 2006/09/09 16:11:47 manu Exp $ */ /* $KAME: isakmp_base.c,v 1.49 2003/11/13 02:30:20 sakane Exp $ */ @@ -61,6 +61,10 @@ #include "schedule.h" #include "debug.h" +#ifdef ENABLE_HYBRID +#include +#endif + #include "localconf.h" #include "remoteconf.h" #include "isakmp_var.h" @@ -80,6 +84,10 @@ #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. @@ -105,6 +113,14 @@ base_i1send(iph1, msg) #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) { @@ -136,6 +152,28 @@ base_i1send(iph1, msg) if (iph1->nonce == NULL) goto end; +#ifdef ENABLE_HYBRID + /* Do we need Xauth VID? */ + switch (RMAUTHMETHOD(iph1)) { + case FICTIVE_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); @@ -184,13 +222,28 @@ base_i1send(iph1, msg) 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); - - iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); #endif + iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); @@ -214,6 +267,16 @@ base_i1send(iph1, msg) 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; } @@ -235,6 +298,10 @@ base_i2recv(iph1, msg) vchar_t *satmp = NULL; int error = -1; int vid_numeric; +#ifdef ENABLE_HYBRID + vchar_t *unity_vid; + vchar_t *xauth_vid; +#endif /* validity check */ if (iph1->status != PHASE1ST_MSG1SENT) { @@ -279,6 +346,29 @@ base_i2recv(iph1, msg) #ifdef ENABLE_NATT if (iph1->rmconf->nat_traversal && 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->dpd) { + iph1->dpd_support=1; + plog(LLV_DEBUG, LOCATION, NULL, + "remote supports DPD\n"); + } #endif break; default: @@ -372,10 +462,21 @@ base_i2send(iph1, msg) goto end; /* generate SKEYID to compute hash if not signature mode */ - if (iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_RSASIG - && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_DSSSIG) { + switch (AUTHMETHOD(iph1)) { + 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 */ @@ -383,9 +484,13 @@ base_i2send(iph1, msg) iph1->hash = oakley_ph1hash_base_i(iph1, GENERATE); if (iph1->hash == NULL) goto end; - - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case FICTIVE_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 */ @@ -400,6 +505,10 @@ base_i2send(iph1, msg) 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) @@ -412,25 +521,30 @@ base_i2send(iph1, msg) need_cert = 1; /* create isakmp KE payload */ - plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE); + 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->pl, ISAKMP_NPTYPE_CERT); + plist = isakmp_plist_append(plist, + iph1->cert->pl, ISAKMP_NPTYPE_CERT); /* add SIG payload */ - plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG); + 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: - break; - default: - plog(LLV_ERROR, LOCATION, NULL, "invalid authmethod %d\n", - iph1->approval->authmethod); - goto end; +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: +#endif break; } @@ -614,10 +728,21 @@ base_i3recv(iph1, msg) goto end; /* generate SKEYID to compute hash if signature mode */ - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_RSASIG - || iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_DSSSIG) { + switch (AUTHMETHOD(iph1)) { + 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 */ @@ -748,6 +873,29 @@ base_r1recv(iph1, msg) (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_BASE)) iph1->frag = 1; #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->dpd) { + iph1->dpd_support=1; + plog(LLV_DEBUG, LOCATION, NULL, + "remote supports DPD\n"); + } +#endif break; default: /* don't send information, see ident_r1recv() */ @@ -821,6 +969,16 @@ base_r1send(iph1, msg) #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) { @@ -857,6 +1015,56 @@ base_r1send(iph1, msg) 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); @@ -885,6 +1093,20 @@ base_r1send(iph1, msg) 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 VPTRINIT(iph1->sa_ret); @@ -1069,15 +1291,30 @@ base_r2send(iph1, msg) /* generate HASH to send */ plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n"); - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { 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: @@ -1089,22 +1326,34 @@ base_r2send(iph1, msg) if (iph1->hash == NULL) goto end; - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { 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); + plist = isakmp_plist_append(plist, + iph1->dhpub, ISAKMP_NPTYPE_KE); /* create isakmp HASH payload */ - plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH); + 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); + 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) @@ -1117,52 +1366,60 @@ base_r2send(iph1, msg) need_cert = 1; /* create isakmp KE payload */ - plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE); + 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->pl, ISAKMP_NPTYPE_CERT); + plist = isakmp_plist_append(plist, + iph1->cert->pl, ISAKMP_NPTYPE_CERT); /* add SIG payload */ - plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG); + 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: - break; - default: - plog(LLV_ERROR, LOCATION, NULL, "invalid authmethod %d\n", - iph1->approval->authmethod); - goto end; +#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)) - { + 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_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)); + "NAT-D hashing failed for %s\n", + saddr2str(iph1->remote)); goto end; } - if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) { + 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)); + "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); + 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); + iph1->sendbuf = isakmp_plist_set_all(&plist, iph1); #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp_cfg.c b/crypto/dist/ipsec-tools/src/racoon/isakmp_cfg.c index bb1cf27713735..a4b0ed6880f87 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_cfg.c +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_cfg.c @@ -1,9 +1,9 @@ -/* $NetBSD: isakmp_cfg.c,v 1.1.1.5 2005/10/14 13:21:47 manu Exp $ */ +/* $NetBSD: isakmp_cfg.c,v 1.1.1.6 2006/09/09 16:11:59 manu Exp $ */ -/* Id: isakmp_cfg.c,v 1.26.2.6 2005/09/23 14:29:45 manubsd Exp */ +/* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */ /* - * Copyright (C) 2004 Emmanuel Dreyfus + * Copyright (C) 2004-2006 Emmanuel Dreyfus * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,6 +38,18 @@ #include #include +#include +#if defined(__APPLE__) && defined(__MACH__) +#include +#endif + +#ifdef __FreeBSD__ +# include +#endif +#ifdef __NetBSD__ +# include +#endif + #include #include @@ -59,7 +71,11 @@ #ifdef HAVE_UNISTD_H #include #endif +#if HAVE_STDINT_H +#include +#endif #include +#include #ifdef HAVE_LIBRADIUS #include @@ -89,21 +105,7 @@ #include "admin.h" #include "privsep.h" -struct isakmp_cfg_config isakmp_cfg_config = { - 0x00000000, /* network4 */ - 0x00000000, /* netmask4 */ - 0x00000000, /* dns4 */ - 0x00000000, /* nbns4 */ - NULL, /* pool */ - ISAKMP_CFG_AUTH_SYSTEM, /* authsource */ - ISAKMP_CFG_CONF_LOCAL, /* confsource */ - ISAKMP_CFG_ACCT_NONE, /* accounting */ - ISAKMP_CFG_MAX_CNX, /* pool_size */ - THROTTLE_PENALTY, /* auth_throttle */ - ISAKMP_CFG_MOTD, /* motd */ - 0, /* pfs_group */ - 0, /* save_passwd */ -}; +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 *); @@ -113,6 +115,12 @@ static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *); static vchar_t *isakmp_cfg_addr4(struct ph1handle *, struct isakmp_data *, 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 @@ -157,7 +165,8 @@ isakmp_cfg_r(iph1, msg) * Decrypt the packet. If this is the beginning of a new * exchange, reinitialize the IV */ - if (iph1->mode_cfg->ivm == NULL) + 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; @@ -267,6 +276,8 @@ isakmp_cfg_attr_r(iph1, msgid, 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 */ @@ -310,6 +321,7 @@ isakmp_cfg_reply(iph1, attrpl) char *npp; int type; struct sockaddr_in *sin; + int error; tlen = ntohs(attrpl->h.len); attr = (struct isakmp_data *)(attrpl + 1); @@ -323,17 +335,20 @@ isakmp_cfg_reply(iph1, attrpl) type &= ~ISAKMP_GEN_MASK; plog(LLV_DEBUG, LOCATION, NULL, - "Short attribute %d = %d\n", - type, ntohs(attr->lorv)); + "Short attribute %s = %d\n", + s_isakmp_cfg_type(type), ntohs(attr->lorv)); switch (type) { case XAUTH_TYPE: - xauth_attr_reply(iph1, attr, ntohs(attrpl->id)); + if ((error = xauth_attr_reply(iph1, + attr, ntohs(attrpl->id))) != 0) + return error; break; default: plog(LLV_WARNING, LOCATION, NULL, - "Ignored short attribute %d\n", type); + "Ignored short attribute %s\n", + s_isakmp_cfg_type(type)); break; } @@ -348,12 +363,14 @@ isakmp_cfg_reply(iph1, attrpl) /* Check that the attribute fit in the packet */ if (tlen < alen) { plog(LLV_ERROR, LOCATION, NULL, - "Short attribute %d\n", type); + "Short attribute %s\n", + s_isakmp_cfg_type(type)); return -1; } plog(LLV_DEBUG, LOCATION, NULL, - "Attribute %d, len %zu\n", type, alen); + "Attribute %s, len %zu\n", + s_isakmp_cfg_type(type), alen); switch(type) { case XAUTH_TYPE: @@ -366,7 +383,9 @@ isakmp_cfg_reply(iph1, attrpl) case XAUTH_STATUS: case XAUTH_NEXT_PIN: case XAUTH_ANSWER: - xauth_attr_reply(iph1, attr, ntohs(attrpl->id)); + 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); @@ -377,28 +396,40 @@ isakmp_cfg_reply(iph1, attrpl) iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4; break; case INTERNAL_IP4_DNS: - isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->dns4); + 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_getaddr4(attr, &iph1->mode_cfg->wins4); + 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 INTERNAL_IP4_SUBNET: - case INTERNAL_ADDRESS_EXPIRY: - case UNITY_BANNER: - case UNITY_SAVE_PASSWD: case UNITY_DEF_DOMAIN: - case UNITY_SPLITDNS_NAME: + 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 %d\n", type); + "Ignored attribute %s\n", + s_isakmp_cfg_type(type)); break; } @@ -412,9 +443,25 @@ isakmp_cfg_reply(iph1, attrpl) * 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) - script_hook(iph1, SCRIPT_PHASE1_UP); + iph1->rmconf->mode_cfg) { + switch (AUTHMETHOD(iph1)) { + case FICTIVE_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 { @@ -470,8 +517,8 @@ isakmp_cfg_request(iph1, attrpl) type &= ~ISAKMP_GEN_MASK; plog(LLV_DEBUG, LOCATION, NULL, - "Short attribute %d = %d\n", - type, ntohs(attr->lorv)); + "Short attribute %s = %d\n", + s_isakmp_cfg_type(type), ntohs(attr->lorv)); switch (type) { case XAUTH_TYPE: @@ -479,7 +526,8 @@ isakmp_cfg_request(iph1, attrpl) break; default: plog(LLV_WARNING, LOCATION, NULL, - "Ignored short attribute %d\n", type); + "Ignored short attribute %s\n", + s_isakmp_cfg_type(type)); break; } @@ -500,12 +548,14 @@ isakmp_cfg_request(iph1, attrpl) /* Check that the attribute fit in the packet */ if (tlen < alen) { plog(LLV_ERROR, LOCATION, NULL, - "Short attribute %d\n", type); + "Short attribute %s\n", + s_isakmp_cfg_type(type)); goto end; } plog(LLV_DEBUG, LOCATION, NULL, - "Attribute %d, len %zu\n", type, alen); + "Attribute %s, len %zu\n", + s_isakmp_cfg_type(type), alen); switch(type) { case INTERNAL_IP4_ADDRESS: @@ -542,6 +592,7 @@ isakmp_cfg_request(iph1, attrpl) 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); @@ -550,7 +601,8 @@ isakmp_cfg_request(iph1, attrpl) case INTERNAL_ADDRESS_EXPIRY: default: plog(LLV_WARNING, LOCATION, NULL, - "Ignored attribute %d\n", type); + "Ignored attribute %s\n", + s_isakmp_cfg_type(type)); break; } @@ -570,12 +622,29 @@ isakmp_cfg_request(iph1, attrpl) 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); - /* Reinit the IV */ - oakley_delivm(iph1->mode_cfg->ivm); - iph1->mode_cfg->ivm = NULL; + if (iph1->status == PHASE1ST_ESTABLISHED) { + switch (AUTHMETHOD(iph1)) { + 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); @@ -614,18 +683,22 @@ isakmp_cfg_set(iph1, attrpl) 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 %d\n", - type & ~ISAKMP_GEN_MASK); + "Unexpected SET attribute %s\n", + s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK)); break; } - if ((reply_attr = vmalloc(sizeof(*reply_attr))) != NULL) { + if (reply_attr != NULL) { payload = buffer_cat(payload, reply_attr); vfree(reply_attr); } @@ -651,6 +724,9 @@ isakmp_cfg_set(iph1, attrpl) 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); @@ -659,6 +735,7 @@ isakmp_cfg_set(iph1, attrpl) isakmp_info_send_d1(iph1); remph1(iph1); delph1(iph1); + iph1 = NULL; } end: vfree(payload); @@ -666,7 +743,7 @@ isakmp_cfg_set(iph1, attrpl) /* * If required, request ISAKMP mode config information */ - if ((iph1->rmconf->mode_cfg) && (error == 0)) + if ((iph1 != NULL) && (iph1->rmconf->mode_cfg) && (error == 0)) error = isakmp_cfg_getconfig(iph1); return error; @@ -700,6 +777,7 @@ isakmp_cfg_net(iph1, attr) struct isakmp_data *attr; { int type; + int confsource; in_addr_t addr4; type = ntohs(attr->type); @@ -713,12 +791,30 @@ isakmp_cfg_net(iph1, attr) 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(isakmp_cfg_config.confsource) { + 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_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 @@ -728,6 +824,8 @@ isakmp_cfg_net(iph1, attr) 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) { @@ -755,14 +853,26 @@ isakmp_cfg_net(iph1, attr) break; case INTERNAL_IP4_NETMASK: - switch(isakmp_cfg_config.confsource) { + 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_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 @@ -779,13 +889,15 @@ isakmp_cfg_net(iph1, attr) break; case INTERNAL_IP4_DNS: - return isakmp_cfg_addr4(iph1, - attr, &isakmp_cfg_config.dns4); + 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(iph1, - attr, &isakmp_cfg_config.nbns4); + return isakmp_cfg_addr4_list(iph1, + attr, &isakmp_cfg_config.nbns4[0], + isakmp_cfg_config.nbns4_index); break; case INTERNAL_IP4_SUBNET: @@ -797,7 +909,6 @@ isakmp_cfg_net(iph1, attr) plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type); break; } - return NULL; } @@ -870,17 +981,16 @@ isakmp_cfg_short(iph1, attr, value) } vchar_t * -isakmp_cfg_string(iph1, attr, string) +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; - size_t len; char *data; - len = strlen(string); if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); return NULL; @@ -896,6 +1006,15 @@ isakmp_cfg_string(iph1, attr, string) 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) @@ -922,6 +1041,42 @@ isakmp_cfg_addr4(iph1, attr, addr) 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; +{ + vchar_t *buffer; + vchar_t *bufone; + 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"); + return NULL; + } + for(i = 0; i < nbr; i++) { + if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory\n"); + return NULL; + } + 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); + } + + return buffer; +} + struct isakmp_ivm * isakmp_cfg_newiv(iph1, msgid) struct ph1handle *iph1; @@ -939,6 +1094,7 @@ isakmp_cfg_newiv(iph1, msgid) oakley_delivm(ics->ivm); ics->ivm = oakley_newiv2(iph1, msgid); + ics->last_msgid = msgid; return ics->ivm; } @@ -976,18 +1132,29 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange) 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; + } + switch (iph1->remote->sa_family) { case AF_INET: -#ifndef ENABLE_NATT +#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in *)iph2->dst)->sin_port = 0; ((struct sockaddr_in *)iph2->src)->sin_port = 0; #endif break; #ifdef INET6 case AF_INET6: +#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0; ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0; +#endif break; #endif default: @@ -1078,6 +1245,9 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange) #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)) { @@ -1133,6 +1303,20 @@ isakmp_cfg_rmstate(iph1) 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); @@ -1253,6 +1437,9 @@ isakmp_cfg_accounting(iph1, inout) 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; } @@ -1454,6 +1641,68 @@ isakmp_cfg_radius_common(radius_state, port) 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 utmp ut; + char term[UT_LINESIZE]; + char addr[NI_MAXHOST]; + + if (usr == NULL || usr[0]=='\0') { + plog(LLV_ERROR, LOCATION, NULL, + "system accounting : no login found\n"); + return -1; + } + + sprintf(term, TERMSPEC, port); + + switch (inout) { + case ISAKMP_CFG_LOGIN: + strncpy(ut.ut_name, usr, UT_NAMESIZE); + ut.ut_name[UT_NAMESIZE - 1] = '\0'; + + strncpy(ut.ut_line, term, UT_LINESIZE); + ut.ut_line[UT_LINESIZE - 1] = '\0'; + + GETNAMEINFO_NULL(raddr, addr); + strncpy(ut.ut_host, addr, UT_HOSTSIZE); + ut.ut_host[UT_HOSTSIZE - 1] = '\0'; + + ut.ut_time = time(NULL); + + plog(LLV_INFO, LOCATION, NULL, + "Accounting : '%s' logging on '%s' from %s.\n", + ut.ut_name, ut.ut_line, ut.ut_host); + + login(&ut); + + break; + case ISAKMP_CFG_LOGOUT: + + plog(LLV_INFO, LOCATION, NULL, + "Accounting : '%s' unlogging from '%s'.\n", + usr, term); + + logout(term); + + break; + default: + plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); + break; + } + + return 0; +} int isakmp_cfg_getconfig(iph1) @@ -1472,6 +1721,10 @@ isakmp_cfg_getconfig(iph1) INTERNAL_IP4_DNS, INTERNAL_IP4_NBNS, UNITY_BANNER, + UNITY_DEF_DOMAIN, + UNITY_SPLITDNS_NAME, + UNITY_SPLIT_INCLUDE, + UNITY_LOCAL_LAN, APPLICATION_VERSION, }; @@ -1496,6 +1749,9 @@ isakmp_cfg_getconfig(iph1) attr++; } + plog(LLV_DEBUG, LOCATION, NULL, + "Sending MODE_CFG REQUEST\n"); + error = isakmp_cfg_send(iph1, buffer, ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1); @@ -1523,22 +1779,113 @@ isakmp_cfg_getaddr4(attr, ip) 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; { -#define IP_MAX 40 char addrstr[IP_MAX]; + char addrlist[IP_MAX * MAXNS + MAXNS]; + char *splitlist = addrlist; + 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_RADIUS) || + (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, @@ -1551,6 +1898,15 @@ isakmp_cfg_setenv(iph1, envp, envc) 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, @@ -1558,34 +1914,247 @@ isakmp_cfg_setenv(iph1, envp, envc) 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) - inet_ntop(AF_INET, &iph1->mode_cfg->dns4, + 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); - else + + /* 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) { + 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) - inet_ntop(AF_INET, &iph1->mode_cfg->wins4, + 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); - else + + /* 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"); + 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); + else { + splitlist = 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 (splitlist != addrlist) + racoon_free(splitlist); + + if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) + splitlist = splitnet_list_2str(iph1->mode_cfg->split_local); + else { + splitlist = 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 (splitlist != addrlist) + racoon_free(splitlist); + 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; 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 (cold == ISAKMP_CFG_INIT_COLD) { + if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0) + return error; + } + + return 0; +} + diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp_cfg.h b/crypto/dist/ipsec-tools/src/racoon/isakmp_cfg.h index 9d143858fb6bb..c8f64da1c3d7c 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_cfg.h +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_cfg.h @@ -1,4 +1,4 @@ -/* $NetBSD: isakmp_cfg.h,v 1.1.1.4 2005/08/07 08:47:06 manu Exp $ */ +/* $NetBSD: isakmp_cfg.h,v 1.1.1.5 2006/09/09 16:12:00 manu Exp $ */ /* $KAME$ */ @@ -59,12 +59,14 @@ #define INTERNAL_IP6_SUBNET 15 /* For APPLICATION_VERSION */ -#define ISAKMP_CFG_RACOON_VERSION "KAME/racoon " \ - "+ Hybrid auth Patches " +#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 - * Readen from the mode_cfg section of racoon.conf + * Read from the mode_cfg section of racoon.conf */ struct isakmp_cfg_port { char used; @@ -74,34 +76,57 @@ struct isakmp_cfg_port { }; struct isakmp_cfg_config { - in_addr_t network4; - in_addr_t netmask4; - in_addr_t dns4; - in_addr_t nbns4; - struct isakmp_cfg_port *port_pool; - int authsource; - int confsource; - int accounting; - size_t pool_size; - int auth_throttle; - char motd[MAXPATHLEN + 1]; - int pfs_group; - int save_passwd; + 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 @@ -109,6 +134,9 @@ struct isakmp_cfg_config { /* For motd */ #define ISAKMP_CFG_MOTD "/etc/motd" +/* For default domain */ +#define ISAKMP_CFG_DEFAULT_DOMAIN "" + extern struct isakmp_cfg_config isakmp_cfg_config; /* @@ -121,18 +149,28 @@ struct isakmp_cfg_state { char login[LOGINLEN + 1]; /* login */ struct in_addr addr4; /* IPv4 address */ struct in_addr mask4; /* IPv4 netmask */ - struct in_addr dns4; /* IPv4 DNS (when client only) */ - struct in_addr wins4; /* IPv4 WINS (when client only) */ + 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_RADIUS 0x08 /* Address from RADIUS */ -#define ISAKMP_CFG_MASK4_RADIUS 0x10 /* Netmask from RADIUS */ +#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 */ @@ -140,6 +178,9 @@ struct isakmp_cfg_state { #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; @@ -155,12 +196,17 @@ 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_getport(struct ph1handle *); +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; @@ -172,3 +218,5 @@ int isakmp_cfg_radius_common(struct rad_handle *, int); 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/crypto/dist/ipsec-tools/src/racoon/isakmp_frag.h b/crypto/dist/ipsec-tools/src/racoon/isakmp_frag.h index 1716788b9c121..1479508e12269 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_frag.h +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_frag.h @@ -1,6 +1,6 @@ -/* $NetBSD: isakmp_frag.h,v 1.1.1.2 2005/02/23 14:54:19 manu Exp $ */ +/* $NetBSD: isakmp_frag.h,v 1.1.1.3 2006/09/09 16:12:00 manu Exp $ */ -/* Id: isakmp_frag.h,v 1.2 2004/10/24 16:51:24 manubsd Exp */ +/* Id: isakmp_frag.h,v 1.3 2005/04/09 16:25:24 manubsd Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -32,6 +32,7 @@ */ /* IKE fragmentation capabilities */ +#define VENDORID_FRAG_IDENT 0x80000000 #define VENDORID_FRAG_BASE 0x40000000 #define VENDORID_FRAG_AGG 0x80000000 diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp_ident.c b/crypto/dist/ipsec-tools/src/racoon/isakmp_ident.c index ec622774dbe49..3dd676ffb1db5 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_ident.c +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_ident.c @@ -1,6 +1,6 @@ -/* $NetBSD: isakmp_ident.c,v 1.1.1.4 2005/11/21 14:12:11 manu Exp $ */ +/* $NetBSD: isakmp_ident.c,v 1.1.1.5 2006/09/09 16:12:01 manu Exp $ */ -/* Id: isakmp_ident.c,v 1.13.2.2 2005/11/21 09:46:23 vanhu 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. @@ -81,6 +81,14 @@ #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 *)); @@ -106,6 +114,13 @@ ident_i1send(iph1, msg) 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 @@ -138,12 +153,53 @@ ident_i1send(iph1, msg) if (iph1->rmconf->nat_traversal) plist = isakmp_plist_append_natt_vids(plist, vid_natt); #endif +#ifdef ENABLE_HYBRID + /* Do we need Xauth VID? */ + switch (RMAUTHMETHOD(iph1)) { + case FICTIVE_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); + ISAKMP_NPTYPE_VID); } #endif @@ -163,10 +219,20 @@ ident_i1send(iph1, msg) 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); @@ -238,6 +304,22 @@ ident_i2recv(iph1, msg) if (iph1->rmconf->nat_traversal && 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->dpd) iph1->dpd_support=1; @@ -319,7 +401,7 @@ ident_i2send(iph1, msg) goto end; #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && gssapi_get_itoken(iph1, NULL) < 0) goto end; #endif @@ -485,6 +567,10 @@ ident_i3recv(iph1, msg) error = 0; end: +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif if (pbuf) vfree(pbuf); if (error) { @@ -544,7 +630,7 @@ ident_i3send(iph1, msg0) goto end; #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && + if (AUTHMETHOD(iph1) == 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) @@ -840,6 +926,27 @@ ident_r1recv(iph1, msg) if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric)) natt_handle_vendorid(iph1, vid_numeric); #endif +#ifdef ENABLE_FRAG + if ((vid_numeric == VENDORID_FRAG) && + (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_IDENT)) + iph1->frag = 1; +#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->dpd) iph1->dpd_support=1; @@ -905,13 +1012,23 @@ ident_r1send(iph1, msg) struct payload_list *plist = NULL; int error = -1; vchar_t *gss_sa = NULL; +#ifdef HAVE_GSSAPI + int free_gss_sa = 0; +#endif vchar_t *vid = NULL; #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) { @@ -924,9 +1041,11 @@ ident_r1send(iph1, msg) isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local); #ifdef HAVE_GSSAPI - if (iph1->approval->gssid != NULL) + if (iph1->approval->gssid != NULL) { gss_sa = ipsecdoi_setph1proposal(iph1->approval); - else + if (gss_sa != iph1->sa_ret) + free_gss_sa = 1; + } else #endif gss_sa = iph1->sa_ret; @@ -937,6 +1056,28 @@ ident_r1send(iph1, msg) if (vid) plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); +#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)) @@ -953,6 +1094,20 @@ ident_r1send(iph1, msg) 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); @@ -962,8 +1117,9 @@ ident_r1send(iph1, msg) /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { goto end; + } /* the sending message is added to the received-list. */ if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { @@ -978,7 +1134,7 @@ ident_r1send(iph1, msg) end: #ifdef HAVE_GSSAPI - if (gss_sa != iph1->sa_ret) + if (free_gss_sa) vfree(gss_sa); #endif if (vid) @@ -988,10 +1144,20 @@ ident_r1send(iph1, msg) 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; } @@ -1064,7 +1230,7 @@ ident_r2recv(iph1, msg) 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) + pa->type == iph1->natt_options->payload_nat_d) { vchar_t *natd_received = NULL; int natd_verified; @@ -1168,7 +1334,7 @@ ident_r2send(iph1, msg) goto end; #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) gssapi_get_rtoken(iph1, NULL); #endif @@ -1315,18 +1481,31 @@ ident_r3recv(iph1, msg0) { int ng = 0; - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { 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; @@ -1455,7 +1634,7 @@ ident_r3send(iph1, msg) goto end; #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && gssapi_more_tokens(iph1)) { gssapi_get_rtoken(iph1, &len); if (len != 0) @@ -1549,7 +1728,7 @@ ident_ir2mx(iph1) } #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) gssapi_get_token_to_send(iph1, &gsstoken); #endif @@ -1560,7 +1739,7 @@ ident_ir2mx(iph1) plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE); #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); #endif @@ -1653,8 +1832,14 @@ ident_ir3mx(iph1) vchar_t *gsshash = NULL; #endif - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case FICTIVE_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); @@ -1663,6 +1848,14 @@ ident_ir3mx(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_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; @@ -1724,6 +1917,12 @@ ident_ir3mx(iph1) #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); @@ -1753,6 +1952,10 @@ ident_ir3mx(iph1) error = 0; end: +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif if (cr) vfree(cr); if (error && buf != NULL) { diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c b/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c index 93080b5b19e02..d12e7fd0efbc9 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c @@ -1,6 +1,6 @@ -/* $NetBSD: isakmp_inf.c,v 1.1.1.5 2005/08/20 00:41:48 manu Exp $ */ +/* $NetBSD: isakmp_inf.c,v 1.1.1.6 2006/09/09 16:12:03 manu Exp $ */ -/* Id: isakmp_inf.c,v 1.14.4.9 2005/08/02 15:09:26 vanhu 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. @@ -60,6 +60,9 @@ # include # endif #endif +#ifdef ENABLE_HYBRID +#include +#endif #include "libpfkey.h" @@ -74,16 +77,18 @@ #include "localconf.h" #include "remoteconf.h" #include "sockmisc.h" +#include "handler.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 "handler.h" #include "ipsec_doi.h" #include "crypto_openssl.h" #include "pfkey.h" @@ -97,8 +102,8 @@ #endif /* information exchange */ -static int isakmp_info_recv_n __P((struct ph1handle *, vchar_t *)); -static int isakmp_info_recv_d __P((struct ph1handle *, vchar_t *)); +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 *, @@ -109,7 +114,6 @@ static void isakmp_info_send_r_u __P((void *)); #endif static void purge_isakmp_spi __P((int, isakmp_index *, size_t)); -static void purge_ipsec_spi __P((struct sockaddr *, int, u_int32_t *, size_t)); static void info_recv_initialcontact __P((struct ph1handle *)); /* %%% @@ -124,24 +128,33 @@ isakmp_info_recv(iph1, msg0) 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; + int flag; 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) @@ -170,18 +183,18 @@ isakmp_info_recv(iph1, msg0) if (encrypted) { if (isakmp->np != ISAKMP_NPTYPE_HASH) { plog(LLV_ERROR, LOCATION, NULL, - "ignore information because the " + "ignore information because the" "message has no hash payload.\n"); goto end; } if (iph1->status != PHASE1ST_ESTABLISHED) { plog(LLV_ERROR, LOCATION, NULL, - "ignore information because ISAKMP-SA " + "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, @@ -249,7 +262,7 @@ isakmp_info_recv(iph1, msg0) vfree(hash); vfree(payload); } else { - /* make sure the packet were encrypted after the beginning of phase 1. */ + /* make sure the packet was encrypted after the beginning of phase 1. */ switch (iph1->etype) { case ISAKMP_ETYPE_AGG: case ISAKMP_ETYPE_BASE: @@ -263,38 +276,290 @@ isakmp_info_recv(iph1, msg0) plog(LLV_ERROR, LOCATION, iph1->remote, "%s message must be encrypted\n", s_isakmp_nptype(np)); + error = 0; goto end; } } - switch (np) { - case ISAKMP_NPTYPE_N: - if (isakmp_info_recv_n(iph1, msg) < 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; + } else { + flag |= error; + } + } + end: + if (msg != NULL) + vfree(msg); + if (pbuf != NULL) + vfree(pbuf); + return error; +} + +/* + * 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; + vchar_t *pbuf; + vchar_t *ndata; + char *nraw; + size_t l; + char *spi; + + 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_NPTYPE_D: - if (isakmp_info_recv_d(iph1, msg) < 0) - goto end; + case ISAKMP_NTYPE_INITIAL_CONTACT: + if (encrypted) + info_recv_initialcontact(iph1); + return 0; + 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; - case ISAKMP_NPTYPE_NONCE: - /* XXX to be 6.4.2 ike-01.txt */ - /* XXX IV is to be synchronized. */ +#endif + default: + { + /* XXX there is a potential of dos attack. */ + if(type >= ISAKMP_NTYPE_MINERROR && + type <= ISAKMP_NTYPE_MAXERROR) { + if (msgid == 0) { + /* don't think this realy deletes ph1 ? */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "delete phase1 handle.\n"); + return -1; + } else { + if (getph2bymsgid(iph1, msgid) == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "fatal %s notify messsage, " + "phase1 should be deleted.\n", + s_isakmp_notify_msg(type)); + } else { + plog(LLV_ERROR, LOCATION, iph1->remote, + "fatal %s notify messsage, " + "phase2 should be deleted.\n", + s_isakmp_notify_msg(type)); + } + } + } else { + plog(LLV_ERROR, LOCATION, iph1->remote, + "unhandled notify message %s, " + "no phase2 handle found.\n", + s_isakmp_notify_msg(type)); + } + } + break; + } + + /* get spi if specified and allocate */ + if(notify->spi_size > 0) { + if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "invalid spi_size in notification payload.\n"); + return -1; + } + spi = val2str((char *)(notify + 1), notify->spi_size); + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "notification message %d:%s, " + "doi=%d proto_id=%d spi=%s(size=%d).\n", + type, s_isakmp_notify_msg(type), + ntohl(notify->doi), notify->proto_id, spi, notify->spi_size); + + racoon_free(spi); + } + + /* Send the message data to the logs */ + if(type >= ISAKMP_NTYPE_MINERROR && + type <= ISAKMP_NTYPE_MAXERROR) { + l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size; + if (l > 0) { + nraw = (char*)notify; + nraw += sizeof(*notify) + notify->spi_size; + ndata = vmalloc(l); + memcpy(ndata->v, nraw, ndata->l); + plog(LLV_ERROR, LOCATION, iph1->remote, + "Message: '%s'.\n", + binsanitize(ndata->v, ndata->l)); + vfree(ndata); + } + } + 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 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, - "ignore Acknowledged Informational\n"); + "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->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; + } + EVT_PUSH(iph1->local, iph1->remote, + EVTT_PEERPH1_NOPROP, NULL); + if (iph1->scr) + SCHED_KILL(iph1->scr); + + purge_remote(iph1); 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; + } + EVT_PUSH(iph1->local, iph1->remote, + EVTT_PEER_DELETE, NULL); + 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: - /* don't send information, see isakmp_ident_r1() */ - error = 0; plog(LLV_ERROR, LOCATION, iph1->remote, - "reject the packet, " - "received unexpecting payload type %d.\n", - gen->np); - goto end; + "deletion message received, " + "invalid proto_id: %d\n", + delete->proto_id); + return 0; } - end: - if (msg != NULL) - vfree(msg); + plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n"); return 0; } @@ -451,8 +716,10 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) iph1->flags = 0; iph1->msgid = 0; /* XXX */ #ifdef ENABLE_HYBRID - if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) - return -1; + if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { + error = -1; + goto end; + } #endif #ifdef ENABLE_FRAG iph1->frag = 0; @@ -460,8 +727,10 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) #endif /* copy remote address */ - if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) - return -1; + if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) { + error = -1; + goto end; + } tlen = sizeof(*n) + spisiz; if (data) @@ -470,6 +739,7 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) if (payload == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to get buffer to send.\n"); + error = -1; goto end; } @@ -481,7 +751,7 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) n->spi_size = spisiz; n->type = htons(type); if (spisiz) - memset(n + 1, 0, spisiz); /*XXX*/ + memset(n + 1, 0, spisiz); /* XXX spisiz is always 0 */ if (data) memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); @@ -628,18 +898,28 @@ isakmp_info_send_common(iph1, payload, np, flags) 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; + } switch (iph1->remote->sa_family) { case AF_INET: -#ifndef ENABLE_NATT +#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in *)iph2->dst)->sin_port = 0; ((struct sockaddr_in *)iph2->src)->sin_port = 0; #endif break; #ifdef INET6 case AF_INET6: +#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0; ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0; +#endif break; #endif default: @@ -823,113 +1103,7 @@ isakmp_add_pl_n(buf0, np_p, type, pr, data) return buf; } -/* - * handling to receive Notification payload - */ -static int -isakmp_info_recv_n(iph1, msg) - struct ph1handle *iph1; - vchar_t *msg; -{ - struct isakmp_pl_n *n = NULL; - u_int type; - vchar_t *pbuf; - struct isakmp_parse_t *pa, *pap; - char *spi; - - if (!(pbuf = isakmp_parse(msg))) - return -1; - pa = (struct isakmp_parse_t *)pbuf->v; - for (pap = pa; pap->type; pap++) { - switch (pap->type) { - case ISAKMP_NPTYPE_HASH: - /* do something here */ - break; - case ISAKMP_NPTYPE_NONCE: - /* send to ack */ - break; - case ISAKMP_NPTYPE_N: - n = (struct isakmp_pl_n *)pap->ptr; - break; - default: - vfree(pbuf); - return -1; - } - } - vfree(pbuf); - if (!n) - return -1; - - type = ntohs(n->type); - - switch (type) { - case ISAKMP_NTYPE_CONNECTED: - case ISAKMP_NTYPE_RESPONDER_LIFETIME: - case ISAKMP_NTYPE_REPLAY_STATUS: - /* do something */ - break; - case ISAKMP_NTYPE_INITIAL_CONTACT: - info_recv_initialcontact(iph1); - break; -#ifdef ENABLE_DPD - case ISAKMP_NTYPE_R_U_THERE: - isakmp_info_recv_r_u(iph1, (struct isakmp_pl_ru *)n, - ((struct isakmp *)msg->v)->msgid); - break; - case ISAKMP_NTYPE_R_U_THERE_ACK: - isakmp_info_recv_r_u_ack(iph1, (struct isakmp_pl_ru *)n, - ((struct isakmp *)msg->v)->msgid); - break; -#endif - - default: - { - u_int32_t msgid = ((struct isakmp *)msg->v)->msgid; - struct ph2handle *iph2; - - /* XXX there is a potential of dos attack. */ - if (msgid == 0) { - /* delete ph1 */ - plog(LLV_ERROR, LOCATION, iph1->remote, - "delete phase1 handle.\n"); - return -1; - } else { - iph2 = getph2bymsgid(iph1, msgid); - if (iph2 == NULL) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "unknown notify message, " - "no phase2 handle found.\n"); - } else { - /* delete ph2 */ - unbindph12(iph2); - remph2(iph2); - delph2(iph2); - } - } - } - break; - } - - /* get spi and allocate */ - if (ntohs(n->h.len) < sizeof(*n) + n->spi_size) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "invalid spi_size in notification payload.\n"); - return -1; - } - spi = val2str((char *)(n + 1), n->spi_size); - - plog(LLV_DEBUG, LOCATION, iph1->remote, - "notification message %d:%s, " - "doi=%d proto_id=%d spi=%s(size=%d).\n", - type, s_isakmp_notify_msg(type), - ntohl(n->doi), n->proto_id, spi, n->spi_size); - - racoon_free(spi); - - return(0); -} - -void +static void purge_isakmp_spi(proto, spi, n) int proto; isakmp_index *spi; /*network byteorder*/ @@ -955,7 +1129,9 @@ purge_isakmp_spi(proto, spi, n) } } -static void + + +void purge_ipsec_spi(dst0, proto, spi, n) struct sockaddr *dst0; int proto; @@ -1039,7 +1215,7 @@ purge_ipsec_spi(dst0, proto, spi, n) * exists. */ iph2 = getph2bysaidx(src, dst, proto, spi[i]); - if (iph2) { + if(iph2 != NULL){ delete_spd(iph2); unbindph12(iph2); remph2(iph2); @@ -1085,8 +1261,10 @@ info_recv_initialcontact(iph1) return; #if 0 - loc = strdup(saddrwop2str(iph1->local)); - rem = strdup(saddrwop2str(iph1->remote)); + 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 @@ -1261,162 +1439,6 @@ info_recv_initialcontact(iph1) vfree(buf); } -/* - * handling to receive Deletion payload - */ -static int -isakmp_info_recv_d(iph1, msg) - struct ph1handle *iph1; - vchar_t *msg; -{ - struct isakmp_pl_d *d; - int tlen, num_spi; - vchar_t *pbuf; - struct isakmp_parse_t *pa, *pap; - int protected = 0; - union { - u_int32_t spi32; - u_int16_t spi16[2]; - } spi; - - /* validate the type of next payload */ - if (!(pbuf = isakmp_parse(msg))) - return -1; - pa = (struct isakmp_parse_t *)pbuf->v; - for (pap = pa; pap->type; pap++) { - switch (pap->type) { - case ISAKMP_NPTYPE_D: - break; - case ISAKMP_NPTYPE_HASH: - if (pap == pa) { - protected++; - break; - } - plog(LLV_ERROR, LOCATION, iph1->remote, - "received next payload type %d " - "in wrong place (must be the first payload).\n", - pap->type); - vfree(pbuf); - return -1; - default: - /* don't send information, see isakmp_ident_r1() */ - plog(LLV_ERROR, LOCATION, iph1->remote, - "reject the packet, " - "received unexpecting payload type %d.\n", - pap->type); - vfree(pbuf); - return 0; - } - } - - if (!protected) { - plog(LLV_ERROR, LOCATION, NULL, - "delete payload is not proteted, " - "ignored.\n"); - vfree(pbuf); - return -1; - } - - /* process a delete payload */ - for (pap = pa; pap->type; pap++) { - if (pap->type != ISAKMP_NPTYPE_D) - continue; - - d = (struct isakmp_pl_d *)pap->ptr; - - if (ntohl(d->doi) != IPSEC_DOI) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "delete payload with invalid doi:%d.\n", - ntohl(d->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) || (d->doi != 0)) - continue; -#else - continue; -#endif - } - - num_spi = ntohs(d->num_spi); - tlen = ntohs(d->h.len) - sizeof(struct isakmp_pl_d); - - if (tlen != num_spi * d->spi_size) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "deletion payload with invalid length.\n"); - vfree(pbuf); - return -1; - } - - switch (d->proto_id) { - case IPSECDOI_PROTO_ISAKMP: - if (d->spi_size != sizeof(isakmp_index)) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "delete payload with strange spi " - "size %d(proto_id:%d)\n", - d->spi_size, d->proto_id); - continue; - } - - if (iph1->scr) - SCHED_KILL(iph1->scr); - - purge_remote(iph1); - break; - - case IPSECDOI_PROTO_IPSEC_AH: - case IPSECDOI_PROTO_IPSEC_ESP: - if (d->spi_size != sizeof(u_int32_t)) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "delete payload with strange spi " - "size %d(proto_id:%d)\n", - d->spi_size, d->proto_id); - continue; - } - EVT_PUSH(iph1->local, iph1->remote, - EVTT_PEER_DELETE, NULL); - purge_ipsec_spi(iph1->remote, d->proto_id, - (u_int32_t *)(d + 1), num_spi); - break; - - case IPSECDOI_PROTO_IPCOMP: - /* need to handle both 16bit/32bit SPI */ - memset(&spi, 0, sizeof(spi)); - if (d->spi_size == sizeof(spi.spi16[1])) { - memcpy(&spi.spi16[1], d + 1, - sizeof(spi.spi16[1])); - } else if (d->spi_size == sizeof(spi.spi32)) - memcpy(&spi.spi32, d + 1, sizeof(spi.spi32)); - else { - plog(LLV_ERROR, LOCATION, iph1->remote, - "delete payload with strange spi " - "size %d(proto_id:%d)\n", - d->spi_size, d->proto_id); - continue; - } - purge_ipsec_spi(iph1->remote, d->proto_id, - &spi.spi32, num_spi); - break; - - default: - plog(LLV_ERROR, LOCATION, iph1->remote, - "deletion message received, " - "invalid proto_id: %d\n", - d->proto_id); - continue; - } - - plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n"); - } - - vfree(pbuf); - - return 0; -} - void isakmp_check_notify(gen, iph1) struct isakmp_gen *gen; /* points to Notify payload */ @@ -1429,31 +1451,26 @@ isakmp_check_notify(gen, iph1) switch (ntohs(notify->type)) { case ISAKMP_NTYPE_CONNECTED: - plog(LLV_WARNING, LOCATION, iph1->remote, - "ignore CONNECTED notification.\n"); - break; case ISAKMP_NTYPE_RESPONDER_LIFETIME: - plog(LLV_WARNING, LOCATION, iph1->remote, - "ignore RESPONDER-LIFETIME notification.\n"); - break; case ISAKMP_NTYPE_REPLAY_STATUS: + case ISAKMP_NTYPE_HEARTBEAT: +#ifdef ENABLE_HYBRID + case ISAKMP_NTYPE_UNITY_HEARTBEAT: +#endif plog(LLV_WARNING, LOCATION, iph1->remote, - "ignore REPLAY-STATUS notification.\n"); + "ignore %s notification.\n", + s_isakmp_notify_msg(ntohs(notify->type))); break; case ISAKMP_NTYPE_INITIAL_CONTACT: plog(LLV_WARNING, LOCATION, iph1->remote, "ignore INITIAL-CONTACT notification, " "because it is only accepted after phase1.\n"); break; - case ISAKMP_NTYPE_HEARTBEAT: - plog(LLV_WARNING, LOCATION, iph1->remote, - "ignore HEARTBEAT notification\n"); - break; default: isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); plog(LLV_ERROR, LOCATION, iph1->remote, - "received unknown notification type %u.\n", - ntohs(notify->type)); + "received unknown notification type %s.\n", + s_isakmp_notify_msg(ntohs(notify->type))); } return; @@ -1550,6 +1567,8 @@ isakmp_info_recv_r_u_ack (iph1, ru, msgid) } + + /* * send Delete payload (for ISAKMP SA) in Informational exchange. */ diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.h b/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.h index b78aa49d01944..3a4b4600e6282 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.h +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.h @@ -1,6 +1,6 @@ -/* $NetBSD: isakmp_inf.h,v 1.1.1.2 2005/02/23 14:54:21 manu Exp $ */ +/* $NetBSD: isakmp_inf.h,v 1.1.1.3 2006/09/09 16:12:03 manu Exp $ */ -/* Id: isakmp_inf.h,v 1.4 2004/11/16 15:44:46 ludvigm 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. @@ -54,4 +54,7 @@ extern void isakmp_check_notify __P((struct isakmp_gen *, struct ph1handle *)); 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/crypto/dist/ipsec-tools/src/racoon/isakmp_quick.c b/crypto/dist/ipsec-tools/src/racoon/isakmp_quick.c index d2d8f7061c176..4fa770fbaf892 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_quick.c +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_quick.c @@ -1,6 +1,6 @@ -/* $NetBSD: isakmp_quick.c,v 1.1.1.4 2005/08/07 08:47:23 manu Exp $ */ +/* $NetBSD: isakmp_quick.c,v 1.1.1.5 2006/09/09 16:12:04 manu Exp $ */ -/* Id: isakmp_quick.c,v 1.13.2.7 2005/07/20 08:02:05 vanhu 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. @@ -53,6 +53,9 @@ # include # endif #endif +#ifdef ENABLE_HYBRID +#include +#endif #ifndef HAVE_NETINET6_IPSEC #include @@ -69,12 +72,13 @@ #include "localconf.h" #include "remoteconf.h" +#include "handler.h" +#include "proposal.h" #include "isakmp_var.h" #include "isakmp.h" #include "isakmp_inf.h" #include "isakmp_quick.h" #include "oakley.h" -#include "handler.h" #include "ipsec_doi.h" #include "crypto_openssl.h" #include "pfkey.h" @@ -205,9 +209,9 @@ quick_i1send(iph2, msg) "failed to get ID.\n"); goto end; } - plog(LLV_DEBUG, LOCATION, NULL, "IDci:"); + plog(LLV_DEBUG, LOCATION, NULL, "IDci:\n"); plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l); - plog(LLV_DEBUG, LOCATION, NULL, "IDcr:"); + plog(LLV_DEBUG, LOCATION, NULL, "IDcr:\n"); plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l); /* @@ -727,6 +731,11 @@ quick_i3recv(iph2, msg0) 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; + } isakmp_check_notify(pa->ptr, iph2->ph1); notify = vmalloc(pa->len); if (notify == NULL) { @@ -1062,6 +1071,7 @@ quick_r1recv(iph2, msg0) goto end; } + /* check the existence of ID payload and create responder's proposal */ error = get_proposal_r(iph2); switch (error) { @@ -1592,6 +1602,18 @@ quick_r3send(iph2, msg0) 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. */ @@ -1600,7 +1622,6 @@ quick_r3prep(iph2, msg0) struct ph2handle *iph2; vchar_t *msg0; { - vchar_t *msg = NULL; int error = ISAKMP_INTERNAL_ERROR; /* validity check */ @@ -1705,9 +1726,6 @@ quick_r3prep(iph2, msg0) error = 0; end: - if (msg != NULL) - vfree(msg); - return error; } @@ -1758,6 +1776,7 @@ quick_ir1mx(iph2, body, hash) /* encoding */ new = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); + if (new == NULL) goto end; @@ -1788,7 +1807,7 @@ get_sainfo_r(iph2) int prefixlen; int error = ISAKMP_INTERNAL_ERROR; - if (iph2->id_p == NULL) { + if (iph2->id == NULL) { switch (iph2->src->sa_family) { case AF_INET: prefixlen = sizeof(struct in_addr) << 3; @@ -1812,7 +1831,7 @@ get_sainfo_r(iph2) goto end; } - if (iph2->id == NULL) { + if (iph2->id_p == NULL) { switch (iph2->dst->sa_family) { case AF_INET: prefixlen = sizeof(struct in_addr) << 3; @@ -1843,8 +1862,15 @@ get_sainfo_r(iph2) 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, - "get sa info: %s\n", sainfo2str(iph2->sainfo)); + "selected sainfo: %s\n", sainfo2str(iph2->sainfo)); error = 0; end: @@ -1992,7 +2018,17 @@ get_proposal_r(iph2) if (_XIDT(iph2->id_p) == idi2type && spidx.dst.ss_family == spidx.src.ss_family) { iph2->src_id = dupsaddr((struct sockaddr *)&spidx.dst); + if (iph2->src_id == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "buffer allocation failed.\n"); + return ISAKMP_INTERNAL_ERROR; + } iph2->dst_id = dupsaddr((struct sockaddr *)&spidx.src); + if (iph2->dst_id == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "buffer allocation failed.\n"); + return ISAKMP_INTERNAL_ERROR; + } } } else { @@ -2119,3 +2155,4 @@ get_proposal_r(iph2) return 0; } + diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp_unity.c b/crypto/dist/ipsec-tools/src/racoon/isakmp_unity.c index 8d5664aad4b7a..2329bc671df6b 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_unity.c +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_unity.c @@ -1,6 +1,6 @@ -/* $NetBSD: isakmp_unity.c,v 1.1.1.3 2005/08/07 08:47:23 manu Exp $ */ +/* $NetBSD: isakmp_unity.c,v 1.1.1.4 2006/09/09 16:12:05 manu Exp $ */ -/* Id: isakmp_unity.c,v 1.5.4.1 2005/05/10 09:45:46 manubsd Exp */ +/* Id: isakmp_unity.c,v 1.10 2006/07/31 04:49:23 manubsd Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -61,6 +61,7 @@ #include #endif #include +#include #include "var.h" #include "misc.h" @@ -78,6 +79,9 @@ #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; @@ -100,13 +104,14 @@ isakmp_unity_req(iph1, attr) type &= ~ISAKMP_GEN_MASK; plog(LLV_DEBUG, LOCATION, NULL, - "Short attribute %d = %d\n", - type, ntohs(attr->lorv)); + "Short attribute %s = %d\n", + s_isakmp_cfg_type(type), ntohs(attr->lorv)); switch (type) { default: plog(LLV_DEBUG, LOCATION, NULL, - "Ignored short attribute %d\n", type); + "Ignored short attribute %s\n", + s_isakmp_cfg_type(type)); break; } @@ -156,14 +161,37 @@ isakmp_unity_req(iph1, attr) break; case UNITY_DEF_DOMAIN: - case UNITY_FW_TYPE: - case UNITY_SPLITDNS_NAME: + 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 %d\n", type); + "Ignored attribute %s\n", s_isakmp_cfg_type(type)); return NULL; break; } @@ -171,4 +199,203 @@ isakmp_unity_req(iph1, attr) 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 * newentry; + + /* + * allocate new netentry and copy + * new splitnet network data + */ + newentry = (struct unity_netentry *) + racoon_malloc(sizeof(struct unity_netentry)); + if (newentry == NULL) + return -1; + + memcpy(&newentry->network,network, + sizeof(struct unity_network)); + newentry->next = NULL; + + /* + * locate the last netentry in our + * splitnet list and add our entry + */ + if (*list == NULL) + *list = newentry; + else { + struct unity_netentry * tmpentry = *list; + while (tmpentry->next != NULL) + tmpentry = tmpentry->next; + tmpentry->next = newentry; + } + + (*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) + struct unity_netentry * list; +{ + 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 */ + str = racoon_malloc(len); + 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); + + len += sprintf(str+len, "%s/%s ", tmp1, tmp2); + + netentry = netentry->next; + } + + str[len-1]=0; + + return str; +} diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp_unity.h b/crypto/dist/ipsec-tools/src/racoon/isakmp_unity.h index a839ddf8f701f..8ffa1c373a8af 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_unity.h +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_unity.h @@ -1,4 +1,4 @@ -/* $NetBSD: isakmp_unity.h,v 1.1.1.2 2005/02/23 14:54:21 manu Exp $ */ +/* $NetBSD: isakmp_unity.h,v 1.1.1.3 2006/09/09 16:12:05 manu Exp $ */ /* $KAME$ */ @@ -31,6 +31,10 @@ * SUCH DAMAGE. */ +/* 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 @@ -44,4 +48,25 @@ #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 *); + vchar_t *isakmp_unity_req(struct ph1handle *, struct isakmp_data *); +void isakmp_unity_reply(struct ph1handle *, struct isakmp_data *); diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp_var.h b/crypto/dist/ipsec-tools/src/racoon/isakmp_var.h index 332f48254e40c..bf98b0cae57fc 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_var.h +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_var.h @@ -1,6 +1,6 @@ -/* $NetBSD: isakmp_var.h,v 1.1.1.3 2005/08/07 08:47:27 manu Exp $ */ +/* $NetBSD: isakmp_var.h,v 1.1.1.4 2006/09/09 16:12:05 manu Exp $ */ -/* Id: isakmp_var.h,v 1.9.2.1 2005/05/07 17:26:06 manubsd 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. @@ -122,11 +122,11 @@ 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((int, int, char * const *)); +extern int script_exec __P((char *, int, char * const *)); void purge_remote __P((struct ph1handle *)); void delete_spd __P((struct ph2handle *)); #ifdef INET6 u_int32_t setscopeid __P((struct sockaddr *, struct sockaddr *)); -#endif +#endif #endif /* _ISAKMP_VAR_H */ diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.c b/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.c index 5e312e3b76aa9..9a1c5894d487f 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.c +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.c @@ -1,6 +1,6 @@ -/* $NetBSD: isakmp_xauth.c,v 1.1.1.5 2005/08/07 08:47:28 manu Exp $ */ +/* $NetBSD: isakmp_xauth.c,v 1.1.1.6 2006/09/09 16:12:06 manu Exp $ */ -/* Id: isakmp_xauth.c,v 1.17.2.5 2005/05/20 07:31:09 manubsd Exp */ +/* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */ /* * Copyright (C) 2004-2005 Emmanuel Dreyfus @@ -45,9 +45,7 @@ #include #include #include -#ifdef HAVE_SHADOW_H -#include -#endif +#include #if TIME_WITH_SYS_TIME # include # include @@ -63,6 +61,11 @@ #include #endif #include +#include + +#ifdef HAVE_SHADOW_H +#include +#endif #include "var.h" #include "misc.h" @@ -107,6 +110,11 @@ static int PAM_conv(int, const struct pam_message **, 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) @@ -174,7 +182,7 @@ xauth_sendreq(iph1) return; } -void +int xauth_attr_reply(iph1, attr, id) struct ph1handle *iph1; struct isakmp_data *attr; @@ -189,13 +197,13 @@ xauth_attr_reply(iph1, attr, id) plog(LLV_ERROR, LOCATION, NULL, "Xauth reply but peer did not declare " "itself as Xauth capable\n"); - return; + return -1; } if (xst->status != XAUTHST_REQSENT) { plog(LLV_ERROR, LOCATION, NULL, "Xauth reply while Xauth state is %d\n", xst->status); - return; + return -1; } type = ntohs(attr->type) & ~ISAKMP_GEN_MASK; @@ -209,7 +217,7 @@ xauth_attr_reply(iph1, attr, id) plog(LLV_WARNING, LOCATION, NULL, "Unexpected authentication type %d\n", ntohs(type)); - return; + return -1; } break; @@ -233,7 +241,7 @@ xauth_attr_reply(iph1, attr, id) if ((*outlet = racoon_malloc(alen + 1)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory for Xauth Data\n"); - return; + return -1; } memcpy(*outlet, attr + 1, alen); @@ -278,6 +286,11 @@ xauth_attr_reply(iph1, attr, id) 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, @@ -286,6 +299,14 @@ xauth_attr_reply(iph1, attr, id) 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. @@ -311,8 +332,7 @@ xauth_attr_reply(iph1, attr, id) if ((xra = racoon_malloc(sizeof(*xra))) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "malloc failed, bypass throttling\n"); - xauth_reply(iph1, port, id, res); - return; + return xauth_reply(iph1, port, id, res); } /* @@ -326,11 +346,11 @@ xauth_attr_reply(iph1, attr, id) xra->res = res; sched_new(throttle_delay, xauth_reply_stub, xra); } else { - xauth_reply(iph1, port, id, res); + return xauth_reply(iph1, port, id, res); } } - return; + return 0; } void @@ -341,7 +361,7 @@ xauth_reply_stub(args) struct ph1handle *iph1; if ((iph1 = getph1byindex(&xra->index)) != NULL) - xauth_reply(iph1, xra->port, xra->id, xra->res); + (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"); @@ -350,7 +370,7 @@ xauth_reply_stub(args) return; } -void +int xauth_reply(iph1, port, id, res) struct ph1handle *iph1; int port; @@ -375,7 +395,7 @@ xauth_reply(iph1, port, id, res) remph1(iph1); delph1(iph1); - return; + return -1; } xst->status = XAUTHST_OK; @@ -384,7 +404,7 @@ xauth_reply(iph1, port, id, res) xauth_sendstatus(iph1, XAUTH_STATUS_OK, id); - return; + return 0; } void @@ -511,13 +531,13 @@ xauth_login_radius(iph1, usr, pwd) case RAD_FRAMED_IP_ADDRESS: iph1->mode_cfg->addr4 = rad_cvt_addr(data); iph1->mode_cfg->flags - |= ISAKMP_CFG_ADDR4_RADIUS; + |= 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_RADIUS; + |= ISAKMP_CFG_MASK4_EXTERN; break; default: @@ -572,13 +592,21 @@ PAM_conv(msg_count, msg, rsp, dontcare) case PAM_PROMPT_ECHO_ON: /* Send the username, libpam frees resp */ reply[i].resp_retcode = PAM_SUCCESS; - reply[i].resp = strdup(PAM_usr); + 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; - reply[i].resp = strdup(PAM_pwd); + if ((reply[i].resp = strdup(PAM_pwd)) == NULL) { + plog(LLV_ERROR, LOCATION, + NULL, "strdup failed\n"); + exit(1); + } break; case PAM_TEXT_INFO: @@ -613,7 +641,7 @@ xauth_login_pam(port, raddr, usr, pwd) const void *data; size_t len; int type; - char *remote; + char *remote = NULL; pam_handle_t *pam = NULL; if (isakmp_cfg_config.port_pool == NULL) { @@ -676,15 +704,474 @@ xauth_login_pam(port, raddr, usr, pwd) 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(void) +{ + int tmplen; + 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 defualt host */ + tmplen = strlen(LDAP_DFLT_HOST); + xauth_ldap_config.host = vmalloc(tmplen); + if (xauth_ldap_config.host == NULL ) + return -1; + 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 ) + return -1; + 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 ) + return -1; + 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 ) + return -1; + 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 ) + return -1; + 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 ) + return -1; + memcpy(xauth_ldap_config.attr_member->v, LDAP_DFLT_MEMBER, tmplen); + + return 0; +} + +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; @@ -722,22 +1209,54 @@ xauth_login_system(usr, pwd) 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; - /* If we don't use Xauth, then we pass */ - switch (iph1->approval->authmethod) { - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + /* + * 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 (AUTHMETHOD(iph1)) { + 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_XAUTH_PSKEY_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: + 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 " @@ -762,6 +1281,80 @@ xauth_check(iph1) 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; @@ -772,6 +1365,8 @@ isakmp_xauth_req(iph1, attr) int ashort = 0; int value = 0; vchar_t *buffer = NULL; + char* mraw = NULL; + vchar_t *mdata = NULL; char *data; vchar_t *usr = NULL; vchar_t *pwd = NULL; @@ -807,48 +1402,40 @@ isakmp_xauth_req(iph1, attr) break; case XAUTH_USER_NAME: - if (iph1->rmconf->idvtype != IDTYPE_LOGIN) { - plog(LLV_ERROR, LOCATION, NULL, "Xauth performed " - "while identifier is not a login\n"); - return NULL; - } - - if (iph1->rmconf->idv == NULL) { + 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->idv->l; + dlen = iph1->rmconf->xauth->login->l - 1; + iph1->rmconf->xauth->state |= XAUTH_SENT_USERNAME; break; case XAUTH_USER_PASSWORD: - if (iph1->rmconf->idvtype != IDTYPE_LOGIN) - return NULL; - - if (iph1->rmconf->idv == NULL) + if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) return NULL; skip = sizeof(struct ipsecdoi_id_b); - if ((usr = vmalloc(iph1->rmconf->idv->l + skip)) == NULL) { + 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->idv->v, - iph1->rmconf->idv->l); + iph1->rmconf->xauth->login->v, + iph1->rmconf->xauth->login->l - 1); - if (iph1->rmconf->key) { + if (iph1->rmconf->xauth->pass) { /* A key given through racoonctl */ - pwd = iph1->rmconf->key; + 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->idv->v); + iph1->rmconf->xauth->login->v); vfree(usr); return NULL; } @@ -857,13 +1444,27 @@ isakmp_xauth_req(iph1, attr) } 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 = vmalloc(dlen); + memcpy(mdata->v, mraw, mdata->l); + plog(LLV_NOTIFY,LOCATION, iph1->remote, + "XAUTH Message: '%s'.\n", + binsanitize(mdata->v, mdata->l)); + vfree(mdata); + } + } + return NULL; default: plog(LLV_WARNING, LOCATION, NULL, - "Ignored attribute %d\n", type); + "Ignored attribute %s\n", s_isakmp_cfg_type(type)); return NULL; break; } @@ -887,7 +1488,11 @@ isakmp_xauth_req(iph1, attr) switch(type) { case XAUTH_USER_NAME: - memcpy(data, iph1->rmconf->idv->v, dlen); + /* + * 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); @@ -911,6 +1516,10 @@ isakmp_xauth_set(iph1, attr) int type; vchar_t *buffer = NULL; char *data; + struct xauth_state *xst; + size_t dlen = 0; + char* mraw = NULL; + vchar_t *mdata = NULL; if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) { plog(LLV_ERROR, LOCATION, NULL, @@ -923,6 +1532,28 @@ isakmp_xauth_set(iph1, attr) 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(AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case FICTIVE_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, @@ -933,16 +1564,30 @@ isakmp_xauth_set(iph1, attr) iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1; } else { - EVT_PUSH(iph1->local, - iph1->remote, EVTT_XAUTH_SUCCESS, NULL); + EVT_PUSH(iph1->local, iph1->remote, + EVTT_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 = vmalloc(dlen); + memcpy(mdata->v, mraw, mdata->l); + plog(LLV_NOTIFY,LOCATION, iph1->remote, + "XAUTH Message: '%s'.\n", + binsanitize(mdata->v, mdata->l)); + vfree(mdata); + } + } + default: plog(LLV_WARNING, LOCATION, NULL, - "Ignored attribute %d\n", type); + "Ignored attribute %s\n", s_isakmp_cfg_type(type)); return NULL; break; } @@ -988,6 +1633,46 @@ xauth_rmstate(xst) 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; +} diff --git a/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.h b/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.h index 649c111b21464..281d155eb7093 100644 --- a/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.h +++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.h @@ -1,4 +1,4 @@ -/* $NetBSD: isakmp_xauth.h,v 1.1.1.2 2005/02/23 14:54:21 manu Exp $ */ +/* $NetBSD: isakmp_xauth.h,v 1.1.1.3 2006/09/09 16:12:06 manu Exp $ */ /* $KAME$ */ @@ -31,6 +31,9 @@ * SUCH DAMAGE. */ +#ifndef _ISAKMP_XAUTH_H +#define _ISAKMP_XAUTH_H + /* ISAKMP mode config attribute types specific to the Xauth vendor ID */ #define XAUTH_TYPE 16520 #define XAUTH_USER_NAME 16521 @@ -53,8 +56,9 @@ #define XAUTH_STATUS_FAIL 0 #define XAUTH_STATUS_OK 1 +/* For phase 1 Xauth status */ struct xauth_state { - int status; + int status; /* authentication status, used only on server side */ int vendorid; int authtype; union { @@ -63,6 +67,21 @@ struct xauth_state { 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 */ @@ -78,21 +97,59 @@ struct xauth_reply_arg { }; struct ph1handle; +struct isakmp_data; void xauth_sendreq(struct ph1handle *); -void xauth_attr_reply(struct ph1handle *, struct isakmp_data *, int); +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(void *); -void xauth_reply(struct ph1handle *, int, int, int); +int xauth_reply(struct ph1handle *, int, int, int); +int xauth_rmconf_used(struct xauth_rmconf **); +void xauth_rmconf_delete(struct xauth_rmconf **); #ifdef HAVE_LIBRADIUS int xauth_login_radius(struct ph1handle *, char *, char *); int xauth_radius_init(void); #endif + #ifdef HAVE_LIBPAM int xauth_login_pam(int, struct sockaddr *, 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(void); +int xauth_login_ldap(struct ph1handle *, char *, char *); +#endif + +#endif /* _ISAKMP_XAUTH_H */ diff --git a/crypto/dist/ipsec-tools/src/racoon/kmpstat.c b/crypto/dist/ipsec-tools/src/racoon/kmpstat.c index 46360945422cd..dc4fa24c515b1 100644 --- a/crypto/dist/ipsec-tools/src/racoon/kmpstat.c +++ b/crypto/dist/ipsec-tools/src/racoon/kmpstat.c @@ -1,4 +1,4 @@ -/* $NetBSD: kmpstat.c,v 1.1.1.2 2005/02/23 14:54:21 manu Exp $ */ +/* $NetBSD: kmpstat.c,v 1.1.1.3 2006/09/09 16:11:58 manu Exp $ */ /* $KAME: kmpstat.c,v 1.33 2004/08/16 08:20:28 itojun Exp $ */ @@ -62,6 +62,7 @@ #endif #include #include +#include #include "libpfkey.h" @@ -80,7 +81,6 @@ #include "isakmp_xauth.h" #include "isakmp_var.h" #include "isakmp_cfg.h" -#include "isakmp_unity.h" #include "oakley.h" #include "handler.h" #include "pfkey.h" diff --git a/crypto/dist/ipsec-tools/src/racoon/localconf.c b/crypto/dist/ipsec-tools/src/racoon/localconf.c index 0a0a95b67081c..db20f4baa763b 100644 --- a/crypto/dist/ipsec-tools/src/racoon/localconf.c +++ b/crypto/dist/ipsec-tools/src/racoon/localconf.c @@ -1,4 +1,4 @@ -/* $NetBSD: localconf.c,v 1.1.1.3 2005/02/24 20:53:34 manu Exp $ */ +/* $NetBSD: localconf.c,v 1.1.1.4 2006/09/09 16:12:07 manu Exp $ */ /* $KAME: localconf.c,v 1.33 2001/08/09 07:32:19 sakane Exp $ */ @@ -333,3 +333,39 @@ doitype2doi(doitype) return -1; } + + +static void +saverestore_params(f) + int f; +{ + static u_int16_t s_port_isakmp; +#ifdef ENABLE_ADMINPORT + static u_int16_t s_port_admin; +#endif + + /* 0: save, 1: restore */ + if (f) { + lcconf->port_isakmp = s_port_isakmp; +#ifdef ENABLE_ADMINPORT + lcconf->port_admin = s_port_admin; +#endif + } else { + s_port_isakmp = lcconf->port_isakmp; +#ifdef ENABLE_ADMINPORT + s_port_admin = lcconf->port_admin; +#endif + } +} + +void +restore_params() +{ + saverestore_params(1); +} + +void +save_params() +{ + saverestore_params(0); +} diff --git a/crypto/dist/ipsec-tools/src/racoon/localconf.h b/crypto/dist/ipsec-tools/src/racoon/localconf.h index 75359262a921c..82136a8ebc05f 100644 --- a/crypto/dist/ipsec-tools/src/racoon/localconf.h +++ b/crypto/dist/ipsec-tools/src/racoon/localconf.h @@ -1,6 +1,6 @@ -/* $NetBSD: localconf.h,v 1.1.1.5 2005/11/21 14:12:08 manu Exp $ */ +/* $NetBSD: localconf.h,v 1.1.1.6 2006/09/09 16:12:07 manu Exp $ */ -/* Id: localconf.h,v 1.9.2.3 2005/11/06 17:18:26 monas Exp */ +/* Id: localconf.h,v 1.13 2005/11/06 18:13:18 monas Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -131,4 +131,7 @@ 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/crypto/dist/ipsec-tools/src/racoon/logger.c b/crypto/dist/ipsec-tools/src/racoon/logger.c index 42ed9b23b7ee7..fecd867c5ee39 100644 --- a/crypto/dist/ipsec-tools/src/racoon/logger.c +++ b/crypto/dist/ipsec-tools/src/racoon/logger.c @@ -1,4 +1,4 @@ -/* $NetBSD: logger.c,v 1.1.1.2 2005/02/23 14:54:22 manu Exp $ */ +/* $NetBSD: logger.c,v 1.1.1.3 2006/09/09 16:12:07 manu Exp $ */ /* $KAME: logger.c,v 1.9 2002/09/03 14:37:03 itojun Exp $ */ @@ -89,7 +89,7 @@ log_open(siz, fname) p->siz = siz; if (fname) - p->fname = strdup(fname); + p->fname = racoon_strdup(fname); return p; } @@ -107,7 +107,7 @@ log_add(p, str) /* syslog if p->fname == NULL? */ if (p->buf[p->head]) racoon_free(p->buf[p->head]); - p->buf[p->head] = strdup(str); + p->buf[p->head] = racoon_strdup(str); p->tbuf[p->head] = time(NULL); p->head++; p->head %= p->siz; diff --git a/crypto/dist/ipsec-tools/src/racoon/main.c b/crypto/dist/ipsec-tools/src/racoon/main.c index 4c6cb11bd8d80..9d6c0aef3dd1d 100644 --- a/crypto/dist/ipsec-tools/src/racoon/main.c +++ b/crypto/dist/ipsec-tools/src/racoon/main.c @@ -1,6 +1,6 @@ -/* $NetBSD: main.c,v 1.1.1.3 2005/11/21 14:12:11 manu Exp $ */ +/* $NetBSD: main.c,v 1.1.1.4 2006/09/09 16:11:46 manu Exp $ */ -/* Id: main.c,v 1.14.2.3 2005/11/06 17:18:26 monas Exp */ +/* Id: main.c,v 1.25 2006/06/20 20:31:34 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -66,9 +66,11 @@ #include "cfparse_proto.h" #include "isakmp_var.h" -#ifdef HAVE_LIBRADIUS +#ifdef ENABLE_HYBRID +#include #include "isakmp.h" #include "isakmp_xauth.h" +#include "isakmp_cfg.h" #endif #include "remoteconf.h" #include "localconf.h" @@ -95,9 +97,6 @@ static char version[] = "@(#) racoon / IPsec-tools"; int main __P((int, char **)); static void usage __P((void)); static void parse __P((int, char **)); -static void restore_params __P((void)); -static void save_params __P((void)); -static void saverestore_params __P((int)); #if 0 static void cleanup_pidfile __P((void)); #endif @@ -180,6 +179,8 @@ main(ac, av) 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); if (pfkey_init() < 0) { errx(1, "something error happened " @@ -187,6 +188,16 @@ main(ac, av) /* NOTREACHED*/ } +#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() != 0) + errx(1, "could not initialize libldap"); +#endif + /* * in order to prefer the parameters by command line, * saving some parameters before parsing configuration file. @@ -197,6 +208,9 @@ main(ac, av) errx(1, "failed to parse configuration file."); restore_params(); + if (dump_config) + dumprmconf (); + #ifdef HAVE_LIBRADIUS if (xauth_radius_init() != 0) { errx(1, "could not initialize libradius"); @@ -204,9 +218,6 @@ main(ac, av) } #endif - if (dump_config) - dumprmconf (); - /* * install SAs from the specified file. If the file is not specified * by the configuration file, racoon will exit. @@ -375,38 +386,3 @@ parse(ac, av) return; } - -static void -restore_params() -{ - saverestore_params(1); -} - -static void -save_params() -{ - saverestore_params(0); -} - -static void -saverestore_params(f) - int f; -{ - static u_int16_t s_port_isakmp; -#ifdef ENABLE_ADMINPORT - static u_int16_t s_port_admin; -#endif - - /* 0: save, 1: restore */ - if (f) { - lcconf->port_isakmp = s_port_isakmp; -#ifdef ENABLE_ADMINPORT - lcconf->port_admin = s_port_admin; -#endif - } else { - s_port_isakmp = lcconf->port_isakmp; -#ifdef ENABLE_ADMINPORT - s_port_admin = lcconf->port_admin; -#endif - } -} diff --git a/crypto/dist/ipsec-tools/src/racoon/misc.h b/crypto/dist/ipsec-tools/src/racoon/misc.h index 3043b53281582..4c095c6b002a1 100644 --- a/crypto/dist/ipsec-tools/src/racoon/misc.h +++ b/crypto/dist/ipsec-tools/src/racoon/misc.h @@ -1,6 +1,6 @@ -/* $NetBSD: misc.h,v 1.1.1.3 2005/11/21 14:12:07 manu Exp $ */ +/* $NetBSD: misc.h,v 1.1.1.4 2006/09/09 16:12:07 manu Exp $ */ -/* Id: misc.h,v 1.6.10.1 2005/11/06 17:18:26 monas Exp */ +/* Id: misc.h,v 1.9 2006/04/06 14:00:06 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -49,6 +49,15 @@ 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 *)); + +#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') @@ -58,6 +67,11 @@ extern double timedelta __P((struct timeval *, struct timeval *)); #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/crypto/dist/ipsec-tools/src/racoon/nattraversal.c b/crypto/dist/ipsec-tools/src/racoon/nattraversal.c index c34dfb27068f2..b7bf55a3da382 100644 --- a/crypto/dist/ipsec-tools/src/racoon/nattraversal.c +++ b/crypto/dist/ipsec-tools/src/racoon/nattraversal.c @@ -1,4 +1,4 @@ -/* $NetBSD: nattraversal.c,v 1.1.1.3 2005/08/07 08:47:34 manu Exp $ */ +/* $NetBSD: nattraversal.c,v 1.1.1.4 2006/09/09 16:11:57 manu Exp $ */ /* * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. @@ -198,6 +198,11 @@ natt_compare_addr_hash (struct ph1handle *iph1, vchar_t *natd_received, 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; @@ -377,8 +382,16 @@ natt_keepalive_add (struct sockaddr *src, struct sockaddr *dst) return -1; } - new_addr->src = dupsaddr(src); - new_addr->dst = dupsaddr(dst); + 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); diff --git a/crypto/dist/ipsec-tools/src/racoon/oakley.c b/crypto/dist/ipsec-tools/src/racoon/oakley.c index fb8290a6c63a1..07c5de07f91c2 100644 --- a/crypto/dist/ipsec-tools/src/racoon/oakley.c +++ b/crypto/dist/ipsec-tools/src/racoon/oakley.c @@ -1,6 +1,6 @@ -/* $NetBSD: oakley.c,v 1.1.1.5 2005/10/14 13:21:49 manu Exp $ */ +/* $NetBSD: oakley.c,v 1.1.1.6 2006/09/09 16:12:12 manu Exp $ */ -/* Id: oakley.c,v 1.17.2.5 2005/10/04 09:54:27 manubsd Exp */ +/* Id: oakley.c,v 1.32 2006/05/26 12:19:46 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -38,8 +38,8 @@ #include /* XXX for subjectaltname */ #include /* XXX for subjectaltname */ -#include #include +#include #include #include @@ -56,6 +56,9 @@ # include # endif #endif +#ifdef ENABLE_HYBRID +#include +#endif #include "var.h" #include "misc.h" @@ -254,7 +257,7 @@ oakley_dh_compute(dh, pub, priv, pub_p, gxy) #ifdef ENABLE_STATS gettimeofday(&end, NULL); - syslog(LOG_NOTICE, "%s(%s%d): %8.6f", __func__, + syslog(LOG_NOTICE, "%s(%s%zu): %8.6f", __func__, s_attr_isakmp_group(dh->type), dh->prime->l << 3, timedelta(&start, &end)); #endif @@ -301,7 +304,7 @@ oakley_dh_generate(dh, pub, priv) #ifdef ENABLE_STATS gettimeofday(&end, NULL); - syslog(LOG_NOTICE, "%s(%s%d): %8.6f", __func__, + syslog(LOG_NOTICE, "%s(%s%zu): %8.6f", __func__, s_attr_isakmp_group(dh->type), dh->prime->l << 3, timedelta(&start, &end)); #endif @@ -590,6 +593,7 @@ oakley_compute_keymat_x(iph2, side, sa_dir) 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); @@ -605,8 +609,14 @@ oakley_compute_keymat_x(iph2, side, sa_dir) 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"); @@ -848,7 +858,7 @@ oakley_ph1hash_common(iph1, sw) + (sw == GENERATE ? iph1->id->l : iph1->id_p->l); #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { + if (AUTHMETHOD(iph1) == 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; @@ -909,7 +919,7 @@ oakley_ph1hash_common(iph1, sw) p += bp->l; #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { + if (AUTHMETHOD(iph1) == 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); @@ -930,7 +940,8 @@ oakley_ph1hash_common(iph1, sw) error = 0; - plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n"); + plog(LLV_DEBUG, LOCATION, NULL, "HASH (%s) computed:\n", + iph1->side == INITIATOR ? "init" : "resp"); plogdump(LLV_DEBUG, res->v, res->l); end: @@ -969,10 +980,18 @@ oakley_ph1hash_base_i(iph1, sw) return NULL; } - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { 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 FICTIVE_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; @@ -982,12 +1001,18 @@ oakley_ph1hash_base_i(iph1, sw) 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_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: 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; @@ -1095,16 +1120,28 @@ oakley_ph1hash_base_r(iph1, sw) "invalid etype for this hash function\n"); return NULL; } - if (iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_DSSSIG + + switch(AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: #ifdef ENABLE_HYBRID - && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I - && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I + 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 FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: #endif - && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_RSASIG) { + break; + default: plog(LLV_ERROR, LOCATION, NULL, "not supported authentication method %d\n", iph1->approval->authmethod); return NULL; + break; } /* make hash for seed */ @@ -1166,7 +1203,7 @@ oakley_ph1hash_base_r(iph1, sw) memcpy(p, bp->v, bp->l); p += bp->l; - plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n"); + plog(LLV_DEBUG, LOCATION, NULL, "HASH_R with:\n"); plogdump(LLV_DEBUG, buf->v, buf->l); /* compute HASH */ @@ -1176,7 +1213,7 @@ oakley_ph1hash_base_r(iph1, sw) error = 0; - plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n"); + plog(LLV_DEBUG, LOCATION, NULL, "HASH_R computed:\n"); plogdump(LLV_DEBUG, res->v, res->l); end: @@ -1211,8 +1248,13 @@ oakley_validate_auth(iph1) #ifdef ENABLE_STATS gettimeofday(&start, NULL); #endif - switch (iph1->approval->authmethod) { + + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif /* validate HASH */ { char *r_hash; @@ -1222,10 +1264,20 @@ oakley_validate_auth(iph1) "few isakmp message received.\n"); return ISAKMP_NTYPE_PAYLOAD_MALFORMED; } - +#ifdef ENABLE_HYBRID + if (AUTHMETHOD(iph1) == FICTIVE_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:"); + plog(LLV_DEBUG, LOCATION, NULL, "HASH received:\n"); plogdump(LLV_DEBUG, r_hash, ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash)); @@ -1262,8 +1314,12 @@ oakley_validate_auth(iph1) 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_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 { int error = 0; @@ -1356,9 +1412,9 @@ oakley_validate_auth(iph1) && iph1->rmconf->getcert_method == ISAKMP_GETCERT_PAYLOAD) { certtype = iph1->rmconf->certtype; #ifdef ENABLE_HYBRID - switch (iph1->approval->authmethod) { - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + switch (AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: certtype = iph1->cert_p->type; break; default: @@ -1422,9 +1478,9 @@ oakley_validate_auth(iph1) certtype = iph1->rmconf->certtype; #ifdef ENABLE_HYBRID - switch (iph1->approval->authmethod) { - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + switch (AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: certtype = iph1->cert_p->type; break; default: @@ -1463,8 +1519,8 @@ oakley_validate_auth(iph1) } 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_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, " @@ -1482,6 +1538,11 @@ oakley_validate_auth(iph1) #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: @@ -1519,6 +1580,12 @@ oakley_validate_auth(iph1) #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"); @@ -2214,6 +2281,12 @@ save_certbuf(gen) { cert_t *new; + if(ntohs(gen->len) <= sizeof(*gen)){ + plog(LLV_ERROR, LOCATION, NULL, + "Len is too small !!.\n"); + return NULL; + } + new = oakley_newcert(); if (!new) { plog(LLV_ERROR, LOCATION, NULL, @@ -2289,10 +2362,15 @@ oakley_getcr(iph1) "failed to get cr buffer\n"); return NULL; } - buf->v[0] = iph1->rmconf->certtype; - - plog(LLV_DEBUG, LOCATION, NULL, "create my CR: %s\n", + if(iph1->rmconf->certtype == ISAKMP_CERT_NONE) { + buf->v[0] = iph1->rmconf->cacerttype; + plog(LLV_DEBUG, LOCATION, NULL, "create my CR: NONE, using %s instead\n", + s_isakmp_certtype(iph1->rmconf->cacerttype)); + } else { + buf->v[0] = iph1->rmconf->certtype; + plog(LLV_DEBUG, LOCATION, NULL, "create my CR: %s\n", s_isakmp_certtype(iph1->rmconf->certtype)); + } if (buf->l > 1) plogdump(LLV_DEBUG, buf->v, buf->l); @@ -2336,6 +2414,10 @@ oakley_needcr(type) #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: @@ -2359,10 +2441,14 @@ oakley_skeyid(iph1) char *p; int len; int error = -1; - + /* SKEYID */ - switch(iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case FICTIVE_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) { @@ -2429,6 +2515,10 @@ oakley_skeyid(iph1) 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: @@ -2460,6 +2550,12 @@ oakley_skeyid(iph1) 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)); @@ -2529,7 +2625,7 @@ oakley_skeyid_dae(iph1) buf = NULL; plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_d computed:\n"); - plogdump(LLV_DEBUG, iph1->skeyid_d->v, iph1->skeyid->l); + 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) */ @@ -2941,6 +3037,7 @@ oakley_delivm(ivm) if (ivm->ive != NULL) vfree(ivm->ive); racoon_free(ivm); + plog(LLV_DEBUG, LOCATION, NULL, "IV freed\n"); return; } @@ -3005,8 +3102,6 @@ oakley_do_decrypt(iph1, msg, ivdp, ivep) vfree(buf); buf = NULL; - if (new == NULL) - goto end; plog(LLV_DEBUG, LOCATION, NULL, "decrypted payload by IV:\n"); plogdump(LLV_DEBUG, ivdp->v, ivdp->l); @@ -3140,8 +3235,6 @@ oakley_do_encrypt(iph1, msg, ivep, ivp) vfree(buf); buf = NULL; - if (new == NULL) - goto end; plog(LLV_DEBUG, LOCATION, NULL, "encrypted payload by IV:\n"); plogdump(LLV_DEBUG, ivep->v, ivep->l); diff --git a/crypto/dist/ipsec-tools/src/racoon/oakley.h b/crypto/dist/ipsec-tools/src/racoon/oakley.h index 0f16ae6283225..3cd7ab27b243e 100644 --- a/crypto/dist/ipsec-tools/src/racoon/oakley.h +++ b/crypto/dist/ipsec-tools/src/racoon/oakley.h @@ -1,6 +1,6 @@ -/* $NetBSD: oakley.h,v 1.1.1.2 2005/02/23 14:54:23 manu Exp $ */ +/* $NetBSD: oakley.h,v 1.1.1.3 2006/09/09 16:12:12 manu Exp $ */ -/* Id: oakley.h,v 1.9 2004/10/24 17:37:00 manubsd Exp */ +/* Id: oakley.h,v 1.13 2005/05/30 20:12:43 fredsen Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -75,7 +75,7 @@ /* 65001 - 65535 Private Use */ - /* Plain Xauth, Not implemented */ + /* 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 @@ -88,6 +88,12 @@ #define OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R 65010 #endif + /* 65500 -> still private + * to avoid clash with GSSAPI_KRB below + */ +#define FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I 65500 + + /* * The following are valid when the Vendor ID is one of * the following: @@ -217,4 +223,20 @@ extern vchar_t *oakley_do_decrypt __P((struct ph1handle *, extern vchar_t *oakley_do_encrypt __P((struct ph1handle *, vchar_t *, vchar_t *, vchar_t *)); +#ifdef ENABLE_HYBRID +#define AUTHMETHOD(iph1) \ + (((iph1)->rmconf->xauth && \ + (iph1)->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I) ? \ + FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I : (iph1)->approval->authmethod) +#define RMAUTHMETHOD(iph1) \ + (((iph1)->rmconf->xauth && \ + (iph1)->rmconf->proposal->authmethod == \ + OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I) ? \ + FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I : \ + (iph1)->rmconf->proposal->authmethod) +#else +#define AUTHMETHOD(iph1) (iph1)->approval->authmethod +#define RMAUTHMETHOD(iph1) (iph1)->rmconf->proposal->authmethod +#endif /* ENABLE_HYBRID */ + #endif /* _OAKLEY_H */ diff --git a/crypto/dist/ipsec-tools/src/racoon/pfkey.c b/crypto/dist/ipsec-tools/src/racoon/pfkey.c index f8e8ac290a84d..d8b97edce75d3 100644 --- a/crypto/dist/ipsec-tools/src/racoon/pfkey.c +++ b/crypto/dist/ipsec-tools/src/racoon/pfkey.c @@ -1,6 +1,6 @@ -/* $NetBSD: pfkey.c,v 1.1.1.4 2005/10/14 13:21:49 manu Exp $ */ +/* $NetBSD: pfkey.c,v 1.1.1.5 2006/09/09 16:12:09 manu Exp $ */ -/* Id: pfkey.c,v 1.31.2.10 2005/10/03 14:52:19 manubsd Exp */ +/* Id: pfkey.c,v 1.52 2006/08/11 16:07:05 vanhu Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -49,7 +49,8 @@ # ifdef __linux__ # include # endif -# if defined(__NetBSD__) || defined(__FreeBSD__) +# if defined(__NetBSD__) || defined(__FreeBSD__) || \ + (defined(__APPLE__) && defined(__MACH__)) # include # endif #endif @@ -69,6 +70,7 @@ #else #include #endif +#include #include "libpfkey.h" @@ -82,17 +84,17 @@ #include "schedule.h" #include "localconf.h" #include "remoteconf.h" +#include "handler.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 "handler.h" #include "policy.h" #include "algorithm.h" #include "sainfo.h" -#include "proposal.h" #include "admin.h" #include "privsep.h" #include "strnames.h" @@ -156,7 +158,7 @@ NULL, /* SADB_X_SPDSETIDX */ pk_recvspdexpire, NULL, /* SADB_X_SPDDELETE2 */ NULL, /* SADB_X_NAT_T_NEW_MAPPING */ -NULL, /* SADB_X_MIGRATE */ +NULL, /* SADB_X_MIGRATE */ #if (SADB_MAX > 24) #error "SADB extra message?" #endif @@ -399,6 +401,9 @@ pfkey_init() "libipsec failed pfkey open (%s)\n", ipsec_strerror()); return -1; } + 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, @@ -876,6 +881,15 @@ pk_sendgetspi(iph2) return -1; } +#ifdef ENABLE_NATT + /* XXX should we do a copy of src/dst for each pr ? + */ + if (! pr->udp_encap) { + /* Remove port information, that SA doesn't use it */ + set_port(src, 0); + set_port(dst, 0); + } +#endif plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n"); if (pfkey_send_getspi( lcconf->sock_pfkey, @@ -1083,6 +1097,10 @@ pk_sendupdate(iph2) natt.frag = iph2->ph1->rmconf->esp_frag; } else { memset (&natt, 0, sizeof (natt)); + + /* Remove port information, that SA doesn't use it */ + set_port(src, 0); + set_port(dst, 0); } if (pfkey_send_update_nat( @@ -1837,6 +1855,9 @@ pk_recvacquire(mhp) return -1; /* XXX should use the algorithm list from register message */ } + + plog(LLV_DEBUG, LOCATION, NULL, + "selected sainfo: %s\n", sainfo2str(iph2[n]->sainfo)); } if (set_proposal_from_policy(iph2[n], sp_out, sp_in) < 0) { @@ -1888,7 +1909,7 @@ pk_recvdelete(mhp) || mhp[SADB_EXT_ADDRESS_SRC] == NULL || mhp[SADB_EXT_ADDRESS_DST] == NULL) { plog(LLV_ERROR, LOCATION, NULL, - "inappropriate sadb acquire message passed.\n"); + "inappropriate sadb delete message passed.\n"); return -1; } msg = (struct sadb_msg *)mhp[0]; @@ -1949,7 +1970,7 @@ pk_recvflush(mhp) /* sanity check */ if (mhp[0] == NULL) { plog(LLV_ERROR, LOCATION, NULL, - "inappropriate sadb acquire message passed.\n"); + "inappropriate sadb flush message passed.\n"); return -1; } @@ -2032,8 +2053,13 @@ getsadbpolicy(policy0, policylen0, type, iph2) */ xisr->sadb_x_ipsecrequest_proto = satype; xisr->sadb_x_ipsecrequest_mode = mode; - xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE; - xisr->sadb_x_ipsecrequest_reqid = 0; + 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); @@ -2653,7 +2679,7 @@ static int addnewsp(mhp) caddr_t *mhp; { - struct secpolicy *new; + struct secpolicy *new = NULL; struct sadb_address *saddr, *daddr; struct sadb_x_policy *xpl; @@ -2663,7 +2689,7 @@ addnewsp(mhp) || mhp[SADB_X_EXT_POLICY] == NULL) { plog(LLV_ERROR, LOCATION, NULL, "inappropriate sadb spd management message passed.\n"); - return -1; + goto bad; } saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; @@ -2682,7 +2708,7 @@ addnewsp(mhp) if (new == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to allocate buffer\n"); - return -1; + goto bad; } new->spidx.dir = xpl->sadb_x_policy_dir; @@ -2708,7 +2734,7 @@ addnewsp(mhp) if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) { plog(LLV_ERROR, LOCATION, NULL, "invalid msg length.\n"); - return -1; + goto bad; } tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl); @@ -2720,7 +2746,7 @@ addnewsp(mhp) if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) { plog(LLV_ERROR, LOCATION, NULL, "invalid msg length.\n"); - return -1; + goto bad; } /* allocate request buffer */ @@ -2728,7 +2754,7 @@ addnewsp(mhp) if (*p_isr == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to get new ipsecreq.\n"); - return -1; + goto bad; } /* set values */ @@ -2743,7 +2769,7 @@ addnewsp(mhp) plog(LLV_ERROR, LOCATION, NULL, "invalid proto type: %u\n", xisr->sadb_x_ipsecrequest_proto); - return -1; + goto bad; } (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto; @@ -2756,7 +2782,7 @@ addnewsp(mhp) plog(LLV_ERROR, LOCATION, NULL, "invalid mode: %u\n", xisr->sadb_x_ipsecrequest_mode); - return -1; + goto bad; } (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode; @@ -2774,7 +2800,7 @@ addnewsp(mhp) plog(LLV_ERROR, LOCATION, NULL, "invalid level: %u\n", xisr->sadb_x_ipsecrequest_level); - return -1; + goto bad; } (*p_isr)->level = xisr->sadb_x_ipsecrequest_level; @@ -2812,7 +2838,7 @@ addnewsp(mhp) default: plog(LLV_ERROR, LOCATION, NULL, "invalid policy type.\n"); - return -1; + goto bad; } #ifdef HAVE_PFKEY_POLICY_PRIORITY @@ -2837,6 +2863,13 @@ addnewsp(mhp) 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 */ diff --git a/crypto/dist/ipsec-tools/src/racoon/plainrsa-gen.8 b/crypto/dist/ipsec-tools/src/racoon/plainrsa-gen.8 index d16bc545b9a42..9149053271d63 100644 --- a/crypto/dist/ipsec-tools/src/racoon/plainrsa-gen.8 +++ b/crypto/dist/ipsec-tools/src/racoon/plainrsa-gen.8 @@ -1,6 +1,6 @@ -.\" $NetBSD: plainrsa-gen.8,v 1.1.1.3 2005/08/07 08:47:45 manu Exp $ +.\" $NetBSD: plainrsa-gen.8,v 1.1.1.4 2006/09/09 16:12:12 manu Exp $ .\" -.\" Id: plainrsa-gen.8,v 1.2.10.1 2005/04/18 11:10:55 manubsd 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 @@ -62,22 +62,20 @@ or .\" .Bl -tag -width Ds .It Fl b Ar bits -bit length of the key. -Default is +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 more time. +bits. +Note that generating longer keys takes longer time. .It Fl e Ar pubexp -value of the RSA public exponent. +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 -write the resulting key to .Ar outfile instead of .Li stdout . diff --git a/crypto/dist/ipsec-tools/src/racoon/plainrsa-gen.c b/crypto/dist/ipsec-tools/src/racoon/plainrsa-gen.c index 3c077c6e75fd1..3a07d0d301b98 100644 --- a/crypto/dist/ipsec-tools/src/racoon/plainrsa-gen.c +++ b/crypto/dist/ipsec-tools/src/racoon/plainrsa-gen.c @@ -1,6 +1,6 @@ -/* $NetBSD: plainrsa-gen.c,v 1.1.1.3 2005/08/07 08:47:45 manu Exp $ */ +/* $NetBSD: plainrsa-gen.c,v 1.1.1.4 2006/09/09 16:12:13 manu Exp $ */ -/* Id: plainrsa-gen.c,v 1.4.8.2 2005/04/21 09:07:20 monas 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 diff --git a/crypto/dist/ipsec-tools/src/racoon/plog.c b/crypto/dist/ipsec-tools/src/racoon/plog.c index 6b146d88e5bba..d0fc35ccc1238 100644 --- a/crypto/dist/ipsec-tools/src/racoon/plog.c +++ b/crypto/dist/ipsec-tools/src/racoon/plog.c @@ -1,6 +1,6 @@ -/* $NetBSD: plog.c,v 1.1.1.2 2005/02/23 14:54:24 manu Exp $ */ +/* $NetBSD: plog.c,v 1.1.1.3 2006/09/09 16:12:13 manu Exp $ */ -/* Id: plog.c,v 1.6 2004/07/12 20:15:08 ludvigm Exp */ +/* Id: plog.c,v 1.11 2006/06/20 09:57:31 vanhu Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -85,10 +85,10 @@ static struct plogtags { int priority; } ptab[] = { { "(not defined)", 0, }, - { "INFO", LOG_INFO, }, - { "NOTIFY", LOG_INFO, }, - { "WARNING", LOG_INFO, }, { "ERROR", LOG_INFO, }, + { "WARNING", LOG_INFO, }, + { "NOTIFY", LOG_INFO, }, + { "INFO", LOG_INFO, }, { "DEBUG", LOG_DEBUG, }, { "DEBUG2", LOG_DEBUG, }, }; @@ -129,6 +129,10 @@ plog_common(pri, fmt, func) snprintf(p, reslen, "%s: %s", func, fmt); else snprintf(p, reslen, "%s", fmt); +#ifdef BROKEN_PRINTF + while ((p = strstr(buf,"%z")) != NULL) + p[1] = 'l'; +#endif return buf; } @@ -231,6 +235,31 @@ plogset(file) { if (logfile != NULL) racoon_free(logfile); - logfile = strdup(file); + 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; + for (p = 0, q = 0; p < n; p++) { + if (isgraph((int)binstr[p])) { + binstr[q++] = binstr[p]; + } else { + if (q && binstr[q - 1] != ' ') + binstr[q++] = ' '; + } + } + binstr[q++] = '\0'; + return binstr; +} + diff --git a/crypto/dist/ipsec-tools/src/racoon/plog.h b/crypto/dist/ipsec-tools/src/racoon/plog.h index 2a92f57a55604..975b9be5ed6ef 100644 --- a/crypto/dist/ipsec-tools/src/racoon/plog.h +++ b/crypto/dist/ipsec-tools/src/racoon/plog.h @@ -1,6 +1,6 @@ -/* $NetBSD: plog.h,v 1.1.1.2 2005/02/23 14:54:24 manu Exp $ */ +/* $NetBSD: plog.h,v 1.1.1.3 2006/09/09 16:12:13 manu Exp $ */ -/* Id: plog.h,v 1.5 2004/06/11 16:00:17 ludvigm Exp */ +/* Id: plog.h,v 1.7 2006/06/20 09:57:31 vanhu Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -49,14 +49,14 @@ * DEBUG1: debugging informatioin. * DEBUG2: too more verbose. e.g. parsing config. */ -#define LLV_INFO 1 -#define LLV_NOTIFY 2 -#define LLV_WARNING 3 -#define LLV_ERROR 4 +#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 4 /* always logging less than this value. */ +#define LLV_BASE LLV_INFO /* by default log less than this value. */ extern char *pname; extern u_int32_t loglevel; @@ -72,4 +72,6 @@ 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/crypto/dist/ipsec-tools/src/racoon/privsep.c b/crypto/dist/ipsec-tools/src/racoon/privsep.c index ed6b777810608..ec263c910da38 100644 --- a/crypto/dist/ipsec-tools/src/racoon/privsep.c +++ b/crypto/dist/ipsec-tools/src/racoon/privsep.c @@ -1,6 +1,6 @@ -/* $NetBSD: privsep.c,v 1.1.1.6 2005/08/20 00:42:20 manu Exp $ */ +/* $NetBSD: privsep.c,v 1.1.1.7 2006/09/09 16:12:14 manu Exp $ */ -/* Id: privsep.c,v 1.6.2.7 2005/08/08 11:25:01 vanhu Exp */ +/* Id: privsep.c,v 1.15 2005/08/08 11:23:44 vanhu Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -56,12 +56,14 @@ #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" static int privsep_sock[2] = { -1, -1 }; @@ -69,14 +71,10 @@ 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); -#ifdef HAVE_LIBPAM static int port_check(int); -#endif static int unsafe_env(char *const *); static int unknown_name(int); -static int unknown_script(int); static int unsafe_path(char *, int); -static char *script_name2path(int); static int privsep_send(sock, buf, len) @@ -173,15 +171,15 @@ privsep_init(void) if (lcconf->uid == 0) return 0; - /* - * When running privsep, certificate and script paths + /* + * When running privsep, certificate and script paths * are mandatory, as they enable us to check path safety * in the privilegied 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"); + "require path cert and path script in the config file\n"); return -1; } @@ -335,7 +333,7 @@ privsep_init(void) * stuff eay_get_pkcs1privkey and eay_get_x509sign * together and sign the hash in the privilegied * instance? - * pro: the key remains inaccessibleato + * pro: the key remains inaccessible to unpriv * con: a compromised unpriv racoon can still sign anything */ case PRIVSEP_EAY_GET_PKCS1PRIVKEY: { @@ -347,11 +345,14 @@ privsep_init(void) bufs[0][combuf->bufs.buflen[0] - 1] = '\0'; if (unsafe_path(bufs[0], LC_PATHTYPE_CERT) != 0) { - plog(LLV_ERROR, LOCATION, NULL, + plog(LLV_ERROR, LOCATION, NULL, "privsep_eay_get_pkcs1privkey: " - "unsafe key \"%s\"\n", bufs[0]); + "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; @@ -373,7 +374,7 @@ privsep_init(void) } case PRIVSEP_SCRIPT_EXEC: { - int script; + char *script; int name; char **envp = NULL; int envc = 0; @@ -386,7 +387,11 @@ privsep_init(void) * * 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++) { @@ -423,13 +428,7 @@ privsep_init(void) * Populate script, name and envp */ count = 0; - - if (combuf->bufs.buflen[count] != sizeof(script)) { - plog(LLV_ERROR, LOCATION, NULL, - "privsep_script_exec: corrupted message\n"); - goto out; - } - memcpy((char *)&script, bufs[count++], sizeof(script)); + script = bufs[count++]; if (combuf->bufs.buflen[count] != sizeof(name)) { plog(LLV_ERROR, LOCATION, NULL, @@ -443,6 +442,10 @@ privsep_init(void) 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 @@ -450,15 +453,12 @@ privsep_init(void) */ if ((unsafe_env(envp) == 0) && (unknown_name(name) == 0) && - (unknown_script(script) == 0) && - (unsafe_path(script_name2path(script), - LC_PATHTYPE_SCRIPT) == 0)) + (unsafe_path(script, LC_PATHTYPE_SCRIPT) == 0)) (void)script_exec(script, name, envp); else - plog(LLV_ERROR, LOCATION, NULL, + plog(LLV_ERROR, LOCATION, NULL, "privsep_script_exec: " - "unsafe script \"%s\"\n", - script_name2path(script)); + "unsafe script \"%s\"\n", script); racoon_free(envp); break; @@ -479,6 +479,10 @@ privsep_init(void) 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; @@ -500,6 +504,44 @@ privsep_init(void) } #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; @@ -509,6 +551,10 @@ privsep_init(void) 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) @@ -522,18 +568,30 @@ privsep_init(void) 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) @@ -546,6 +604,7 @@ privsep_init(void) case PRIVSEP_XAUTH_LOGIN_PAM: { int port; + int pool_size; struct sockaddr *raddr; if (safety_check(combuf, 0) != 0) @@ -556,19 +615,30 @@ privsep_init(void) break; if (safety_check(combuf, 3) != 0) break; + if (safety_check(combuf, 4) != 0) + break; memcpy(&port, bufs[0], sizeof(port)); - raddr = (struct sockaddr *)bufs[1]; + memcpy(&pool_size, bufs[1], sizeof(pool_size)); + raddr = (struct sockaddr *)bufs[2]; - bufs[2][combuf->bufs.buflen[2] - 1] = '\0'; 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[2], bufs[3]) != 0) { + raddr, bufs[3], bufs[4]) != 0) { if (errno == 0) reply->hdr.ac_errno = EINVAL; else @@ -579,15 +649,26 @@ privsep_init(void) 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; @@ -697,7 +778,7 @@ privsep_pfkey_close(ps) int privsep_script_exec(script, name, envp) - int script; + char *script; int name; char *const envp[]; { @@ -747,7 +828,7 @@ privsep_script_exec(script, name, envp) * Compute the length */ count = 0; - msg->bufs.buflen[count] = sizeof(script); /* script */ + msg->bufs.buflen[count] = strlen(script) + 1; /* script */ msg->hdr.ac_len += msg->bufs.buflen[count++]; msg->bufs.buflen[count] = sizeof(name); /* name */ @@ -773,7 +854,7 @@ privsep_script_exec(script, name, envp) data = (char *)(msg + 1); count = 0; - memcpy(data, (char *)&script, msg->bufs.buflen[count]); /* script */ + memcpy(data, (char *)script, msg->bufs.buflen[count]); /* script */ data += msg->bufs.buflen[count++]; memcpy(data, (char *)&name, msg->bufs.buflen[count]); /* name */ @@ -905,9 +986,73 @@ privsep_xauth_login_system(usr, pwd) racoon_free(msg); return 0; } -#endif /* ENABLE_HYBRID */ -#ifdef HAVE_LIBPAM +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]); + + 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; @@ -969,10 +1114,10 @@ unsafe_env(envp) return -1; } -/* - * Check path safety - */ -static int +/* + * Check path safety + */ +static int unsafe_path(script, pathtype) char *script; int pathtype; @@ -981,8 +1126,8 @@ unsafe_path(script, pathtype) char rpath[MAXPATHLEN + 1]; size_t len; - if (script == NULL) - return -1; + if (script == NULL) + return -1; path = lcconf->pathinfo[pathtype]; @@ -1003,45 +1148,6 @@ unsafe_path(script, pathtype) return 0; } -static char * -script_name2path(name) - int name; -{ - vchar_t **sp; - - if (script_paths == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "script_name2path: script_paths was not initialized\n"); - return NULL; - } - - sp = (vchar_t **)(script_paths->v); - - return sp[name]->v; -} - -/* - * Check the script path index is correct - */ -static int -unknown_script(script) - int script; -{ - if (script_paths == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "privsep_script_exec: script_paths was not initialized\n"); - return -1; - } - - if ((script < 0) || (script > (script_paths->l / sizeof(vchar_t *)))) { - plog(LLV_ERROR, LOCATION, NULL, - "privsep_script_exec: unsafe script index\n"); - return -1; - } - - return 0; -} - static int unknown_name(name) int name; @@ -1065,12 +1171,17 @@ privsep_accounting_pam(port, inout) 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); + 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)); @@ -1081,12 +1192,15 @@ privsep_accounting_pam(port, inout) 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; if (privsep_send(privsep_sock[1], msg, len) != 0) return -1; @@ -1124,9 +1238,11 @@ privsep_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)); @@ -1136,21 +1252,25 @@ privsep_xauth_login_pam(port, raddr, usr, pwd) msg->hdr.ac_cmd = PRIVSEP_XAUTH_LOGIN_PAM; 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] = strlen(pwd) + 1; + 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 += sizeof(msg->bufs.buflen[0]); - memcpy(data, raddr, msg->bufs.buflen[1]); + data += msg->bufs.buflen[0]; + memcpy(data, &isakmp_cfg_config.pool_size, msg->bufs.buflen[1]); data += msg->bufs.buflen[1]; - memcpy(data, usr, msg->bufs.buflen[2]); + memcpy(data, raddr, msg->bufs.buflen[2]); data += msg->bufs.buflen[2]; - memcpy(data, pwd, msg->bufs.buflen[3]); + memcpy(data, usr, msg->bufs.buflen[3]); + + data += msg->bufs.buflen[3]; + memcpy(data, pwd, msg->bufs.buflen[4]); if (privsep_send(privsep_sock[1], msg, len) != 0) return -1; @@ -1183,7 +1303,10 @@ privsep_cleanup_pam(port) if (geteuid() == 0) return cleanup_pam(port); - len = sizeof(*msg) + sizeof(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)); @@ -1193,10 +1316,14 @@ privsep_cleanup_pam(port) 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]); + if (privsep_send(privsep_sock[1], msg, len) != 0) return; diff --git a/crypto/dist/ipsec-tools/src/racoon/privsep.h b/crypto/dist/ipsec-tools/src/racoon/privsep.h index 4c26234b59bf3..9c7b0ec5081b7 100644 --- a/crypto/dist/ipsec-tools/src/racoon/privsep.h +++ b/crypto/dist/ipsec-tools/src/racoon/privsep.h @@ -1,6 +1,6 @@ -/* $NetBSD: privsep.h,v 1.1.1.2 2005/02/23 14:54:25 manu Exp $ */ +/* $NetBSD: privsep.h,v 1.1.1.3 2006/09/09 16:12:14 manu Exp $ */ -/* Id: privsep.h,v 1.3 2005/02/10 02:02:56 manubsd Exp */ +/* Id: privsep.h,v 1.5 2005/06/07 12:22:11 fredsen Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -41,8 +41,9 @@ #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_NBUF_MAX 16 +#define PRIVSEP_NBUF_MAX 24 #define PRIVSEP_BUFLEN_MAX 4096 struct admin_com_bufs { size_t buflen[PRIVSEP_NBUF_MAX]; @@ -59,7 +60,7 @@ int privsep_init __P((void)); vchar_t *privsep_eay_get_pkcs1privkey __P((char *)); int privsep_pfkey_open __P((void)); void privsep_pfkey_close __P((int)); -int privsep_script_exec __P((int, int, char * const *)); +int privsep_script_exec __P((char *, int, char * const *)); vchar_t *privsep_getpsk __P((const char *, const int)); int privsep_xauth_login_system __P((char *, char *)); #ifdef HAVE_LIBPAM @@ -67,5 +68,5 @@ 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/crypto/dist/ipsec-tools/src/racoon/proposal.c b/crypto/dist/ipsec-tools/src/racoon/proposal.c index 0fead434ffffc..60bb14d185630 100644 --- a/crypto/dist/ipsec-tools/src/racoon/proposal.c +++ b/crypto/dist/ipsec-tools/src/racoon/proposal.c @@ -1,6 +1,6 @@ -/* $NetBSD: proposal.c,v 1.1.1.3 2005/08/07 08:47:50 manu Exp $ */ +/* $NetBSD: proposal.c,v 1.1.1.4 2006/09/09 16:12:15 manu Exp $ */ -/* Id: proposal.c,v 1.13.8.5 2005/07/28 05:05:52 manubsd Exp */ +/* Id: proposal.c,v 1.19 2006/04/27 03:41:54 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -75,6 +75,8 @@ #include "nattraversal.h" #endif +static uint g_nextreqid = 1; + /* %%% * modules for ipsec sa spec */ @@ -1113,6 +1115,10 @@ set_proposal_from_proposal(iph2) 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; @@ -1134,8 +1140,8 @@ set_proposal_from_proposal(iph2) /*FALLTHROUGH*/ } - for (pr = pp_peer->head; pr; pr = pr->next) { - + for (pr = pp_peer->head; pr; pr = pr->next) { + newpr = newsaproto(); if (newpr == NULL) { plog(LLV_ERROR, LOCATION, NULL, @@ -1147,8 +1153,23 @@ set_proposal_from_proposal(iph2) newpr->encmode = pr->encmode; newpr->spi = 0; newpr->spi_p = pr->spi; /* copy peer's SPI */ - newpr->reqid_in = 0; - newpr->reqid_out = 0; + { + struct remoteconf *conf; + conf = getrmconf(iph2->dst); + if (conf != NULL && + conf->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) { @@ -1177,15 +1198,3 @@ set_proposal_from_proposal(iph2) free_proppair(pair); 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; -} diff --git a/crypto/dist/ipsec-tools/src/racoon/proposal.h b/crypto/dist/ipsec-tools/src/racoon/proposal.h index 684926d96e6ab..ce3cd89133ad8 100644 --- a/crypto/dist/ipsec-tools/src/racoon/proposal.h +++ b/crypto/dist/ipsec-tools/src/racoon/proposal.h @@ -1,6 +1,6 @@ -/* $NetBSD: proposal.h,v 1.1.1.3 2005/08/07 08:47:50 manu Exp $ */ +/* $NetBSD: proposal.h,v 1.1.1.4 2006/09/09 16:12:15 manu Exp $ */ -/* Id: proposal.h,v 1.5.10.1 2005/05/12 19:34:10 manubsd Exp */ +/* Id: proposal.h,v 1.5 2004/06/11 16:00:17 ludvigm Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -208,6 +208,5 @@ 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 *)); -extern int tunnel_mode_prop __P((struct saprop *p)); #endif /* _PROPOSAL_H */ diff --git a/crypto/dist/ipsec-tools/src/racoon/racoon.8 b/crypto/dist/ipsec-tools/src/racoon/racoon.8 index 09c86037bde4f..4448a9affa690 100644 --- a/crypto/dist/ipsec-tools/src/racoon/racoon.8 +++ b/crypto/dist/ipsec-tools/src/racoon/racoon.8 @@ -1,6 +1,6 @@ -.\" $NetBSD: racoon.8,v 1.1.1.3 2005/08/07 08:47:51 manu Exp $ +.\" $NetBSD: racoon.8,v 1.1.1.4 2006/09/09 16:12:16 manu Exp $ .\" -.\" Id: racoon.8,v 1.3.10.1 2005/04/18 11:10:55 manubsd 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. diff --git a/crypto/dist/ipsec-tools/src/racoon/racoon.conf.5 b/crypto/dist/ipsec-tools/src/racoon/racoon.conf.5 index 5631cffeac959..77b6f5c43f80c 100644 --- a/crypto/dist/ipsec-tools/src/racoon/racoon.conf.5 +++ b/crypto/dist/ipsec-tools/src/racoon/racoon.conf.5 @@ -1,6 +1,6 @@ -.\" $NetBSD: racoon.conf.5,v 1.1.1.7 2005/11/21 14:12:16 manu Exp $ +.\" $NetBSD: racoon.conf.5,v 1.1.1.8 2006/09/09 16:12:17 manu Exp $ .\" -.\" Id: racoon.conf.5,v 1.27.2.11 2005/11/06 17:18:26 monas 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. @@ -135,7 +135,14 @@ When enabled, these enable 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. +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 ; @@ -144,7 +151,7 @@ The user to which the unprivileged instance of should switch. This can be a quoted user name or a numeric UID. .It Ic group Ar group ; -The group to which the unprivileged instance of +The group the unprivilegied instance of .Xr racoon 8 , should switch. This can be a quoted group name or a numeric GID. @@ -158,8 +165,8 @@ reachable: .Bl -tag -width Ds -compact .It Pa /dev/random .It Pa /dev/urandom -.It the certificates -.It the file containing the Xauth banner +.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 @@ -176,7 +183,9 @@ When running in privilege separation mode, .Ic certificate and .Ic script -paths are mandatory. +paths are mandatory, and you need a to restart +.Xr racoon 8 +if you want to change them. .Bl -tag -width Ds -compact .It Ic path include Ar path ; specifies a path to include a file. @@ -210,12 +219,14 @@ 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 -.Ic / +specifies file where to store PID of process. +If path starts with +.Pa / it is treated as an absolute path, otherwise relative to VARRUN directory specified at -compilation time. Default is -.Ic racoon.pid +compilation time. +Default is +.Pa racoon.pid . .El .\" .Ss File Inclusion @@ -291,6 +302,12 @@ There is no default. require that all addresses for ISAKMP must be bound. This statement will be ignored if you do not specify any address. .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, @@ -395,15 +412,26 @@ is obsolete. Instead, use .Ic my_identifier . .\" -.It Ic my_identifier Ar idtype ... ; +.It Xo +.Ic my_identifier Bq Ar qualifier +.Ar idtype ... ; +.Xc 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 . -Use them in the following way: +.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. @@ -412,8 +440,13 @@ This is the default type if you do not specify an identifier to use. 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 Ar file ; -the type is a KEY_ID. +.It Xo +.Ic my_identifier Ic keyid Bq Ic file +.Ar file ; +.Xc +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 @@ -453,7 +486,7 @@ Alternative acceptable peer identifiers may be specified by repeating the .Ic peers_identifier statement. .\" -.It Ic verify_identifier (on \(ba off) ; +.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 @@ -485,10 +518,16 @@ Default is .Pa /etc/openssl/cert.pem .El .\" -.It Ic mode_cfg (on \(ba off) ; +.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 on 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 ar wrong, for instance. +.\" .It Ic peers_certfile ( dnssec | Ar certfile ) ; If .Ic dnssec @@ -530,22 +569,41 @@ was enabled: 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 -Internal DNS server IPv4 address obtained by ISAKMP mode config. -.It INTERNAL_NBNS4 -Internal WINS server IPv4 address obtained by ISAKMP mode config. +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 DEFAULT_DOMAIN +The DNS default domain name obtained by ISAKMP mode config. .El .\" .\" -.It Ic send_cert (on \(ba off) ; +.It Ic send_cert (on | off) ; If you do not want to send a certificate for some reason, set this to off. The default is on. .\" -.It Ic send_cr (on \(ba off) ; +.It Ic send_cr (on | off) ; If you do not want to send a certificate request for some reason, set this to off. The default is on. .\" -.It Ic verify_cert (on \(ba off) ; +.It Ic verify_cert (on | off) ; If you do not want to verify the peer's certificate for some reason, set this to off. The default is on. @@ -557,7 +615,7 @@ Any proposal will be accepted, and the attribute(s) will be not proposed to the peer if you do not specify it (them). They can be individually specified in each proposal. .\" -.It Ic ike_frag (on \(ba off) ; +.It Ic ike_frag (on | off) ; Enable receiver-side IKE fragmentation, if .Xr racoon 8 has been built with this feature. @@ -583,7 +641,7 @@ is, the better is the performance. 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 \(ba off) ; +.It Ic initial_contact (on | off) ; enable this to send an INITIAL-CONTACT message. The default value is .Ic on . @@ -596,7 +654,7 @@ The KAME stack has the switch in the system wide value net.key.preferred_oldsa. when the value is zero, the stack always uses a new SA. .\" -.It Ic passive (on \(ba off) ; +.It Ic passive (on | off) ; If you do not want to initiate the negotiation, set this to on. The default value is .Ic off . @@ -637,13 +695,13 @@ If PFS is required by both sides and if the responder's group is not equal to the initiator's one, then the responder will reject the proposal. .El .\" -.It Ic support_proxy (on \(ba off) ; +.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 \(ba off) ; +.It Ic generate_policy (on | off | require | unique) ; This directive is for the responder. Therefore you should set .Ic passive @@ -661,12 +719,19 @@ 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 means 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 \(ba off \(ba force) ; +.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., @@ -730,7 +795,7 @@ specify 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 +.Ic des, 3des, blowfish, cast128, aes .\".Ic rc5 , idea for Oakley. For other transforms, this statement should not be used. @@ -749,8 +814,9 @@ This directive must be defined. .Ar type is one of: .Ic pre_shared_key , rsasig , gssapi_krb , hybrid_rsa_server , +.Ic hybrid_rsa_client , xauth_rsa_server , xauth_rsa_client , xauth_psk_server or -.Ic hybrid_rsa_client . +.Ic xauth_psk_client . .\" .It Ic dh_group Ar group ; define the group used for the Diffie-Hellman exponentiations. @@ -798,7 +864,7 @@ and policies in the kernel. .Ss Sainfo Specifications .Bl -tag -width Ds -compact .It Xo -.Ic sainfo ( Ar source_id destination_id | Ic anonymous ) [ from Ar idtype [ Ar string ] ] +.Ic sainfo ( Ar source_id destination_id | Ar source_id Ic anonymous | Ic anonymous Ar destination_id | Ic anonymous ) [ from Ar idtype [ Ar string ] ] [ Ic group Ar string ] .Ic { Ar statements Ic } .Xc defines the parameters of the IKE phase 2 (IPsec-SA establishment). @@ -823,17 +889,24 @@ or .Pp .Ar idtype Ar string .Pp -It means exactly the content of ID payload. +It means exactly the content of ID payload (source is the local end, +destination is the remote end). This is not like a filter rule. For example, if you define 3ffe:501:4819::/48 as .Ar source_id . 3ffe:501:4819:1000:/64 will not match. .Pp -In case of longest prefix (selecting single host) +In case of longest prefix (selecting 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. +instructs to send ID type of SUBNET. +Otherwise these instructions are identical. +.Pp +The group keyword allows an xauth group membership check to be performed +for this sainfo section. When the mode_cfg auth source is set to system +or 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 .\" @@ -914,11 +987,11 @@ Note that the kernel may not support the algorithm you have specified. define logging level. .Ar level is one of following: -.Ic notify , debug , +.Ic error , warning , notify , info , debug and .Ic debug2 . The default is -.Ic notify . +.Ic info . If you set the logging level too high on slower machines, IKE negotiation can fail due to timing constraint changes. .El @@ -929,10 +1002,10 @@ IKE negotiation can fail due to timing constraint changes. specified padding format. The following are valid statements: .Bl -tag -width Ds -compact -.It Ic randomize (on \(ba off) ; +.It Ic randomize (on | off) ; enable using a randomized value for padding. The default is on. -.It Ic randomize_length (on \(ba off) ; +.It Ic randomize_length (on | off) ; the pad length is random. The default is off. .It Ic maximum_length Ar number ; @@ -941,11 +1014,11 @@ If .Ic randomize_length is off, this is ignored. The default is 20 bytes. -.It Ic exclusive_tail (on \(ba off) ; +.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 \(ba off) ; +.It Ic strict_check (on | off) ; means to constrain the peer to set the number of pad bytes. The default is off. .El @@ -956,12 +1029,12 @@ The default is off. Defines the information to return for remote hosts' ISAKMP mode config requests. Also defines the authentication source for remote peers -authenticating through hybrid auth. +authenticating through Xauth. .Pp The following are valid statements: .Bl -tag -width Ds -compact -.It Ic auth_source (system \(ba radius \(ba pam) ; -Specify the source for authentication of users through hybrid auth. +.It Ic auth_source (system | radius | pam | ldap) ; +Specify the source for authentication of users through Xauth. .Ar system means to use the Unix user database. This is the default. @@ -975,10 +1048,35 @@ was built with libradius support, and the configuration is done in means to use PAM. It works only if .Xr racoon 8 -was built with libpam support. -.It Ic conf_source (local \(ba radius) ; +was build with libpam support. +.Ar ldap +means to use LDAP. +It works only if +.Xr racoon 8 +was build with libldap support, and the configuration is handled by +adding statements to the +.Ic ldapcfg +section. +.It Ic auth_groups Ar "group1", ... ; +Specify 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) ; +Specify the source for group validataion 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 build with libldap support, and the configuration is handled by +adding statements to the +.Ic ldapcfg +section. +.It Ic conf_source (local | radius | ldap) ; Specify the source for IP addresses and netmask allocated through ISAKMP -mode config. +mode config. .Ar local means to use the local IP pool defined by the .Ic network4 @@ -990,27 +1088,39 @@ This is the default. means to use a RADIUS server. It works only if .Xr racoon 8 -was built with libradius support, and the configuration is done in +was build with libradius support, and the configuration is done in .Xr radius.conf 5 . RADIUS configuration requires RADIUS authentication. -.It Ic accounting (none \(ba radius \(ba pam) ; +.Ar ldap +means to use an LDAP server. +It works only if +.Xr racoon 8 +was build with libldap support, and the configuration is done in the +.Ic ldapcfg +section. +LDAP configuration requires LDAP authentication. +.It Ic accounting (none | system | radius | pam) ; Enable or disable accounting for Xauth logins and logouts. Default is .Ar none , which disable accounting. +.Ar system +enable system accounting through +.Xr utmp 5 . .Ar radius enable RADIUS accounting. It works only if .Xr racoon 8 -was built with libradius support, and the configuration is done in +was build with libradius support, and the configuration is done in .Xr radius.conf 5 . RADIUS accounting require RADIUS authentication. .Ar pam enable PAM accounting. It works only if .Xr racoon 8 -was built with libpam support. -PAM accounting requires PAM authentication. +was build with libpam support. +PAM accounting require +PAM authentication. .It Ic pool_size Ar size Specify the size of the IP address pool, either local or allocated through RADIUS. @@ -1032,10 +1142,26 @@ 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 address ; -The IPv4 address for a DNS server. -.It Ic nbns4 Ar address ; -The IPv4 address for a WINS server. +.It Ic dns4 Ar addresses ; +A list of IPv4 addresses for DNS servers, separated by commas, or on multiple +.Ic dns4 +lines. +.It Ic nbns4 Ar addresses ; +A list of IPv4 address for WINS servers. +.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 @@ -1055,9 +1181,64 @@ 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 distinguised name; +The user dn used to optionaly 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 Special directives .Bl -tag -width Ds -compact -.It Ic complex_bundle (on \(ba off) ; +.It Ic complex_bundle (on | off) ; defines the interpretation of proposal in the case of SA bundle. Normally .Dq IP AH ESP IP payload diff --git a/crypto/dist/ipsec-tools/src/racoon/racoonctl.8 b/crypto/dist/ipsec-tools/src/racoon/racoonctl.8 index db95fe70f466f..4aaa4f982f608 100644 --- a/crypto/dist/ipsec-tools/src/racoon/racoonctl.8 +++ b/crypto/dist/ipsec-tools/src/racoon/racoonctl.8 @@ -1,6 +1,6 @@ -.\" $NetBSD: racoonctl.8,v 1.1.1.4 2005/08/07 08:47:55 manu Exp $ +.\" $NetBSD: racoonctl.8,v 1.1.1.5 2006/09/09 16:12:17 manu Exp $ .\" -.\" Id: racoonctl.8,v 1.2.4.2 2005/04/18 11:10:55 manubsd Exp +.\" Id: racoonctl.8,v 1.6 2006/05/07 21:32:59 manubsd Exp .\" .\" Copyright (C) 2004 Emmanuel Dreyfus .\" All rights reserved. @@ -66,6 +66,9 @@ vpn-disconnect .Nm show-event .Op Fl l +.Nm +logout-user +.Ar login .\" .Sh DESCRIPTION .Nm @@ -88,7 +91,6 @@ The following commands are available: This should cause .Xr racoon 8 to reload its configuration file. -This seems completely broken at the time this man page is written. .It show-schedule Unknown command. .It show-sa Op isakmp|esp|ah|ipsec @@ -143,6 +145,9 @@ flag causes .Nm to not stop once all the events have been read, but rather to loop awaiting and reporting new events. +.It logout-user Ar login +Delete all SA established on behalf of the Xauth user +.Ar login . .El .Pp Command shortcuts are available: @@ -165,6 +170,8 @@ vpn-connect vpn-disconnect .It se show-event +.It lu +logout-user .El .\" .Sh RETURN VALUES diff --git a/crypto/dist/ipsec-tools/src/racoon/racoonctl.c b/crypto/dist/ipsec-tools/src/racoon/racoonctl.c index 29d1e25848bf3..2857b06bc17a2 100644 --- a/crypto/dist/ipsec-tools/src/racoon/racoonctl.c +++ b/crypto/dist/ipsec-tools/src/racoon/racoonctl.c @@ -1,6 +1,6 @@ -/* $NetBSD: racoonctl.c,v 1.1.1.3 2005/08/07 08:47:57 manu Exp $ */ +/* $NetBSD: racoonctl.c,v 1.1.1.4 2006/09/09 16:12:18 manu Exp $ */ -/* Id: racoonctl.c,v 1.2.2.1 2005/04/21 09:07:20 monas Exp */ +/* Id: racoonctl.c,v 1.11 2006/04/06 17:06:25 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -62,6 +62,7 @@ #endif #include #include +#include #include "var.h" #include "vmbuf.h" @@ -74,6 +75,7 @@ #include "handler.h" #include "sockmisc.h" #include "vmbuf.h" +#include "plog.h" #include "isakmp_var.h" #include "isakmp.h" #include "isakmp_xauth.h" @@ -96,6 +98,9 @@ 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 **)); @@ -120,6 +125,10 @@ struct cmd_tag { { f_vpnd, ADMIN_DELETE_ALL_SA_DST,"vd" }, { f_getevt, ADMIN_SHOW_EVT, "show-event" }, { f_getevt, ADMIN_SHOW_EVT, "se" }, +#ifdef ENABLE_HYBRID + { f_logoutusr, ADMIN_LOGOUT_USER, "logout-user" }, + { f_logoutusr, ADMIN_LOGOUT_USER, "lu" }, +#endif { NULL, 0, NULL }, }; @@ -142,7 +151,10 @@ struct evtmsg { { EVTT_XAUTH_FAILED, "Xauth exchange failed", ERROR }, { EVTT_PEERPH1AUTH_FAILED, "Peer failed phase 1 authentication " "(certificate problem?)", ERROR }, + { EVTT_PEERPH1_NOPROP, "Peer failed phase 1 initiation " + "(proposal problem?)", ERROR }, { 0, NULL, UNSPEC }, + { EVTT_NO_ISAKMP_CFG, "No need for ISAKMP mode config ", INFO }, }; static int get_proto __P((char *)); @@ -204,6 +216,7 @@ void print_evt __P((caddr_t, int)); void print_cfg __P((caddr_t, int)); void print_err __P((caddr_t, int)); void print_ph1down __P((caddr_t, int)); +void print_ph1up __P((caddr_t, int)); int evt_poll __P((void)); char * fixed_addr __P((char *, char *, int)); @@ -329,6 +342,7 @@ evt_poll(void) { com_init(); if (com_send(sendbuf) != 0) errx(1, "Cannot send combuf"); + vfree(sendbuf); if (com_recv(&recvbuf) == 0) { handle_recv(recvbuf); @@ -552,7 +566,7 @@ f_deletesa(ac, av) buf = vmalloc(sizeof(*head) + index->l); if (buf == NULL) - return NULL; + goto out; head = (struct admin_com *)buf->v; head->ac_len = buf->l + index->l; @@ -562,6 +576,10 @@ f_deletesa(ac, av) memcpy(buf->v+sizeof(*head), index->v, index->l); +out: + if (index != NULL) + vfree(index); + return buf; } @@ -603,7 +621,7 @@ f_deleteallsadst(ac, av) buf = vmalloc(sizeof(*head) + index->l); if (buf == NULL) - return NULL; + goto out; head = (struct admin_com *)buf->v; head->ac_len = buf->l + index->l; @@ -613,6 +631,10 @@ f_deleteallsadst(ac, av) memcpy(buf->v+sizeof(*head), index->v, index->l); +out: + if (index != NULL) + vfree(index); + return buf; } @@ -692,7 +714,7 @@ f_exchangesa(ac, av) acp = (struct admin_com_psk *) (buf->v + sizeof(*head) + index->l); - acp->id_type = IDTYPE_LOGIN; + acp->id_type = IDTYPE_USERFQDN; acp->id_len = strlen(id) + 1; acp->key_len = strlen(key) + 1; @@ -703,6 +725,8 @@ f_exchangesa(ac, av) strcpy(data, key); } + vfree(index); + return buf; } @@ -782,7 +806,6 @@ f_vpnd(ac, av) char *inet = "inet"; char *anyaddr = "0.0.0.0"; char *idx; - vchar_t *buf, *index; if (ac < 1) errx(1, "VPN gateway required"); @@ -800,6 +823,39 @@ f_vpnd(ac, av) return f_deleteallsadst(nac, nav); } +#ifdef ENABLE_HYBRID +static vchar_t * +f_logoutusr(ac, av) + int ac; + char **av; +{ + vchar_t *buf; + struct admin_com *head; + char *user; + + /* need username */ + if (ac < 1) + errx(1, "insufficient arguments"); + user = av[0]; + if ((user == NULL) || (strlen(user) > LOGINLEN)) + errx(1, "bad login (too long?)"); + + buf = vmalloc(sizeof(*head) + strlen(user) + 1); + if (buf == NULL) + return NULL; + + head = (struct admin_com *)buf->v; + head->ac_len = buf->l; + head->ac_cmd = ADMIN_LOGOUT_USER; + head->ac_errno = 0; + head->ac_proto = 0; + + strncpy((char *)(head + 1), user, LOGINLEN); + + return buf; +} +#endif /* ENABLE_HYBRID */ + static int get_proto(str) @@ -956,20 +1012,23 @@ get_comindex(str, name, port, pref) *name = *port = *pref = NULL; - *name = strdup(str); + *name = racoon_strdup(str); + STRDUP_FATAL(*name); p = strpbrk(*name, "/["); if (p != NULL) { if (*(p + 1) == '\0') goto bad; if (*p == '/') { *p = '\0'; - *pref = strdup(p + 1); + *pref = racoon_strdup(p + 1); + STRDUP_FATAL(*pref); p = strchr(*pref, '['); if (p != NULL) { if (*(p + 1) == '\0') goto bad; *p = '\0'; - *port = strdup(p + 1); + *port = racoon_strdup(p + 1); + STRDUP_FATAL(*port); p = strchr(*pref, ']'); if (p == NULL) goto bad; @@ -977,7 +1036,8 @@ get_comindex(str, name, port, pref) } } else if (*p == '[') { *p = '\0'; - *port = strdup(p + 1); + *port = racoon_strdup(p + 1); + STRDUP_FATAL(*port); p = strchr(*pref, ']'); if (p == NULL) goto bad; @@ -1366,7 +1426,8 @@ print_cfg(buf, len) memset(&addr4, 0, sizeof(addr4)); - if (evtdump->type != EVTT_ISAKMP_CFG_DONE) + if (evtdump->type != EVTT_ISAKMP_CFG_DONE && + evtdump->type != EVTT_NO_ISAKMP_CFG) return; len -= sizeof(*evtdump); @@ -1419,8 +1480,12 @@ print_cfg(buf, len) (n + sizeof(*attr) + ntohs(attr->lorv)); } } - - printf("Bound to address %s\n", inet_ntoa(addr4)); + + if (evtdump->type == EVTT_ISAKMP_CFG_DONE) + printf("Bound to address %s\n", inet_ntoa(addr4)); + else + printf("VPN connexion established\n"); + if (banner) { struct winsize win; int col = 0; @@ -1435,6 +1500,7 @@ print_cfg(buf, len) for (i = 0; i < col; i++) printf("%c", '='); printf("\n"); + racoon_free(banner); } if (evt_filter & EVTF_CFG_STOP) diff --git a/crypto/dist/ipsec-tools/src/racoon/racoonctl.h b/crypto/dist/ipsec-tools/src/racoon/racoonctl.h index bd6354d952062..16dfef350133f 100644 --- a/crypto/dist/ipsec-tools/src/racoon/racoonctl.h +++ b/crypto/dist/ipsec-tools/src/racoon/racoonctl.h @@ -1,6 +1,6 @@ -/* $NetBSD: racoonctl.h,v 1.1.1.2 2005/02/23 14:54:27 manu Exp $ */ +/* $NetBSD: racoonctl.h,v 1.1.1.3 2006/09/09 16:12:09 manu Exp $ */ -/* Id: racoonctl.h,v 1.2 2004/12/30 11:08:32 manubsd Exp */ +/* Id: racoonctl.h,v 1.3 2005/06/19 22:37:47 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -35,7 +35,7 @@ #define _RACOONCTL_H /* bumped on any change to the interface */ -#define RACOONCTL_INTERFACE 20041230 +#define RACOONCTL_INTERFACE 20050619 extern u_int32_t racoonctl_interface; /* bumped when introducing changes that break backward compatibility */ diff --git a/crypto/dist/ipsec-tools/src/racoon/remoteconf.c b/crypto/dist/ipsec-tools/src/racoon/remoteconf.c index 0ec3963800c13..a26ed77d83174 100644 --- a/crypto/dist/ipsec-tools/src/racoon/remoteconf.c +++ b/crypto/dist/ipsec-tools/src/racoon/remoteconf.c @@ -1,6 +1,6 @@ -/* $NetBSD: remoteconf.c,v 1.1.1.5 2005/11/21 14:12:14 manu Exp $ */ +/* $NetBSD: remoteconf.c,v 1.1.1.6 2006/09/09 16:12:19 manu Exp $ */ -/* Id: remoteconf.c,v 1.26.2.5 2005/11/06 17:18:26 monas Exp */ +/* Id: remoteconf.c,v 1.38 2006/05/06 15:52:44 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -62,6 +62,9 @@ #include "debug.h" #include "isakmp_var.h" +#ifdef ENABLE_HYBRID +#include "isakmp_xauth.h" +#endif #include "isakmp.h" #include "ipsec_doi.h" #include "oakley.h" @@ -76,13 +79,12 @@ #include "nattraversal.h" #include "genlist.h" -static TAILQ_HEAD(_rmtree, remoteconf) rmtree; +static TAILQ_HEAD(_rmtree, remoteconf) rmtree, rmtree_save, rmtree_tmp; /* * Script hook names and script hook paths */ char *script_names[SCRIPT_MAX + 1] = { "phase1_up", "phase1_down" }; -vchar_t *script_paths = NULL; /*%%%*/ /* @@ -210,12 +212,13 @@ newrmconf() new->getcert_method = ISAKMP_GETCERT_PAYLOAD; new->getcacert_method = ISAKMP_GETCERT_LOCALFILE; new->cacerttype = ISAKMP_CERT_X509SIGN; + new->certtype = ISAKMP_CERT_NONE; new->cacertfile = NULL; new->send_cert = TRUE; new->send_cr = TRUE; new->support_proxy = FALSE; for (i = 0; i <= SCRIPT_MAX; i++) - new->script[i] = -1; + new->script[i] = NULL; new->gen_policy = FALSE; new->retry_counter = lcconf->retry_counter; new->retry_interval = lcconf->retry_interval; @@ -230,6 +233,12 @@ newrmconf() new->dpd_retry = 5; new->dpd_maxfails = 5; + new->weak_phase1_check = 0; + +#ifdef ENABLE_HYBRID + new->xauth = NULL; +#endif + return new; } @@ -262,8 +271,10 @@ dupidvl(entry, arg) id = newidspec(); if (!id) return (void *) -1; - if (set_identifier(&id->id, old->idtype, old->id) != 0) + if (set_identifier(&id->id, old->idtype, old->id) != 0) { + racoon_free(id); return (void *) -1; + } id->idtype = old->idtype; @@ -305,8 +316,14 @@ void delrmconf(rmconf) struct remoteconf *rmconf; { - if (rmconf->etypes) +#ifdef ENABLE_HYBRID + if (rmconf->xauth) + xauth_rmconf_delete(&rmconf->xauth); +#endif + if (rmconf->etypes){ deletypes(rmconf->etypes); + rmconf->etypes=NULL; + } if (rmconf->idvl_p) genlist_free(rmconf->idvl_p, idspec_free); if (rmconf->dhgrp) @@ -397,6 +414,25 @@ initrmconf() TAILQ_INIT(&rmtree); } +void +save_rmconf() +{ + rmtree_save=rmtree; + initrmconf(); +} + +void +save_rmconf_flush() +{ + rmtree_tmp=rmtree; + rmtree=rmtree_save; + flushrmconf(); + initrmconf(); + rmtree=rmtree_tmp; +} + + + /* check exchange type to be acceptable */ struct etypes * check_etypeok(rmconf, etype) @@ -465,15 +501,14 @@ insisakmpsa(new, rmconf) struct remoteconf * foreachrmconf(rmconf_func_t rmconf_func, void *data) { - struct remoteconf *p, *ret = NULL; - - TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) { - ret = (*rmconf_func)(p, data); - if (ret) - break; - } - - return ret; + struct remoteconf *p, *ret = NULL; + RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) { + ret = (*rmconf_func)(p, data); + if (ret) + break; + } + + return ret; } static void * @@ -614,13 +649,13 @@ newidspec() return new; } -int +vchar_t * script_path_add(path) vchar_t *path; { char *script_dir; - vchar_t *new_storage; vchar_t *new_path; + vchar_t *new_storage; vchar_t **sp; size_t len; size_t size; @@ -634,7 +669,7 @@ script_path_add(path) if ((new_path = vmalloc(len)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory: %s\n", strerror(errno)); - return -1; + return NULL; } new_path->v[0] = '\0'; @@ -646,52 +681,31 @@ script_path_add(path) path = new_path; } - /* First time, initialize */ - if (script_paths == NULL) - len = sizeof(vchar_t *); - else - len = script_paths->l; - - /* Add a slot for a new path */ - len += sizeof(vchar_t *); - if ((new_storage = vrealloc(script_paths, len)) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "Cannot allocate memory: %s\n", strerror(errno)); - return -1; - } - script_paths = new_storage; - - size = len / sizeof(vchar_t *); - sp = (vchar_t **)script_paths->v; - sp[size - 1] = NULL; - sp[size - 2] = path; - - return (size - 2); + return path; } + struct isakmpsa * -dupisakmpsa(sa) - struct isakmpsa *sa; +dupisakmpsa(struct isakmpsa *sa) { - struct isakmpsa *res = NULL; + struct isakmpsa *res=NULL; - if (sa == NULL) + if(sa == NULL) return NULL; - res = newisakmpsa(); + res=newisakmpsa(); if(res == NULL) return NULL; - *res = *sa; + *res=*sa; #ifdef HAVE_GSSAPI - /* - * XXX gssid + /* XXX gssid */ #endif res->next=NULL; - if (sa->dhgrp != NULL) - oakley_setdhgroup(sa->dh_group, &(res->dhgrp)); + if(sa->dhgrp != NULL) + oakley_setdhgroup (sa->dh_group, &(res->dhgrp)); return res; diff --git a/crypto/dist/ipsec-tools/src/racoon/remoteconf.h b/crypto/dist/ipsec-tools/src/racoon/remoteconf.h index 71784fa63d4eb..de63b800e5089 100644 --- a/crypto/dist/ipsec-tools/src/racoon/remoteconf.h +++ b/crypto/dist/ipsec-tools/src/racoon/remoteconf.h @@ -1,6 +1,6 @@ -/* $NetBSD: remoteconf.h,v 1.1.1.3 2005/08/07 08:47:58 manu Exp $ */ +/* $NetBSD: remoteconf.h,v 1.1.1.4 2006/09/09 16:12:19 manu Exp $ */ -/* Id: remoteconf.h,v 1.19.2.1 2005/05/20 00:37:42 manubsd Exp */ +/* Id: remoteconf.h,v 1.26 2006/05/06 15:52:44 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -38,6 +38,10 @@ #include #include "genlist.h" +#ifdef ENABLE_HYBRID +#include "isakmp_var.h" +#include "isakmp_xauth.h" +#endif struct proposalspec; @@ -51,7 +55,6 @@ struct etypes { #define SCRIPT_PHASE1_DOWN 1 #define SCRIPT_MAX 1 extern char *script_names[SCRIPT_MAX + 1]; -extern vchar_t *script_paths; struct remoteconf { struct sockaddr *remote; /* remote IP address */ @@ -86,11 +89,14 @@ struct remoteconf { 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 */ - int script[SCRIPT_MAX + 1]; /* script hooks index in script_paths */ + 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*/ @@ -104,6 +110,8 @@ struct remoteconf { int dpd_interval; /* in seconds */ int dpd_maxfails; + int weak_phase1_check; /* act on unencrypted deletions ? */ + struct isakmpsa *proposal; /* proposal list */ struct remoteconf *inherited_from; /* the original rmconf from which this one @@ -112,6 +120,11 @@ struct remoteconf { 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 */ }; @@ -159,6 +172,9 @@ extern void insrmconf __P((struct remoteconf *)); extern void remrmconf __P((struct remoteconf *)); extern void flushrmconf __P((void)); extern void initrmconf __P((void)); +extern void save_rmconf __P((void)); +extern void save_rmconf_flush __P((void)); + extern struct etypes *check_etypeok __P((struct remoteconf *, u_int8_t)); extern struct remoteconf *foreachrmconf __P((rmconf_func_t rmconf_func, @@ -173,6 +189,6 @@ extern void dumprmconf __P((void)); extern struct idspec *newidspec __P((void)); -extern int script_path_add __P((vchar_t *)); +extern vchar_t *script_path_add __P((vchar_t *)); #endif /* _REMOTECONF_H */ diff --git a/crypto/dist/ipsec-tools/src/racoon/rfc/rfc2367.txt b/crypto/dist/ipsec-tools/src/racoon/rfc/rfc2367.txt new file mode 100644 index 0000000000000..032702d537d4b --- /dev/null +++ b/crypto/dist/ipsec-tools/src/racoon/rfc/rfc2367.txt @@ -0,0 +1,3811 @@ + + + + + + +Network Working Group D. McDonald +Request for Comments: 2367 C. Metz +Category: Informational B. Phan + July 1998 + + + PF_KEY Key Management API, Version 2 + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (1998). All Rights Reserved. + +Abstract + + A generic key management API that can be used not only for IP + Security [Atk95a] [Atk95b] [Atk95c] but also for other network + security services is presented in this document. Version 1 of this + API was implemented inside 4.4-Lite BSD as part of the U. S. Naval + Research Laboratory's freely distributable and usable IPv6 and IPsec + implementation[AMPMC96]. It is documented here for the benefit of + others who might also adopt and use the API, thus providing increased + portability of key management applications (e.g. a manual keying + application, an ISAKMP daemon, a GKMP daemon [HM97a][HM97b], a + Photuris daemon, or a SKIP certificate discovery protocol daemon). + +Table of Contents + + 1 Introduction ............................................. 3 + 1.1 Terminology .............................................. 3 + 1.2 Conceptual Model ......................................... 4 + 1.3 PF_KEY Socket Definition ................................. 8 + 1.4 Overview of PF_KEY Messaging Behavior .................... 8 + 1.5 Common PF_KEY Operations ................................. 9 + 1.6 Differences Between PF_KEY and PF_ROUTE .................. 10 + 1.7 Name Space ............................................... 11 + 1.8 On Manual Keying ..........................................11 + 2 PF_KEY Message Format .................................... 11 + 2.1 Base Message Header Format ............................... 12 + 2.2 Alignment of Headers and Extension Headers ............... 14 + 2.3 Additional Message Fields ................................ 14 + 2.3.1 Association Extension .................................... 15 + 2.3.2 Lifetime Extension ....................................... 16 + + + +McDonald, et. al. Informational [Page 1] + +RFC 2367 PF_KEY Key Management API July 1998 + + + 2.3.3 Address Extension ........................................ 18 + 2.3.4 Key Extension ............................................ 19 + 2.3.5 Identity Extension ....................................... 21 + 2.3.6 Sensitivity Extension .................................... 21 + 2.3.7 Proposal Extension ....................................... 22 + 2.3.8 Supported Algorithms Extension ........................... 25 + 2.3.9 SPI Range Extension ...................................... 26 + 2.4 Illustration of Message Layout ........................... 27 + 3 Symbolic Names ........................................... 30 + 3.1 Message Types ............................................ 31 + 3.1.1 SADB_GETSPI .............................................. 32 + 3.1.2 SADB_UPDATE .............................................. 33 + 3.1.3 SADB_ADD ................................................. 34 + 3.1.4 SADB_DELETE .............................................. 35 + 3.1.5 SADB_GET ................................................. 36 + 3.1.6 SADB_ACQUIRE ............................................. 36 + 3.1.7 SADB_REGISTER ............................................ 38 + 3.1.8 SADB_EXPIRE .............................................. 39 + 3.1.9 SADB_FLUSH ............................................... 40 + 3.1.10 SADB_DUMP ................................................ 40 + 3.2 Security Association Flags ............................... 41 + 3.3 Security Association States .............................. 41 + 3.4 Security Association Types ............................... 41 + 3.5 Algorithm Types .......................................... 42 + 3.6 Extension Header Values .................................. 43 + 3.7 Identity Extension Values ................................ 44 + 3.8 Sensitivity Extension Values ............................. 45 + 3.9 Proposal Extension Values ................................ 45 + 4 Future Directions ........................................ 45 + 5 Examples ................................................. 45 + 5.1 Simple IP Security Example ............................... 46 + 5.2 Proxy IP Security Example ................................ 47 + 5.3 OSPF Security Example .................................... 50 + 5.4 Miscellaneous ............................................ 50 + 6 Security Considerations .................................. 51 + Acknowledgments ............,............................. 52 + References ............................................... 52 + Disclaimer ............................................... 54 + Authors' Addresses ....................................... 54 + A Promiscuous Send/Receive Extension ....................... 55 + B Passive Change Message Extension ......................... 57 + C Key Management Private Data Extension .................... 58 + D Sample Header File ....................................... 59 + E Change Log ............................................... 64 + F Full Copyright Statement ................................. 68 + + + + + + +McDonald, et. al. Informational [Page 2] + +RFC 2367 PF_KEY Key Management API July 1998 + + +1 Introduction + + PF_KEY is a new socket protocol family used by trusted privileged key + management applications to communicate with an operating system's key + management internals (referred to here as the "Key Engine" or the + Security Association Database (SADB)). The Key Engine and its + structures incorporate the required security attributes for a session + and are instances of the "Security Association" (SA) concept + described in [Atk95a]. The names PF_KEY and Key Engine thus refer to + more than cryptographic keys and are retained for consistency with + the traditional phrase, "Key Management". + + PF_KEY is derived in part from the BSD routing socket, PF_ROUTE. + [Skl91] This document describes Version 2 of PF_KEY. Version 1 was + implemented in the first five alpha test versions of the NRL + IPv6+IPsec Software Distribution for 4.4-Lite BSD UNIX and the Cisco + ISAKMP/Oakley key management daemon. Version 2 extends and refines + this interface. Theoretically, the messages defined in this document + could be used in a non-socket context (e.g. between two directly + communicating user-level processes), but this document will not + discuss in detail such possibilities. + + Security policy is deliberately omitted from this interface. PF_KEY + is not a mechanism for tuning systemwide security policy, nor is it + intended to enforce any sort of key management policy. The developers + of PF_KEY believe that it is important to separate security + mechanisms (such as PF_KEY) from security policies. This permits a + single mechanism to more easily support multiple policies. + +1.1 Terminology + + Even though this document is not intended to be an actual Internet + standard, the words that are used to define the significance of + particular features of this interface are usually capitalized. Some + of these words, including MUST, MAY, and SHOULD, are detailed in + [Bra97]. + + - CONFORMANCE and COMPLIANCE + + Conformance to this specification has the same meaning as compliance + to this specification. In either case, the mandatory-to-implement, + or MUST, items MUST be fully implemented as specified here. If any + mandatory item is not implemented as specified here, that + implementation is not conforming and not compliant with this + specification. + + + + + + +McDonald, et. al. Informational [Page 3] + +RFC 2367 PF_KEY Key Management API July 1998 + + + This specification also uses many terms that are commonly used in the + context of network security. Other documents provide more + definitions and background information on these [VK83, HA94, Atk95a]. + Two terms deserve special mention: + + - (Encryption/Authentication) Algorithm + + For PF_KEY purposes, an algorithm, whether encryption or + authentication, is the set of operations performed on a packet to + complete authentication or encryption as indicated by the SA type. A + PF_KEY algorithm MAY consist of more than one cryptographic + algorithm. Another possibility is that the same basic cryptographic + algorithm may be applied with different modes of operation or some + other implementation difference. These differences, henceforth called + _algorithm differentiators_, distinguish between different PF_KEY + algorithms, and options to the same algorithm. Algorithm + differentiators will often cause fundamentally different security + properties. + + For example, both DES and 3DES use the same cryptographic algorithm, + but they are used differently and have different security properties. + The triple-application of DES is considered an algorithm + differentiator. There are therefore separate PF_KEY algorithms for + DES and 3DES. Keyed-MD5 and HMAC-MD5 use the same hash function, but + construct their message authentication codes differently. The use of + HMAC is an algorithm differentiator. DES-ECB and DES-CBC are the + same cryptographic algorithm, but use a different mode. Mode (e.g., + chaining vs. code-book) is an algorithm differentiator. Blowfish with + a 128-bit key, however, is similar to Blowfish with a 384-bit key, + because the algorithm's workings are otherwise the same and therefore + the key length is not an algorithm differentiator. + + In terms of IP Security, a general rule of thumb is that whatever + might be labeled the "encryption" part of an ESP transform is + probably a PF_KEY encryption algorithm. Whatever might be labelled + the "authentication" part of an AH or ESP transform is probably a + PF_KEY authentication algorithm. + +1.2 Conceptual Model + + This section describes the conceptual model of an operating system + that implements the PF_KEY key management application programming + interface. This section is intended to provide background material + useful to understand the rest of this document. Presentation of this + conceptual model does not constrain a PF_KEY implementation to + strictly adhere to the conceptual components discussed in this + subsection. + + + + +McDonald, et. al. Informational [Page 4] + +RFC 2367 PF_KEY Key Management API July 1998 + + + Key management is most commonly implemented in whole or in part at + the application layer. For example, the ISAKMP/Oakley, GKMP, and + Photuris proposals for IPsec key management are all application-layer + protocols. Manual keying is also done at the application layer. + Even parts of the SKIP IP-layer keying proposal can be implemented at + the application layer. Figure 1 shows the relationship between a Key + Management daemon and PF_KEY. Key management daemons use PF_KEY to + communicate with the Key Engine and use PF_INET (or PF_INET6 in the + case of IPv6) to communicate, via the network, with a remote key + management entity. + + The "Key Engine" or "Security Association Database (SADB)" is a + logical entity in the kernel that stores, updates, and deletes + Security Association data for various security protocols. There are + logical interfaces within the kernel (e.g. getassocbyspi(), + getassocbysocket()) that security protocols inside the kernel (e.g. + IP Security, aka IPsec) use to request and obtain Security + Associations. + + In the case of IPsec, if by policy a particular outbound packet needs + processing, then the IPsec implementation requests an appropriate + Security Association from the Key Engine via the kernel-internal + interface. If the Key Engine has an appropriate SA, it allocates the + SA to this session (marking it as used) and returns the SA to the + IPsec implementation for use. If the Key Engine has no such SA but a + key management application has previously indicated (via a PF_KEY + SADB_REGISTER message) that it can obtain such SAs, then the Key + Engine requests that such an SA be created (via a PF_KEY SADB_ACQUIRE + message). When the key management daemon creates a new SA, it places + it into the Key Engine for future use. + + + + + + + + + + + + + + + + + + + + + +McDonald, et. al. Informational [Page 5] + +RFC 2367 PF_KEY Key Management API July 1998 + + + +---------------+ + |Key Mgmt Daemon| + +---------------+ + | | + | | + | | Applications + ======[PF_KEY]====[PF_INET]========================== + | | OS Kernel + +------------+ +-----------------+ + | Key Engine | | TCP/IP, | + | or SADB |---| including IPsec | + +------------+ | | + +-----------------+ + | + +-----------+ + | Network | + | Interface | + +-----------+ + + Figure 1: Relationship of Key Mgmt to PF_KEY + + For performance reasons, some security protocols (e.g. IP Security) + are usually implemented inside the operating system kernel. Other + security protocols (e.g. OSPFv2 Cryptographic Authentication) are + implemented in trusted privileged applications outside the kernel. + Figure 2 shows a trusted, privileged routing daemon using PF_INET to + communicate routing information with a remote routing daemon and + using PF_KEY to request, obtain, and delete Security Associations + used with a routing protocol. + + + + + + + + + + + + + + + + + + + + + + +McDonald, et. al. Informational [Page 6] + +RFC 2367 PF_KEY Key Management API July 1998 + + + +---------------+ + |Routing Daemon| + +---------------+ + | | + | | + | | Applications + ======[PF_KEY]====[PF_INET]========================== + | | OS Kernel + +------------+ +---------+ + | Key Engine | | TCP/IP | + | or SADB |---| | + +------------+ +---------+ + | + +-----------+ + | Network | + | Interface | + +-----------+ + + Figure 2: Relationship of Trusted Application to PF_KEY + + When a trusted privileged application is using the Key Engine but + implements the security protocol within itself, then operation varies + slightly. In this case, the application needing an SA sends a PF_KEY + SADB_ACQUIRE message down to the Key Engine, which then either + returns an error or sends a similar SADB_ACQUIRE message up to one or + more key management applications capable of creating such SAs. As + before, the key management daemon stores the SA into the Key Engine. + Then, the trusted privileged application uses an SADB_GET message to + obtain the SA from the Key Engine. + + In some implementations, policy may be implemented in user-space, + even though the actual cryptographic processing takes place in the + kernel. Such policy communication between the kernel mechanisms and + the user-space policy MAY be implemented by PF_KEY extensions, or + other such mechanism. This document does not specify such + extensions. A PF_KEY implementation specified by the memo does NOT + have to support configuring systemwide policy using PF_KEY. + + Untrusted clients, for example a user's web browser or telnet client, + do not need to use PF_KEY. Mechanisms not specified here are used by + such untrusted client applications to request security services (e.g. + IPsec) from an operating system. For security reasons, only trusted, + privileged applications are permitted to open a PF_KEY socket. + + + + + + + + +McDonald, et. al. Informational [Page 7] + +RFC 2367 PF_KEY Key Management API July 1998 + + +1.3 PF_KEY Socket Definition + + The PF_KEY protocol family (PF_KEY) symbol is defined in + in the same manner that other protocol families are + defined. PF_KEY does not use any socket addresses. Applications + using PF_KEY MUST NOT depend on the availability of a symbol named + AF_KEY, but kernel implementations are encouraged to define that + symbol for completeness. + + The key management socket is created as follows: + + #include + #include + #include + + int s; + s = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); + + The PF_KEY domain currently supports only the SOCK_RAW socket type. + The protocol field MUST be set to PF_KEY_V2, or else EPROTONOSUPPORT + will be returned. Only a trusted, privileged process can create a + PF_KEY socket. On conventional UNIX systems, a privileged process is + a process with an effective userid of zero. On non-MLS proprietary + operating systems, the notion of a "privileged process" is + implementation-defined. On Compartmented Mode Workstations (CMWs) or + other systems that claim to provide Multi-Level Security (MLS), a + process MUST have the "key management privilege" in order to open a + PF_KEY socket[DIA]. MLS systems that don't currently have such a + specific privilege MUST add that special privilege and enforce it + with PF_KEY in order to comply and conform with this specification. + Some systems, most notably some popular personal computers, do not + have the concept of an unprivileged user. These systems SHOULD take + steps to restrict the programs allowed to access the PF_KEY API. + +1.4 Overview of PF_KEY Messaging Behavior + + A process interacts with the key engine by sending and receiving + messages using the PF_KEY socket. Security association information + can be inserted into and retrieved from the kernel's security + association table using a set of predefined messages. In the normal + case, all properly-formed messages sent to the kernel are returned to + all open PF_KEY sockets, including the sender. Improperly formed + messages will result in errors, and an implementation MUST check for + a properly formed message before returning it to the appropriate + listeners. Unlike the routing socket, most errors are sent in reply + messages, not the errno field when write() or send() fails. PF_KEY + message delivery is not guaranteed, especially in cases where kernel + or socket buffers are exhausted and messages are dropped. + + + +McDonald, et. al. Informational [Page 8] + +RFC 2367 PF_KEY Key Management API July 1998 + + + Some messages are generated by the operating system to indicate that + actions need to be taken, and are not necessarily in response to any + message sent down by the user. Such messages are not received by all + PF_KEY sockets, but by sockets which have indicated that kernel- + originated messages are to be received. These messages are special + because of the expected frequency at which they will occur. Also, an + implementation may further wish to restrict return messages from the + kernel, in cases where not all PF_KEY sockets are in the same trust + domain. + + Many of the normal BSD socket calls have undefined behavior on PF_KEY + sockets. These include: bind(), connect(), socketpair(), accept(), + getpeername(), getsockname(), ioctl(), and listen(). + +1.5 Common PF_KEY Operations + + There are two basic ways to add a new Security Association into the + kernel. The simplest is to send a single SADB_ADD message, + containing all of the SA information, from the application into the + kernel's Key Engine. This approach works particularly well with + manual key management, which is required for IPsec, and other + security protocols. + + The second approach to add a new Security Association into the kernel + is for the application to first request a Security Parameters Index + (SPI) value from the kernel using the SADB_GETSPI message and then + send an SADB_UPDATE message with the complete Security Association + data. This second approach works well with key management daemons + when the SPI values need to be known before the entire Security + Association data is known (e.g. so the SPI value can be indicated to + the remote end of the key management session). + + An individual Security Association can be deleted using the + SADB_DELETE message. Categories of SAs or the entire kernel SA table + can be deleted using the SADB_FLUSH message. + + The SADB_GET message is used by a trusted application-layer process + (e.g. routed(8) or gated(8)) to retrieve an SA (e.g. RIP SA or OSPF + SA) from the kernel's Key Engine. + + The kernel or an application-layer can use the SADB_ACQUIRE message + to request that a Security Association be created by some + application-layer key management process that has registered with the + kernel via an SADB_REGISTER message. This ACQUIRE message will have + a sequence number associated with it. This sequence number MUST be + used by followup SADB_GETSPI, SADB_UPDATE, and SADB_ADD messages, in + order to keep track of which request gets its keying material. The + sequence number (described below) is similar to a transaction ID in a + + + +McDonald, et. al. Informational [Page 9] + +RFC 2367 PF_KEY Key Management API July 1998 + + + remote procedure call. + + The SADB_EXPIRE message is sent from the kernel to key management + applications when the "soft lifetime" or "hard lifetime" of a + Security Association has expired. Key management applications should + use receipt of a soft lifetime SADB_EXPIRE message as a hint to + negotiate a replacement SA so the replacement SA will be ready and in + the kernel before it is needed. + + A SADB_DUMP message is also defined, but this is primarily intended + for PF_KEY implementor debugging and is not used in ordinary + operation of PF_KEY. + +1.6 Differences Between PF_KEY and PF_ROUTE + + The following bullets are points of difference between the routing + socket and PF_KEY. Programmers who are used to the routing socket + semantics will find some differences in PF_KEY. + + * PF_KEY message errors are usually returned in PF_KEY messages + instead of causing write() operations to fail and returning the + error number in errno. This means that other listeners on a PF_KEY + socket can be aware that requests from another process failed, + which can be useful for auditing purposes. This also means that + applications that fail to read PF_KEY messages cannot do error + checking. + + An implementation MAY return the errors EINVAL, ENOMEM, and ENOBUFS + by causing write() operations to fail and returning the error + number in errno. This is an optimization for common error cases in + which it does not make sense for any other process to receive the + error. An application MUST NOT depend on such errors being set by + the write() call, but it SHOULD check for such errors, and handle + them in an appropriate manner. + + * The entire message isn't always reflected in the reply. A SADB_ADD + message is an example of this. + + * The PID is not set by the kernel. The process that originates the + message MUST set the sadb_msg_pid to its own PID. If the kernel + ORIGINATES a message, it MUST set the sadb_msg_pid to 0. A reply + to an original message SHOULD have the pid of the original message. + (E.g. the kernel's response to an SADB_ADD SHOULD have its pid set + to the pid value of the original SADB_ADD message.) + + + + + + + +McDonald, et. al. Informational [Page 10] + +RFC 2367 PF_KEY Key Management API July 1998 + + +1.7 Name Space + + All PF_KEYv2 preprocessor symbols and structure definitions are + defined as a result of including the header file . + There is exactly one exception to this rule: the symbol "PF_KEY" (two + exceptions if "AF_KEY" is also counted), which is defined as a result + of including the header file . All PF_KEYv2 + preprocessor symbols start with the prefix "SADB_" and all structure + names start with "sadb_". There are exactly two exceptions to this + rule: the symbol "PF_KEY_V2" and the symbol "PFKEYV2_REVISION". + + The symbol "PFKEYV2_REVISION" is a date-encoded value not unlike + certain values defined by POSIX and X/Open. The current value for + PFKEYV2_REVISION is 199806L, where 1998 is the year and 06 is the + month. + + Inclusion of the file MUST NOT define symbols or + structures in the PF_KEYv2 name space that are not described in this + document without the explicit prior permission of the authors. Any + symbols or structures in the PF_KEYv2 name space that are not + described in this document MUST start with "SADB_X_" or "sadb_x_". An + implementation that fails to obey these rules IS NOT COMPLIANT WITH + THIS SPECIFICATION and MUST NOT make any claim to be. These rules + also apply to any files that might be included as a result of + including the file . This rule provides implementors + with some assurance that they will not encounter namespace-related + surprises. + +1.8 On Manual Keying + + Not unlike the 4.4-Lite BSD PF_ROUTE socket, this interface allows an + application full-reign over the security associations in a kernel + that implements PF_KEY. A PF_KEY implementation MUST have some sort + of manual interface to PF_KEY, which SHOULD allow all of the + functionality of the programmatic interface described here. + +2. PF_KEY Message Format + + PF_KEY messages consist of a base header followed by additional data + fields, some of which may be optional. The format of the additional + data is dependent on the type of message. + + PF_KEY messages currently do not mandate any specific ordering for + non-network multi-octet fields. Unless otherwise specified (e.g. SPI + values), fields MUST be in host-specific byte order. + + + + + + +McDonald, et. al. Informational [Page 11] + +RFC 2367 PF_KEY Key Management API July 1998 + + +2.1 Base Message Header Format + + PF_KEY messages consist of the base message header followed by + security association specific data whose types and lengths are + specified by a generic type-length encoding. + + This base header is shown below, using POSIX types. The fields are + arranged primarily for alignment, and where possible, for reasons of + clarity. + + struct sadb_msg { + uint8_t sadb_msg_version; + uint8_t sadb_msg_type; + uint8_t sadb_msg_errno; + uint8_t sadb_msg_satype; + uint16_t sadb_msg_len; + uint16_t sadb_msg_reserved; + uint32_t sadb_msg_seq; + uint32_t sadb_msg_pid; + }; + /* sizeof(struct sadb_msg) == 16 */ + + sadb_msg_version + The version field of this PF_KEY message. This MUST + be set to PF_KEY_V2. If this is not set to PF_KEY_V2, + the write() call MAY fail and return EINVAL. + Otherwise, the behavior is undetermined, given that + the application might not understand the formatting + of the messages arriving from the kernel. + + sadb_msg_type Identifies the type of message. The valid message + types are described later in this document. + + sadb_msg_errno Should be set to zero by the sender. The responder + stores the error code in this field if an error has + occurred. This includes the case where the responder + is in user space. (e.g. user-space negotiation + fails, an errno can be returned.) + + sadb_msg_satype Indicates the type of security association(s). Valid + Security Association types are declared in the file + . The current set of Security + Association types is enumerated later in this + document. + + + + + + + +McDonald, et. al. Informational [Page 12] + +RFC 2367 PF_KEY Key Management API July 1998 + + + sadb_msg_len Contains the total length, in 64-bit words, of all + data in the PF_KEY message including the base header + length and additional data after the base header, if + any. This length includes any padding or extra space + that might exist. Unless otherwise stated, all other + length fields are also measured in 64-bit words. + + On user to kernel messages, this field MUST be + verified against the length of the inbound message. + EMSGSIZE MUST be returned if the verification fails. + On kernel to user messages, a size mismatch is most + likely the result of the user not providing a large + enough buffer for the message. In these cases, the + user application SHOULD drop the message, but it MAY + try and extract what information it can out of the + message. + + sadb_msg_reserved + Reserved value. It MUST be zeroed by the sender. All + fields labeled reserved later in the document have + the same semantics as this field. + + sadb_msg_seq Contains the sequence number of this message. This + field, along with sadb_msg_pid, MUST be used to + uniquely identify requests to a process. The sender + is responsible for filling in this field. This + responsibility also includes matching the + sadb_msg_seq of a request (e.g. SADB_ACQUIRE). + + This field is similar to a transaction ID in a + remote procedure call implementation. + + sadb_msg_pid Identifies the process which originated this message, + or which process a message is bound for. For + example, if process id 2112 sends an SADB_UPDATE + message to the kernel, the process MUST set this + field to 2112 and the kernel will set this field + to 2112 in its reply to that SADB_UPDATE + message. This field, along with sadb_msg_seq, can + be used to uniquely identify requests to a + process. + + It is currently assumed that a 32-bit quantity will + hold an operating system's process ID space. + + + + + + + +McDonald, et. al. Informational [Page 13] + +RFC 2367 PF_KEY Key Management API July 1998 + + +2.2 Alignment of Headers and Extension Headers + + The base message header is a multiple of 64 bits and fields after it + in memory will be 64 bit aligned if the base itself is 64 bit + aligned. Some of the subsequent extension headers have 64 bit fields + in them, and as a consequence need to be 64 bit aligned in an + environment where 64 bit quantities need to be 64 bit aligned. + + The basic unit of alignment and length in PF_KEY Version 2 is 64 + bits. Therefore: + + * All extension headers, inclusive of the sadb_ext overlay fields, + MUST be a multiple of 64 bits long. + + * All variable length data MUST be padded appropriately such that + its length in a message is a multiple of 64 bits. + + * All length fields are, unless otherwise specified, in units of + 64 bits. + + * Implementations may safely access quantities of between 8 and 64 + bits directly within a message without risk of alignment faults. + + All PF_KEYv2 structures are packed and already have all intended + padding. Implementations MUST NOT insert any extra fields, including + hidden padding, into any structure in this document. This forbids + implementations from "extending" or "enhancing" existing headers + without changing the extension header type. As a guard against such + insertion of silent padding, each structure in this document is + labeled with its size in bytes. The size of these structures in an + implementation MUST match the size listed. + +2.3 Additional Message Fields + + The additional data following the base header consists of various + length-type-values fields. The first 32-bits are of a constant form: + + struct sadb_ext { + uint16_t sadb_ext_len; + uint16_t sadb_ext_type; + }; + /* sizeof(struct sadb_ext) == 4 */ + + sadb_ext_len Length of the extension header in 64 bit words, + inclusive. + + + + + + +McDonald, et. al. Informational [Page 14] + +RFC 2367 PF_KEY Key Management API July 1998 + + + sadb_ext_type The type of extension header that follows. Values for + this field are detailed later. The value zero is + reserved. + + Types of extension headers include: Association, Lifetime(s), + Address(s), Key(s), Identity(ies), Sensitivity, Proposal, and + Supported. There MUST be only one instance of a extension type in a + message. (e.g. Base, Key, Lifetime, Key is forbidden). An EINVAL + will be returned if there are duplicate extensions within a message. + Implementations MAY enforce ordering of extensions in the order + presented in the EXTENSION HEADER VALUES section. + + If an unknown extension type is encountered, it MUST be ignored. + Applications using extension headers not specified in this document + MUST be prepared to work around other system components not + processing those headers. Likewise, if an application encounters an + unknown extension from the kernel, it must be prepared to work around + it. Also, a kernel that generates extra extension header types MUST + NOT _depend_ on applications also understanding extra extension + header types. + + All extension definitions include these two fields (len and exttype) + because they are instances of a generic extension (not unlike + sockaddr_in and sockaddr_in6 are instances of a generic sockaddr). + The sadb_ext header MUST NOT ever be present in a message without at + least four bytes of extension header data following it, and, + therefore, there is no problem with it being only four bytes long. + + All extensions documented in this section MUST be implemented by a + PF_KEY implementation. + +2.3.1 Association Extension + + The Association extension specifies data specific to a single + security association. The only times this extension is not present is + when control messages (e.g. SADB_FLUSH or SADB_REGISTER) are being + passed and on the SADB_ACQUIRE message. + + struct sadb_sa { + uint16_t sadb_sa_len; + uint16_t sadb_sa_exttype; + uint32_t sadb_sa_spi; + uint8_t sadb_sa_replay; + uint8_t sadb_sa_state; + uint8_t sadb_sa_auth; + uint8_t sadb_sa_encrypt; + uint32_t sadb_sa_flags; + }; + + + +McDonald, et. al. Informational [Page 15] + +RFC 2367 PF_KEY Key Management API July 1998 + + + /* sizeof(struct sadb_sa) == 16 */ + + sadb_sa_spi The Security Parameters Index value for the security + association. Although this is a 32-bit field, some + types of security associations might have an SPI or + key identifier that is less than 32-bits long. In + this case, the smaller value shall be stored in the + least significant bits of this field and the unneeded + bits shall be zero. This field MUST be in network + byte order. + + sadb_sa_replay The size of the replay window, if not zero. If zero, + then no replay window is in use. + + sadb_sa_state The state of the security association. The currently + defined states are described later in this document. + + sadb_sa_auth The authentication algorithm to be used with this + security association. The valid authentication + algorithms are described later in this document. A + value of zero means that no authentication is used + for this security association. + + sadb_sa_encrypt The encryption algorithm to be used with this + security association. The valid encryption algorithms + are described later in this document. A value of zero + means that no encryption is used for this security + association. + + sadb_sa_flags A bitmap of options defined for the security + association. The currently defined flags are + described later in this document. + + The kernel MUST check these values where appropriate. For example, + IPsec AH with no authentication algorithm is probably an error. + + When used with some messages, the values in some fields in this + header should be ignored. + +2.3.2 Lifetime Extension + + The Lifetime extension specifies one or more lifetime variants for + this security association. If no Lifetime extension is present the + association has an infinite lifetime. An association SHOULD have a + lifetime of some sort associated with it. Lifetime variants come in + three varieties, HARD - indicating the hard-limit expiration, SOFT - + indicating the soft-limit expiration, and CURRENT - indicating the + current state of a given security association. The Lifetime + + + +McDonald, et. al. Informational [Page 16] + +RFC 2367 PF_KEY Key Management API July 1998 + + + extension looks like: + + struct sadb_lifetime { + uint16_t sadb_lifetime_len; + uint16_t sadb_lifetime_exttype; + uint32_t sadb_lifetime_allocations; + uint64_t sadb_lifetime_bytes; + uint64_t sadb_lifetime_addtime; + uint64_t sadb_lifetime_usetime; + }; + /* sizeof(struct sadb_lifetime) == 32 */ + + sadb_lifetime_allocations + For CURRENT, the number of different connections, + endpoints, or flows that the association has been + allocated towards. For HARD and SOFT, the number of + these the association may be allocated towards + before it expires. The concept of a connection, + flow, or endpoint is system specific. + + sadb_lifetime_bytes + For CURRENT, how many bytes have been processed + using this security association. For HARD and SOFT, + the number of bytes that may be processed using + this security association before it expires. + + sadb_lifetime_addtime + For CURRENT, the time, in seconds, when the + association was created. For HARD and SOFT, the + number of seconds after the creation of the + association until it expires. + + For such time fields, it is assumed that 64-bits is + sufficiently large to hold the POSIX time_t value. + If this assumption is wrong, this field will have to + be revisited. + + sadb_lifetime_usetime + For CURRENT, the time, in seconds, when association + was first used. For HARD and SOFT, the number of + seconds after the first use of the association until + it expires. + + The semantics of lifetimes are inclusive-OR, first-to-expire. This + means that if values for bytes and time, or multiple times, are + passed in, the first of these values to be reached will cause a + lifetime expiration. + + + + +McDonald, et. al. Informational [Page 17] + +RFC 2367 PF_KEY Key Management API July 1998 + + +2.3.3 Address Extension + + The Address extension specifies one or more addresses that are + associated with a security association. Address extensions for both + source and destination MUST be present when an Association extension + is present. The format of an Address extension is: + + struct sadb_address { + uint16_t sadb_address_len; + uint16_t sadb_address_exttype; + uint8_t sadb_address_proto; + uint8_t sadb_address_prefixlen; + uint16_t sadb_address_reserved; + }; + /* sizeof(struct sadb_address) == 8 */ + + /* followed by some form of struct sockaddr */ + + The sockaddr structure SHOULD conform to the sockaddr structure of + the system implementing PF_KEY. If the system has an sa_len field, so + SHOULD the sockaddrs in the message. If the system has NO sa_len + field, the sockaddrs SHOULD NOT have an sa_len field. All non-address + information in the sockaddrs, such as sin_zero for AF_INET sockaddrs, + and sin6_flowinfo for AF_INET6 sockaddrs, MUST be zeroed out. The + zeroing of ports (e.g. sin_port and sin6_port) MUST be done for all + messages except for originating SADB_ACQUIRE messages, which SHOULD + fill them in with ports from the relevant TCP or UDP session which + generates the ACQUIRE message. If the ports are non-zero, then the + sadb_address_proto field, normally zero, MUST be filled in with the + transport protocol's number. If the sadb_address_prefixlen is non- + zero, then the address has a prefix (often used in KM access control + decisions), with length specified in sadb_address_prefixlen. These + additional fields may be useful to KM applications. + + The SRC and DST addresses for a security association MUST be in the + same protocol family and MUST always be present or absent together in + a message. The PROXY address MAY be in a different protocol family, + and for most security protocols, represents an actual originator of a + packet. (For example, the inner-packets's source address in a + tunnel.) + + The SRC address MUST be a unicast or unspecified (e.g., INADDR_ANY) + address. The DST address can be any valid destination address + (unicast, multicast, or even broadcast). The PROXY address SHOULD be + a unicast address (there are experimental security protocols where + PROXY semantics may be different than described above). + + + + + +McDonald, et. al. Informational [Page 18] + +RFC 2367 PF_KEY Key Management API July 1998 + + +2.3.4 Key Extension + + The Key extension specifies one or more keys that are associated with + a security association. A Key extension will not always be present + with messages, because of security risks. The format of a Key + extension is: + + struct sadb_key { + uint16_t sadb_key_len; + uint16_t sadb_key_exttype; + uint16_t sadb_key_bits; + uint16_t sadb_key_reserved; + }; + /* sizeof(struct sadb_key) == 8 */ + + /* followed by the key data */ + + sadb_key_bits The length of the valid key data, in bits. A value of + zero in sadb_key_bits MUST cause an error. + + The key extension comes in two varieties. The AUTH version is used + with authentication keys (e.g. IPsec AH, OSPF MD5) and the ENCRYPT + version is used with encryption keys (e.g. IPsec ESP). PF_KEY deals + only with fully formed cryptographic keys, not with "raw key + material". For example, when ISAKMP/Oakley is in use, the key + management daemon is always responsible for transforming the result + of the Diffie-Hellman computation into distinct fully formed keys + PRIOR to sending those keys into the kernel via PF_KEY. This rule is + made because PF_KEY is designed to support multiple security + protocols (not just IP Security) and also multiple key management + schemes including manual keying, which does not have the concept of + "raw key material". A clean, protocol-independent interface is + important for portability to different operating systems as well as + for portability to different security protocols. + + If an algorithm defines its key to include parity bits (e.g. DES) + then the key used with PF_KEY MUST also include those parity bits. + For example, this means that a single DES key is always a 64-bit + quantity. + + When a particular security protocol only requires one authentication + and/or one encryption key, the fully formed key is transmitted using + the appropriate key extension. When a particular security protocol + requires more than one key for the same function (e.g. Triple-DES + using 2 or 3 keys, and asymmetric algorithms), then those two fully + formed keys MUST be concatenated together in the order used for + outbound packet processing. In the case of multiple keys, the + algorithm MUST be able to determine the lengths of the individual + + + +McDonald, et. al. Informational [Page 19] + +RFC 2367 PF_KEY Key Management API July 1998 + + + keys based on the information provided. The total key length (when + combined with knowledge of the algorithm in use) usually provides + sufficient information to make this determination. + + Keys are always passed through the PF_KEY interface in the order that + they are used for outbound packet processing. For inbound processing, + the correct order that keys are used might be different from this + canonical concatenation order used with the PF_KEY interface. It is + the responsibility of the implementation to use the keys in the + correct order for both inbound and outbound processing. + + For example, consider a pair of nodes communicating unicast using an + ESP three-key Triple-DES Security Association. Both the outbound SA + on the sender node, and the inbound SA on the receiver node will + contain key-A, followed by key-B, followed by key-C in their + respective ENCRYPT key extensions. The outbound SA will use key-A + first, followed by key-B, then key-C when encrypting. The inbound SA + will use key-C, followed by key-B, then key-A when decrypting. + (NOTE: We are aware that 3DES is actually encrypt-decrypt-encrypt.) + The canonical ordering of key-A, key-B, key-C is used for 3DES, and + should be documented. The order of "encryption" is the canonical + order for this example. [Sch96] + + The key data bits are arranged most-significant to least significant. + For example, a 22-bit key would take up three octets, with the least + significant two bits not containing key material. Five additional + octets would then be used for padding to the next 64-bit boundary. + + While not directly related to PF_KEY, there is a user interface issue + regarding odd-digit hexadecimal representation of keys. Consider the + example of the 16-bit number: + + 0x123 + + That will require two octets of storage. In the absence of other + information, however, unclear whether the value shown is stored as: + + 01 23 OR 12 30 + + It is the opinion of the authors that the former (0x123 == 0x0123) is + the better way to interpret this ambiguity. Extra information (for + example, specifying 0x0123 or 0x1230, or specifying that this is only + a twelve-bit number) would solve this problem. + + + + + + + + +McDonald, et. al. Informational [Page 20] + +RFC 2367 PF_KEY Key Management API July 1998 + + +2.3.5 Identity Extension + + The Identity extension contains endpoint identities. This + information is used by key management to select the identity + certificate that is used in negotiations. This information may also + be provided by a kernel to network security aware applications to + identify the remote entity, possibly for access control purposes. If + this extension is not present, key management MUST assume that the + addresses in the Address extension are the only identities for this + Security Association. The Identity extension looks like: + + struct sadb_ident { + uint16_t sadb_ident_len; + uint16_t sadb_ident_exttype; + uint16_t sadb_ident_type; + uint16_t sadb_ident_reserved; + uint64_t sadb_ident_id; + }; + /* sizeof(struct sadb_ident) == 16 */ + + /* followed by the identity string, if present */ + + sadb_ident_type The type of identity information that follows. + Currently defined identity types are described later + in this document. + + sadb_ident_id An identifier used to aid in the construction of an + identity string if none is present. A POSIX user id + value is one such identifier that will be used in this + field. Use of this field is described later in this + document. + + A C string containing a textual representation of the identity + information optionally follows the sadb_ident extension. The format + of this string is determined by the value in sadb_ident_type, and is + described later in this document. + +2.3.6 Sensitivity Extension + + The Sensitivity extension contains security labeling information for + a security association. If this extension is not present, no + sensitivity-related data can be obtained from this security + association. If this extension is present, then the need for + explicit security labeling on the packet is obviated. + + struct sadb_sens { + uint16_t sadb_sens_len; + uint16_t sadb_sens_exttype; + + + +McDonald, et. al. Informational [Page 21] + +RFC 2367 PF_KEY Key Management API July 1998 + + + uint32_t sadb_sens_dpd; + uint8_t sadb_sens_sens_level; + uint8_t sadb_sens_sens_len; + uint8_t sadb_sens_integ_level; + uint8_t sadb_sens_integ_len; + uint32_t sadb_sens_reserved; + }; + /* sizeof(struct sadb_sens) == 16 */ + + /* followed by: + uint64_t sadb_sens_bitmap[sens_len]; + uint64_t sadb_integ_bitmap[integ_len]; */ + + sadb_sens_dpd Describes the protection domain, which allows + interpretation of the levels and compartment + bitmaps. + sadb_sens_sens_level + The sensitivity level. + sadb_sens_sens_len + The length, in 64 bit words, of the sensitivity + bitmap. + sadb_sens_integ_level + The integrity level. + sadb_sens_integ_len + The length, in 64 bit words, of the integrity + bitmap. + + This sensitivity extension is designed to support the Bell-LaPadula + [BL74] security model used in compartmented-mode or multi-level + secure systems, the Clark-Wilson [CW87] commercial security model, + and/or the Biba integrity model [Biba77]. These formal models can be + used to implement a wide variety of security policies. The definition + of a particular security policy is outside the scope of this + document. Each of the bitmaps MUST be padded to a 64-bit boundary if + they are not implicitly 64-bit aligned. + +2.3.7 Proposal Extension + + The Proposal extension contains a "proposed situation" of algorithm + preferences. It looks like: + + struct sadb_prop { + uint16_t sadb_prop_len; + uint16_t sadb_prop_exttype; + uint8_t sadb_prop_replay; + uint8_t sadb_prop_reserved[3]; + }; + /* sizeof(struct sadb_prop) == 8 */ + + + +McDonald, et. al. Informational [Page 22] + +RFC 2367 PF_KEY Key Management API July 1998 + + + /* followed by: + struct sadb_comb sadb_combs[(sadb_prop_len * + sizeof(uint64_t) - sizeof(struct sadb_prop)) / + sizeof(struct sadb_comb)]; */ + + Following the header is a list of proposed parameter combinations in + preferential order. The values in these fields have the same + definition as the fields those values will move into if the + combination is chosen. + + NOTE: Some algorithms in some security protocols will have + variable IV lengths per algorithm. Variable length IVs + are not supported by PF_KEY v2. If they were, however, + proposed IV lengths would go in the Proposal Extension. + + These combinations look like: + + struct sadb_comb { + uint8_t sadb_comb_auth; + uint8_t sadb_comb_encrypt; + uint16_t sadb_comb_flags; + uint16_t sadb_comb_auth_minbits; + uint16_t sadb_comb_auth_maxbits; + uint16_t sadb_comb_encrypt_minbits; + uint16_t sadb_comb_encrypt_maxbits; + uint32_t sadb_comb_reserved; + uint32_t sadb_comb_soft_allocations; + uint32_t sadb_comb_hard_allocations; + uint64_t sadb_comb_soft_bytes; + uint64_t sadb_comb_hard_bytes; + uint64_t sadb_comb_soft_addtime; + uint64_t sadb_comb_hard_addtime; + uint64_t sadb_comb_soft_usetime; + uint64_t sadb_comb_hard_usetime; + }; + + /* sizeof(struct sadb_comb) == 72 */ + + sadb_comb_auth If this combination is accepted, this will be the + value of sadb_sa_auth. + + sadb_comb_encrypt + If this combination is accepted, this will be the + value of sadb_sa_encrypt. + + + + + + + +McDonald, et. al. Informational [Page 23] + +RFC 2367 PF_KEY Key Management API July 1998 + + + sadb_comb_auth_minbits; + sadb_comb_auth_maxbits; + The minimum and maximum acceptable authentication + key lengths, respectably, in bits. If sadb_comb_auth + is zero, both of these values MUST be zero. If + sadb_comb_auth is nonzero, both of these values MUST + be nonzero. If this combination is accepted, a value + between these (inclusive) will be stored in the + sadb_key_bits field of KEY_AUTH. The minimum MUST + NOT be greater than the maximum. + + sadb_comb_encrypt_minbits; + sadb_comb_encrypt_maxbits; + The minimum and maximum acceptable encryption key + lengths, respectably, in bits. If sadb_comb_encrypt + is zero, both of these values MUST be zero. If + sadb_comb_encrypt is nonzero, both of these values + MUST be nonzero. If this combination is accepted, a + value between these (inclusive) will be stored in + the sadb_key_bits field of KEY_ENCRYPT. The minimum + MUST NOT be greater than the maximum. + + sadb_comb_soft_allocations + sadb_comb_hard_allocations + If this combination is accepted, these are proposed + values of sadb_lifetime_allocations in the SOFT and + HARD lifetimes, respectively. + + sadb_comb_soft_bytes + sadb_comb_hard_bytes + If this combination is accepted, these are proposed + values of sadb_lifetime_bytes in the SOFT and HARD + lifetimes, respectively. + + sadb_comb_soft_addtime + sadb_comb_hard_addtime + If this combination is accepted, these are proposed + values of sadb_lifetime_addtime in the SOFT and HARD + lifetimes, respectively. + + sadb_comb_soft_usetime + sadb_comb_hard_usetime + If this combination is accepted, these are proposed + values of sadb_lifetime_usetime in the SOFT and HARD + lifetimes, respectively. + + + + + + +McDonald, et. al. Informational [Page 24] + +RFC 2367 PF_KEY Key Management API July 1998 + + + Each combination has an authentication and encryption algorithm, + which may be 0, indicating none. A combination's flags are the same + as the flags in the Association extension. The minimum and maximum + key lengths (which are in bits) are derived from possible a priori + policy decisions, along with basic properties of the algorithm. + Lifetime attributes are also included in a combination, as some + algorithms may know something about their lifetimes and can suggest + lifetime limits. + +2.3.8 Supported Algorithms Extension + + The Supported Algorithms extension contains a list of all algorithms + supported by the system. This tells key management what algorithms it + can negotiate. Available authentication algorithms are listed in the + SUPPORTED_AUTH extension and available encryption algorithms are + listed in the SUPPORTED_ENCRYPT extension. The format of these + extensions is: + + struct sadb_supported { + uint16_t sadb_supported_len; + uint16_t sadb_supported_exttype; + uint32_t sadb_supported_reserved; + }; + /* sizeof(struct sadb_supported) == 8 */ + + /* followed by: + struct sadb_alg sadb_algs[(sadb_supported_len * + sizeof(uint64_t) - sizeof(struct sadb_supported)) / + sizeof(struct sadb_alg)]; */ + + This header is followed by one or more algorithm descriptions. An + algorithm description looks like: + + struct sadb_alg { + uint8_t sadb_alg_id; + uint8_t sadb_alg_ivlen; + uint16_t sadb_alg_minbits; + uint16_t sadb_alg_maxbits; + uint16_t sadb_alg_reserved; + }; + /* sizeof(struct sadb_alg) == 8 */ + + sadb_alg_id The algorithm identification value for this + algorithm. This is the value that is stored in + sadb_sa_auth or sadb_sa_encrypt if this algorithm is + selected. + + + + + +McDonald, et. al. Informational [Page 25] + +RFC 2367 PF_KEY Key Management API July 1998 + + + sadb_alg_ivlen The length of the initialization vector to be used + for the algorithm. If an IV is not needed, this + value MUST be set to zero. + + sadb_alg_minbits + The minimum acceptable key length, in bits. A value + of zero is invalid. + + sadb_alg_maxbits + The maximum acceptable key length, in bits. A value + of zero is invalid. The minimum MUST NOT be greater + than the maximum. + +2.3.9 SPI Range Extension + + One PF_KEY message, SADB_GETSPI, might need a range of acceptable SPI + values. This extension performs such a function. + + struct sadb_spirange { + uint16_t sadb_spirange_len; + uint16_t sadb_spirange_exttype; + uint32_t sadb_spirange_min; + uint32_t sadb_spirange_max; + uint32_t sadb_spirange_reserved; + }; + /* sizeof(struct sadb_spirange) == 16 */ + + sadb_spirange_min + The minimum acceptable SPI value. + + sadb_spirange_max + The maximum acceptable SPI value. The maximum MUST + be greater than or equal to the minimum. + + + + + + + + + + + + + + + + + + +McDonald, et. al. Informational [Page 26] + +RFC 2367 PF_KEY Key Management API July 1998 + + +2.4 Illustration of Message Layout + + The following shows how the octets are laid out in a PF_KEY message. + Optional fields are indicated as such. + + The base header is as follows: + + 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 + +---------------+---------------+---------------+---------------+ + | ...version | sadb_msg_type | sadb_msg_errno| ...msg_satype | + +---------------+---------------+---------------+---------------+ + | sadb_msg_len | sadb_msg_reserved | + +---------------+---------------+---------------+---------------+ + | sadb_msg_seq | + +---------------+---------------+---------------+---------------+ + | sadb_msg_pid | + +---------------+---------------+---------------+---------------+ + + The base header may be followed by one or more of the following + extension fields, depending on the values of various base header + fields. The following fields are ordered such that if they appear, + they SHOULD appear in the order presented below. + + An extension field MUST not be repeated. If there is a situation + where an extension MUST be repeated, it should be brought to the + attention of the authors. + + The Association extension + + 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 + +---------------+---------------+---------------+---------------+ + | sadb_sa_len | sadb_sa_exttype | + +---------------+---------------+---------------+---------------+ + | sadb_sa_spi | + +---------------+---------------+---------------+---------------+ + | ...replay | sadb_sa_state | sadb_sa_auth |sadb_sa_encrypt| + +---------------+---------------+---------------+---------------+ + | sadb_sa_flags | + +---------------+---------------+---------------+---------------+ + + The Lifetime extension + + +---------------+---------------+---------------+---------------+ + | sadb_lifetime_len | sadb_lifetime_exttype | + +---------------+---------------+---------------+---------------+ + | sadb_lifetime_allocations | + +---------------+---------------+---------------+---------------+ + + + + +McDonald, et. al. Informational [Page 27] + +RFC 2367 PF_KEY Key Management API July 1998 + + + +---------------+---------------+---------------+---------------+ + | sadb_lifetime_bytes | + | (64 bits) | + +---------------+---------------+---------------+---------------+ + | sadb_lifetime_addtime | + | (64 bits) | + +---------------+---------------+---------------+---------------+ + | sadb_lifetime_usetime | + | (64 bits) | + +---------------+---------------+---------------+---------------+ + + The Address extension + + +---------------+---------------+---------------+---------------+ + | sadb_address_len | sadb_address_exttype | + +---------------+---------------+---------------+---------------+ + | _address_proto| ..._prefixlen | sadb_address_reserved | + +---------------+---------------+---------------+---------------+ + > Some form of 64-bit aligned struct sockaddr goes here. < + +---------------+---------------+---------------+---------------+ + + The Key extension + + +---------------+---------------+---------------+---------------+ + | sadb_key_len | sadb_key_exttype | + +---------------+---------------+---------------+---------------+ + | sadb_key_bits | sadb_key_reserved | + +---------------+---------------+---------------+---------------+ + > A key, padded to 64-bits, most significant bits to least. > + +---------------+---------------+---------------+---------------+ + + The Identity extension + + +---------------+---------------+---------------+---------------+ + | sadb_ident_len | sadb_ident_exttype | + +---------------+---------------+---------------+---------------+ + | sadb_ident_type | sadb_ident_reserved | + +---------------+---------------+---------------+---------------+ + | sadb_ident_id | + | (64 bits) | + +---------------+---------------+---------------+---------------+ + > A null-terminated C-string which MUST be padded out for > + < 64-bit alignment. < + +---------------+---------------+---------------+---------------+ + + + + + + + +McDonald, et. al. Informational [Page 28] + +RFC 2367 PF_KEY Key Management API July 1998 + + + The Sensitivity extension + + +---------------+---------------+---------------+---------------+ + | sadb_sens_len | sadb_sens_exttype | + +---------------+---------------+---------------+---------------+ + | sadb_sens_dpd | + +---------------+---------------+---------------+---------------+ + | ...sens_level | ...sens_len |..._integ_level| ..integ_len | + +---------------+---------------+---------------+---------------+ + | sadb_sens_reserved | + +---------------+---------------+---------------+---------------+ + > The sensitivity bitmap, followed immediately by the < + < integrity bitmap, each is an array of uint64_t. > + +---------------+---------------+---------------+---------------+ + + The Proposal extension + + +---------------+---------------+---------------+---------------+ + | sadb_prop_len | sadb_prop_exttype | + +---------------+---------------+---------------+---------------+ + |...prop_replay | sadb_prop_reserved | + +---------------+---------------+---------------+---------------+ + > One or more combinations, specified as follows... < + +---------------+---------------+---------------+---------------+ + + Combination + +---------------+---------------+---------------+---------------+ + |sadb_comb_auth |sadb_comb_encr | sadb_comb_flags | + +---------------+---------------+---------------+---------------+ + | sadb_comb_auth_minbits | sadb_comb_auth_maxbits | + +---------------+---------------+---------------+---------------+ + | sadb_comb_encrypt_minbits | sadb_comb_encrypt_maxbits | + +---------------+---------------+---------------+---------------+ + | sadb_comb_reserved | + +---------------+---------------+---------------+---------------+ + | sadb_comb_soft_allocations | + +---------------+---------------+---------------+---------------+ + | sadb_comb_hard_allocations | + +---------------+---------------+---------------+---------------+ + | sadb_comb_soft_bytes | + | (64 bits) | + +---------------+---------------+---------------+---------------+ + | sadb_comb_hard_bytes | + | (64 bits) | + +---------------+---------------+---------------+---------------+ + | sadb_comb_soft_addtime | + | (64 bits) | + +---------------+---------------+---------------+---------------+ + + + +McDonald, et. al. Informational [Page 29] + +RFC 2367 PF_KEY Key Management API July 1998 + + + +---------------+---------------+---------------+---------------+ + | sadb_comb_hard_addtime | + | (64 bits) | + +---------------+---------------+---------------+---------------+ + | sadb_comb_soft_usetime | + | (64 bits) | + +---------------+---------------+---------------+---------------+ + | sadb_comb_hard_usetime | + | (64 bits) | + +---------------+---------------+---------------+---------------+ + + The Supported Algorithms extension + + +---------------+---------------+---------------+---------------+ + | sadb_supported_len | sadb_supported_exttype | + +---------------+---------------+---------------+---------------+ + | sadb_supported_reserved | + +---------------+---------------+---------------+---------------+ + + Followed by one or more Algorithm Descriptors + + +---------------+---------------+---------------+---------------+ + | sadb_alg_id | sadb_alg_ivlen| sadb_alg_minbits | + +---------------+---------------+---------------+---------------+ + | sadb_alg_maxbits | sadb_alg_reserved | + +---------------+---------------+---------------+---------------+ + + The SPI Range extension + + +---------------+---------------+---------------+---------------+ + | sadb_spirange_len | sadb_spirange_exttype | + +---------------+---------------+---------------+---------------+ + | sadb_spirange_min | + +---------------+---------------+---------------+---------------+ + | sadb_spirange_max | + +---------------+---------------+---------------+---------------+ + | sadb_spirange_reserved | + +---------------+---------------+---------------+---------------+ + +3 Symbolic Names + + This section defines various symbols used with PF_KEY and the + semantics associated with each symbol. Applications MUST use the + symbolic names in order to be portable. The numeric definitions + shown are for illustrative purposes, unless explicitly stated + otherwise. The numeric definition MAY vary on other systems. The + symbolic name MUST be kept the same for all conforming + implementations. + + + +McDonald, et. al. Informational [Page 30] + +RFC 2367 PF_KEY Key Management API July 1998 + + +3.1 Message Types + + The following message types are used with PF_KEY. These are defined + in the file . + + #define SADB_RESERVED 0 + #define SADB_GETSPI 1 + #define SADB_UPDATE 2 + #define SADB_ADD 3 + #define SADB_DELETE 4 + #define SADB_GET 5 + #define SADB_ACQUIRE 6 + #define SADB_REGISTER 7 + #define SADB_EXPIRE 8 + #define SADB_FLUSH 9 + + #define SADB_DUMP 10 /* not used normally */ + + #define SADB_MAX 10 + + Each message has a behavior. A behavior is defined as where the + initial message travels (e.g. user to kernel), and what subsequent + actions are expected to take place. Contents of messages are + illustrated as: + + + + The SA extension is sometimes used only for its SPI field. If all + other fields MUST be ignored, this is represented by "SA(*)". + + The lifetime extensions are represented with one to three letters + after the word "lifetime," representing (H)ARD, (S)OFT, and + (C)URRENT. + + The address extensions are represented with one to three letters + after the word "address," representing (S)RC, (D)ST, (P)ROXY. + + NOTE: Some security association types do not use a source + address for SA identification, where others do. This may + cause EEXIST errors for some SA types where others do not + report collisions. It is expected that application + authors know enough about the underlying security + association types to understand these differences. + + The key extensions are represented with one or two letters after the + word "key," representing (A)UTH and (E)NCRYPT. + + + + + +McDonald, et. al. Informational [Page 31] + +RFC 2367 PF_KEY Key Management API July 1998 + + + The identity extensions are represented with one or two letters after + the word "identity," representing (S)RC and (D)ST. + + In the case of an error, only the base header is returned. + + Note that any standard error could be returned for any message. + + Typically, they will be either one of the errors specifically listed + in the description for a message or one of the following: + + EINVAL Various message improprieties, including SPI ranges + that are malformed. + ENOMEM Needed memory was not available. + ENOBUFS Needed memory was not available. + EMSGSIZ The message exceeds the maximum length allowed. + +3.1.1 SADB_GETSPI + + The SADB_GETSPI message allows a process to obtain a unique SPI value + for given security association type, source address, and destination + address. This message followed by an SADB_UPDATE is one way to + create a security association (SADB_ADD is the other method). The + process specifies the type in the base header, the source and + destination address in address extension. If the SADB_GETSPI message + is in response to a kernel-generated SADB_ACQUIRE, the sadb_msg_seq + MUST be the same as the SADB_ACQUIRE message. The application may + also specify the SPI. This is done by having the kernel select + within a range of SPI values by using the SPI range extension. To + specify a single SPI value to be verified, the application sets the + high and low values to be equal. Permitting range specification is + important because the kernel can allocate an SPI value based on what + it knows about SPI values already in use. The kernel returns the + same message with the allocated SPI value stored in the spi field of + an association extension. The allocate SPI (and destination address) + refer to a LARVAL security association. An SADB_UPDATE message can + later be used to add an entry with the requested SPI value. + + It is recommended that associations that are created with SADB_GETSPI + SHOULD be automatically deleted within a fixed amount of time if they + are not updated by an SADB_UPDATE message. This allows SA storage + not to get cluttered with larval associations. + + The message behavior of the SADB_GETSPI message is: + + Send an SADB_GETSPI message from a user process to the kernel. + + + + + + +McDonald, et. al. Informational [Page 32] + +RFC 2367 PF_KEY Key Management API July 1998 + + + The kernel returns the SADB_GETSPI message to all listening + processes. + + + + Errors: + + EEXIST Requested SPI or SPI range is not available or already + used. + +3.1.2 SADB_UPDATE Message + + The SADB_UPDATE message allows a process to update the information in + an existing Security Association. Since SADB_GETSPI does not allow + setting of certain parameters, this message is needed to fully form + the SADB_SASTATE_LARVAL security association created with + SADB_GETSPI. The format of the update message is a base header, + followed by an association header and possibly by several extension + headers. The kernel searches for the security association with the + same type, spi, source address and destination address specified in + the message and updates the Security Association information using + the content of the SADB_UPDATE message. + + The kernel MAY disallow SADB_UPDATE to succeed unless the message is + issued from the same socket that created the security association. + Such enforcement significantly reduces the chance of accidental + changes to an in-use security association. Malicious trusted parties + could still issue an SADB_FLUSH or SADB_DELETE message, but deletion + of associations is more easily detected and less likely to occur + accidentally than an erroneous SADB_UPDATE. The counter argument to + supporting this behavior involves the case where a user-space key + management application fails and is restarted. The new instance of + the application will not have the same socket as the creator of the + security association. + + The kernel MUST sanity check all significant values submitted in an + SADB_UPDATE message before changing the SA in its database and MUST + return EINVAL if any of the values are invalid. Examples of checks + that should be performed are DES key parity bits, key length + checking, checks for keys known to be weak for the specified + algorithm, and checks for flags or parameters known to be + incompatible with the specified algorithm. + + Only SADB_SASTATE_MATURE SAs may be submitted in an SADB_UPDATE + message. If the original SA is an SADB_SASTATE_LARVAL SA, then any + value in the SA may be changed except for the source address, + destination address, and SPI. If the original SA is an + SADB_SASTATE_DEAD SA, any attempt to perform an SADB_UPDATE on the SA + + + +McDonald, et. al. Informational [Page 33] + +RFC 2367 PF_KEY Key Management API July 1998 + + + MUST return EINVAL. It is not valid for established keying or + algorithm information to change without the SPI changing, which would + require creation of a new SA rather than a change to an existing SA. + Once keying and algorithm information is negotiated, address and + identity information is fixed for the SA. Therefore, if the original + SA is an SADB_SASTATE_MATURE or DYING SA, only the sadb_sa_state + field in the SA header and lifetimes (hard, soft, and current) may be + changed and any attempt to change other values MUST result in an + error return of EINVAL. + + The message behavior of the SADB_UPDATE message is: + + Send an SADB_UPDATE message from a user process to the kernel. + + + + The kernel returns the SADB_UPDATE message to all listening + processes. + + + + + The keying material is not returned on the message from the kernel to + listening sockets because listeners might not have the privileges to + see such keying material. + + Errors: + ESRCH The security association to be updated was not found. + EINVAL In addition to other possible causes, this error is + returned if sanity checking on the SA values (such + as the keys) fails. + EACCES Insufficient privilege to update entry. The socket + issuing the SADB_UPDATE is not creator of the entry + to be updated. + +3.1.3 SADB_ADD + + The SADB_ADD message is nearly identical to the SADB_UPDATE message, + except that it does not require a previous call to SADB_GETSPI. The + SADB_ADD message is used in manual keying applications, and in other + cases where the uniqueness of the SPI is known immediately. + + An SADB_ADD message is also used when negotiation is finished, and + the second of a pair of associations is added. The SPI for this + association was determined by the peer machine. The sadb_msg_seq + + + + +McDonald, et. al. Informational [Page 34] + +RFC 2367 PF_KEY Key Management API July 1998 + + + MUST be set to the value set in a kernel-generated SADB_ACQUIRE so + that both associations in a pair are bound to the same ACQUIRE + request. + + The kernel MUST sanity check all used fields in the SA submitted in + an SADB_ADD message before adding the SA to its database and MUST + return EINVAL if any of the values are invalid. + + Only SADB_SASTATE_MATURE SAs may be submitted in an SADB_ADD message. + SADB_SASTATE_LARVAL SAs are created by SADB_GETSPI and it is not + sensible to add a new SA in the DYING or SADB_SASTATE_DEAD state. + Therefore, the sadb_sa_state field of all submitted SAs MUST be + SADB_SASTATE_MATURE and the kernel MUST return an error if this is + not true. + + The message behavior of the SADB_ADD message is: + + Send an SADB_ADD message from a user process to the kernel. + + + + The kernel returns the SADB_ADD message to all listening + processes. + + + + The keying material is not returned on the message from the kernel to + listening sockets because listeners may not have the privileges to + see such keying material. + + Errors: + + EEXIST The security association that was to be added already + exists. + EINVAL In addition to other possible causes, this error is + returned if sanity checking on the SA values (such + as the keys) fails. + +3.1.4 SADB_DELETE + + The SADB_DELETE message causes the kernel to delete a Security + Association from the key table. The delete message consists of the + base header followed by the association, and the source and + destination sockaddrs in the address extension. The kernel deletes + the security association matching the type, spi, source address, and + destination address in the message. + + + +McDonald, et. al. Informational [Page 35] + +RFC 2367 PF_KEY Key Management API July 1998 + + + The message behavior for SADB_DELETE is as follows: + + Send an SADB_DELETE message from a user process to the kernel. + + + + The kernel returns the SADB_DELETE message to all listening + processes. + + + +3.1.5 SADB_GET + + The SADB_GET message allows a process to retrieve a copy of a + Security Association from the kernel's key table. The get message + consists of the base header follows by the relevant extension fields. + The Security Association matching the type, spi, source address, and + destination address is returned. + + The message behavior of the SADB_GET message is: + + Send an SADB_GET message from a user process to the kernel. + + + + The kernel returns the SADB_GET message to the socket that sent + the SADB_GET message. + + + + Errors: + ESRCH The sought security association was not found. + +3.1.6 SADB_ACQUIRE + + The SADB_ACQUIRE message is typically sent only by the kernel to key + socket listeners who have registered their key socket (see + SADB_REGISTER message). SADB_ACQUIRE messages can be sent by + application-level consumers of security associations (such as an + OSPFv2 implementation that uses OSPF security). The SADB_ACQUIRE + message is a base header along with an address extension, possibly an + identity extension, and a proposal extension. The proposed situation + contains a list of desirable algorithms that can be used if the + algorithms in the base header are not available. The values for the + fields in the base header and in the security association data which + follows the base header indicate the properties of the Security + Association that the listening process should attempt to acquire. If + + + +McDonald, et. al. Informational [Page 36] + +RFC 2367 PF_KEY Key Management API July 1998 + + + the message originates from the kernel (i.e. the sadb_msg_pid is 0), + the sadb_msg_seq number MUST be used by a subsequent SADB_GETSPI and + SADB_UPDATE, or subsequent SADB_ADD message to bind a security + association to the request. This avoids the race condition of two + TCP connections between two IP hosts that each require unique + associations, and having one steal another's security association. + The sadb_msg_errno and sadb_msg_state fields should be ignored by the + listening process. + + The SADB_ACQUIRE message is typically triggered by an outbound packet + that needs security but for which there is no applicable Security + Association existing in the key table. If the packet can be + sufficiently protected by more than one algorithm or combination of + options, the SADB_ACQUIRE message MUST order the preference of + possibilities in the Proposal extension. + + There are three messaging behaviors for SADB_ACQUIRE. The first is + where the kernel needs a security association (e.g. for IPsec). + + The kernel sends an SADB_ACQUIRE message to registered sockets. + + + + NOTE: The address(SD) extensions MUST have the port fields + filled in with the port numbers of the session requiring + keys if appropriate. + + The second is when, for some reason, key management fails, it can + send an ACQUIRE message with the same sadb_msg_seq as the initial + ACQUIRE with a non-zero errno. + + Send an SADB_ACQUIRE to indicate key management failure. + + + + The third is where an application-layer consumer of security + associations (e.g. an OSPFv2 or RIPv2 daemon) needs a security + association. + + Send an SADB_ACQUIRE message from a user process to the kernel. + + + + The kernel returns an SADB_ACQUIRE message to registered + sockets. + + + + +McDonald, et. al. Informational [Page 37] + +RFC 2367 PF_KEY Key Management API July 1998 + + + + + The user-level consumer waits for an SADB_UPDATE or SADB_ADD + message for its particular type, and then can use that + association by using SADB_GET messages. + + Errors: + EINVAL Invalid acquire request. + EPROTONOSUPPORT No KM application has registered with the Key + Engine as being able to obtain the requested SA type, so + the requested SA cannot be acquired. + +3.1.7 SADB_REGISTER + + The SADB_REGISTER message allows an application to register its key + socket as able to acquire new security associations for the kernel. + SADB_REGISTER allows a socket to receive SADB_ACQUIRE messages for + the type of security association specified in sadb_msg_satype. The + application specifies the type of security association that it can + acquire for the kernel in the type field of its register message. If + an application can acquire multiple types of security association, it + MUST register each type in a separate message. Only the base header + is needed for the register message. Key management applications MAY + register for a type not known to the kernel, because the consumer may + be in user-space (e.g. OSPFv2 security). + + The reply of the SADB_REGISTER message contains a supported algorithm + extension. That field contains an array of supported algorithms, one + per octet. This allows key management applications to know what + algorithm are supported by the kernel. + + In an environment where algorithms can be dynamically loaded and + unloaded, an asynchronous SADB_REGISTER reply MAY be generated. The + list of supported algorithms MUST be a complete list, so the + application can make note of omissions or additions. + + The messaging behavior of the SADB_REGISTER message is: + + Send an SADB_REGISTER message from a user process to the kernel. + + + + The kernel returns an SADB_REGISTER message to registered + sockets, with algorithm types supported by the kernel being + indicated in the supported algorithms field. + + + + + +McDonald, et. al. Informational [Page 38] + +RFC 2367 PF_KEY Key Management API July 1998 + + + NOTE: This message may arrive asynchronously due to an + algorithm being loaded or unloaded into a dynamically + linked kernel. + + + +3.1.8 SADB_EXPIRE Message + + The operating system kernel is responsible for tracking SA + expirations for security protocols that are implemented inside the + kernel. If the soft limit or hard limit of a Security Association + has expired for a security protocol implemented inside the kernel, + then the kernel MUST issue an SADB_EXPIRE message to all key socket + listeners. If the soft limit or hard limit of a Security Association + for a user-level security protocol has expired, the user-level + protocol SHOULD issue an SADB_EXPIRE message. + + The base header will contain the security association information + followed by the source sockaddr, destination sockaddr, (and, if + present, internal sockaddr,) (and, if present, one or both + compartment bitmaps). + + The lifetime extension of an SADB_EXPIRE message is important to + indicate which lifetime expired. If a HARD lifetime extension is + included, it indicates that the HARD lifetime expired. This means + the association MAY be deleted already from the SADB. If a SOFT + lifetime extension is included, it indicates that the SOFT lifetime + expired. The CURRENT lifetime extension will indicate the current + status, and comparisons to the HARD or SOFT lifetime will indicate + which limit was reached. HARD lifetimes MUST take precedence over + SOFT lifetimes, meaning if the HARD and SOFT lifetimes are the same, + the HARD lifetime will appear on the EXPIRE message. The + pathological case of HARD lifetimes being shorter than SOFT lifetimes + is handled such that the SOFT lifetime will never expire. + + The messaging behavior of the SADB_EXPIRE message is: + + The kernel sends an SADB_EXPIRE message to all listeners when + the soft limit of a security association has been expired. + + + + Note that the SADB_EXPIRE message is ONLY sent by the kernel to the + KMd. It is a one-way informational message that does not have a + reply. + + + + + + +McDonald, et. al. Informational [Page 39] + +RFC 2367 PF_KEY Key Management API July 1998 + + +3.1.9 SADB_FLUSH + + The SADB_FLUSH message causes the kernel to delete all entries in its + key table for a certain sadb_msg_satype. Only the base header is + required for a flush message. If sadb_msg_satype is filled in with a + specific value, only associations of that type are deleted. If it is + filled in with SADB_SATYPE_UNSPEC, ALL associations are deleted. + + The messaging behavior for SADB_FLUSH is: + + Send an SADB_FLUSH message from a user process to the kernel. + + + + The kernel will return an SADB_FLUSH message to all listening + sockets. + + + + The reply message happens only after the actual flushing + of security associations has been attempted. + +3.1.10 SADB_DUMP + + The SADB_DUMP message causes the kernel to dump the operating + system's entire Key Table to the requesting key socket. As in + SADB_FLUSH, if a sadb_msg_satype value is in the message, only + associations of that type will be dumped. If SADB_SATYPE_UNSPEC is + specified, all associations will be dumped. Each Security Association + is returned in its own SADB_DUMP message. A SADB_DUMP message with a + sadb_seq field of zero indicates the end of the dump transaction. The + dump message is used for debugging purposes only and is not intended + for production use. + + Support for the dump message MAY be discontinued in future versions + of PF_KEY. Key management applications MUST NOT depend on this + message for basic operation. + + The messaging behavior for SADB_DUMP is: + + Send an SADB_DUMP message from a user process to the kernel. + + + + Several SADB_DUMP messages will return from the kernel to the + sending socket. + + + + + +McDonald, et. al. Informational [Page 40] + +RFC 2367 PF_KEY Key Management API July 1998 + + + + +3.2 Security Association Flags + + The Security Association's flags are a bitmask field. These flags + also appear in a combination that is part of a PROPOSAL extension. + The related symbolic definitions below should be used in order that + applications will be portable: + + #define SADB_SAFLAGS_PFS 1 /* perfect forward secrecy */ + + The SADB_SAFLAGS_PFS flag indicates to key management that this + association should have perfect forward secrecy in its key. (In + other words, any given session key cannot be determined by + cryptanalysis of previous session keys or some master key.) + +3.3 Security Association States + + The security association state field is an integer that describes the + states of a security association. They are: + + #define SADB_SASTATE_LARVAL 0 + #define SADB_SASTATE_MATURE 1 + #define SADB_SASTATE_DYING 2 + #define SADB_SASTATE_DEAD 3 + + #define SADB_SASTATE_MAX 3 + + A SADB_SASTATE_LARVAL security association is one that was created by + the SADB_GETSPI message. A SADB_SASTATE_MATURE association is one + that was updated with the SADB_UPDATE message or added with the + SADB_ADD message. A DYING association is one whose soft lifetime has + expired. A SADB_SASTATE_DEAD association is one whose hard lifetime + has expired, but hasn't been reaped by system garbage collection. If + a consumer of security associations has to extend an association + beyond its normal lifetime (e.g. OSPF Security) it MUST only set the + soft lifetime for an association. + +3.4 Security Association Types + + This defines the type of Security Association in this message. The + symbolic names are always the same, even on different + implementations. Applications SHOULD use the symbolic name in order + to have maximum portability across different implementations. These + are defined in the file . + + + + + +McDonald, et. al. Informational [Page 41] + +RFC 2367 PF_KEY Key Management API July 1998 + + + #define SADB_SATYPE_UNSPEC 0 + + #define SADB_SATYPE_AH 2 /* RFC-1826 */ + #define SADB_SATYPE_ESP 3 /* RFC-1827 */ + + #define SADB_SATYPE_RSVP 5 /* RSVP Authentication */ + #define SADB_SATYPE_OSPFV2 6 /* OSPFv2 Authentication */ + #define SADB_SATYPE_RIPV2 7 /* RIPv2 Authentication */ + #define SADB_SATYPE_MIP 8 /* Mobile IP Auth. */ + + #define SADB_SATYPE_MAX 8 + + SADB_SATYPE_UNSPEC is defined for completeness and means no specific + type of security association. This type is never used with PF_KEY + SAs. + + SADB_SATYPE_AH is for the IP Authentication Header [Atk95b]. + + SADB_SATYPE_ESP is for the IP Encapsulating Security Payload + [Atk95c]. + + SADB_SATYPE_RSVP is for the RSVP Integrity Object. + + SADB_SATYPE_OSPFV2 is for OSPFv2 Cryptographic authentication + [Moy98]. + + SADB_SATYPE_RIPV2 is for RIPv2 Cryptographic authentication [BA97]. + + SADB_SATYPE_MIP is for Mobile IP's authentication extensions [Per97]. + + SADB_SATYPE_MAX is always set to the highest valid numeric value. + +3.5 Algorithm Types + + The algorithm type is interpreted in the context of the Security + Association type defined above. The numeric value might vary between + implementations, but the symbolic name MUST NOT vary between + implementations. Applications should use the symbolic name in order + to have maximum portability to various implementations. + + Some of the algorithm types defined below might not be standardized + or might be deprecated in the future. To obtain an assignment for a + symbolic name, contact the authors. + + The symbols below are defined in . + + + + + + +McDonald, et. al. Informational [Page 42] + +RFC 2367 PF_KEY Key Management API July 1998 + + + /* Authentication algorithms */ + #define SADB_AALG_NONE 0 + #define SADB_AALG_MD5HMAC 2 + #define SADB_AALG_SHA1HMAC 3 + #define SADB_AALG_MAX 3 + + /* Encryption algorithms */ + #define SADB_EALG_NONE 0 + #define SADB_EALG_DESCBC 2 + #define SADB_EALG_3DESCBC 3 + #define SADB_EALG_NULL 11 + #define SADB_EALG_MAX 11 + + The algorithm for SADB_AALG_MD5_HMAC is defined in [MG98a]. The + algorithm for SADB_AALG_SHA1HMAC is defined in [MG98b]. The + algorithm for SADB_EALG_DESCBC is defined in [MD98]. SADB_EALG_NULL + is the NULL encryption algorithm, defined in [GK98]. The + SADB_EALG_NONE value is not to be used in any security association + except those which have no possible encryption algorithm in them + (e.g. IPsec AH). + +3.6 Extension Header Values + + To briefly recap the extension header values: + + #define SADB_EXT_RESERVED 0 + #define SADB_EXT_SA 1 + #define SADB_EXT_LIFETIME_CURRENT 2 + #define SADB_EXT_LIFETIME_HARD 3 + #define SADB_EXT_LIFETIME_SOFT 4 + #define SADB_EXT_ADDRESS_SRC 5 + #define SADB_EXT_ADDRESS_DST 6 + #define SADB_EXT_ADDRESS_PROXY 7 + #define SADB_EXT_KEY_AUTH 8 + #define SADB_EXT_KEY_ENCRYPT 9 + #define SADB_EXT_IDENTITY_SRC 10 + #define SADB_EXT_IDENTITY_DST 11 + #define SADB_EXT_SENSITIVITY 12 + #define SADB_EXT_PROPOSAL 13 + #define SADB_EXT_SUPPORTED_AUTH 14 + #define SADB_EXT_SUPPORTED_ENCRYPT 15 + #define SADB_EXT_SPIRANGE 16 + + #define SADB_EXT_MAX 16 + + + + + + + +McDonald, et. al. Informational [Page 43] + +RFC 2367 PF_KEY Key Management API July 1998 + + +3.7 Identity Extension Values + + Each identity can have a certain type. + + #define SADB_IDENTTYPE_RESERVED 0 + #define SADB_IDENTTYPE_PREFIX 1 + #define SADB_IDENTTYPE_FQDN 2 + #define SADB_IDENTTYPE_USERFQDN 3 + + #define SADB_IDENTTYPE_MAX 3 + + The PREFIX identity string consists of a network address followed by a + forward slash and a prefix length. The network address is in a + printable numeric form appropriate for the protocol family. The + prefix length is a decimal number greater than or equal to zero and + less than the number of bits in the network address. It indicates the + number of bits in the network address that are significant; all bits + in the network address that are not significant MUST be set to zero. + Note that implementations MUST parse the contents of the printable + address into a binary form for comparison purposes because multiple + printable strings are valid representations of the same address in + many protocol families (for example, some allow leading zeros and some + have letters that are case insensitive). Examples of PREFIX identities + are "199.33.248.64/27" and "3ffe::1/128". If the source or destination + identity is a PREFIX identity, the source or destination address for + the SA (respectively) MUST be within that prefix. The sadb_ident_id + field is zeroed for these identity types. + + The FQDN identity string contains a fully qualified domain name. An + example FQDN identity is "ministry-of-truth.inner.net". The + sadb_ident_id field is zeroed for these identity types. + + The UserFQDN identity consists of a text string in the format commonly + used for Internet-standard electronic mail. The syntax is the text + username, followed by the "@" character, followed in turn by the + appropriate fully qualified domain name. This identity specifies both + a username and an associated FQDN. There is no requirement that this + string specify a mailbox valid for SMTP or other electronic mail + use. This identity is useful with protocols supporting user-oriented + keying. It is a convenient identity form because the DNS Security + extensions can be used to distribute signed public key values by + associating KEY and SIG records with an appropriate MB DNS record. An + example UserFQDN identity is "julia@ministry-of-love.inner.net". The + sadb_ident_id field is used to contain a POSIX user id in the absence + of an identity string itself so that a user-level application can use + the getpwuid{,_r}() routine to obtain a textual user login id. If a + string is present, it SHOULD match the numeric value in the + sadb_ident_id field. If it does not match, the string SHOULD override + + + +McDonald, et. al. Informational [Page 44] + +RFC 2367 PF_KEY Key Management API July 1998 + + + the numeric value. + +3.8 Sensitivity Extension Values + + The only field currently defined in the sensitivity extension is the + sadb_sens_dpd, which represents the data protection domain. The other + data in the sensitivity extension is based off the sadb_sens_dpd + value. + + The DP/DOI is defined to be the same as the "Labeled Domain Identifier + Value" of the IP Security DOI specification [Pip98]. As noted in that + specification, values in the range 0x80000000 to 0xffffffff + (inclusive) are reserved for private use and values in the range + 0x00000001 through 0x7fffffff are assigned by IANA. The all-zeros + DP/DOI value is permanently reserved to mean that "no DP/DOI is in + use". + +3.9 Proposal Extension Values + + These are already mentioned in the Algorithm Types and Security + Association Flags sections. + +4 Future Directions + + While the current specification for the Sensitivity and Integrity + Labels is believed to be general enough, if a case should arise that + can't work with the current specification then this might cause a + change in a future version of PF_KEY. + + Similarly, PF_KEY might need extensions to work with other kinds of + Security Associations in future. It is strongly desirable for such + extensions to be made in a backwards-compatible manner should they be + needed. + + When more experience is gained with certificate management, it is + possible that the IDENTITY extension will have to be revisited to + allow a finer grained selection of certificate identities. + +5. Examples + + The following examples illustrate how PF_KEY is used. The first + example is an IP Security example, where the consumer of the security + associations is inside an operating system kernel. The second example + is an OSPF Security example, which illustrates a user-level consumer + of security associations. The third example covers things not + mentioned by the first two examples. A real system may closely + conform to one of these examples, or take parts of them. These + examples are purely illustrative, and are not intended to mandate a + + + +McDonald, et. al. Informational [Page 45] + +RFC 2367 PF_KEY Key Management API July 1998 + + + particular implementation method. + +5.1 Simple IP Security Example + + +---------------+ +-------------+ + |Key Mgmt Daemon| | Application | + +---------------+ +-------------+ + | | / + | | / + | | | Applications + ======[PF_KEY]====[PF_INET]========================== + | | | OS Kernel + +------------+ +-----------------+ + | Key Engine | | TCP/IP, | + | or SADB |---| including IPsec | + +------------+ | | + +-----------------+ + + When the Key Management daemon (KMd) begins. It must tell PF_KEY + that it is willing to accept message for the two IPsec services, AH + and ESP. It does this by sending down two SADB_REGISTER messages. + + KMd->Kernel: SADB_REGISTER for ESP + Kernel->Registered: SADB_REGISTER for ESP, Supported Algorithms + KMd->Kernel: SADB_REGISTER for AH + Kernel->Registered: SADB_REGISTER for AH, Supported Algorithms + + Each REGISTER message will cause a reply to go to all PF_KEY sockets + registered for ESP and AH respectively (including the requester). + + Assume that no security associations currently exist for IPsec to + use. Consider when a network application begins transmitting data + (e.g. a TCP SYN). Because of policy, or the application's request, + the kernel IPsec module needs an AH security association for this + data. Since there is not one present, the following message is + generated: + + Kernel->Registered: SADB_ACQUIRE for AH, addrs, ID, sens, + proposals + + The KMd reads the ACQUIRE message, especially the sadb_msg_seq + number. Before it begins the negotiation, it sends down an + SADB_GETSPI message with the sadb_msg_seq number equal to the one + received in the ACQUIRE. The kernel returns the results of the + GETSPI to all listening sockets. + + KMd->Kernel: SADB_GETSPI for AH, addr, SPI range + Kernel->All: SADB_GETSPI for AH, assoc, addrs + + + +McDonald, et. al. Informational [Page 46] + +RFC 2367 PF_KEY Key Management API July 1998 + + + The KMd may perform a second GETSPI operation if it needs both + directions of IPsec SPI values. Now that the KMd has an SPI for at + least one of the security associations, it begins negotiation. After + deriving keying material, and negotiating other parameters, it sends + down one (or more) SADB_UPDATE messages with the same value in + sadb_msg_seq. + + If a KMd has any error at all during its negotiation, it can send + down: + + KMd->Kernel: SADB_ACQUIRE for AH, assoc (with an error) + Kernel->All: SADB_ACQUIRE for AH, assoc (same error) + + but if it succeeds, it can instead: + + KMd->Kernel: SADB_UPDATE for AH, assoc, addrs, keys, + + Kernel->All: SADB_UPDATE for AH, assoc, addrs, + + The results of the UPDATE (minus the actual keys) are sent to all + listening sockets. If only one SPI value was determined locally, the + other SPI (since IPsec SAs are unidirectional) must be added with an + SADB_ADD message. + + KMd->Kernel: SADB_ADD for AH, assoc, addrs, keys, + Kernel->All: SADB_ADD for AH, assoc, addrs, + + If one of the extensions passed down was a Lifetime extension, it is + possible at some point an SADB_EXPIRE message will arrive when one of + the lifetimes has expired. + + Kernel->All: SADB_EXPIRE for AH, assoc, addrs, + Hard or Soft, Current, + + The KMd can use this as a clue to begin negotiation, or, if it has + some say in policy, send an SADB_UPDATE down with a lifetime + extension. + +5.2 Proxy IP Security Example + + Many people are interested in using IP Security in a "proxy" or + "firewall" configuration in which an intermediate system provides + security services for "inside" hosts. In these environments, the + intermediate systems can use PF_KEY to communicate with key + management applications almost exactly as they would if they were the + actual endpoints. The messaging behavior of PF_KEY in these cases is + exactly the same as the previous example, but the address information + is slightly different. + + + +McDonald, et. al. Informational [Page 47] + +RFC 2367 PF_KEY Key Management API July 1998 + + + Consider this case: + + A ========= B --------- C + + Key: + A "outside" host that implements IPsec + B "firewall" that implements IPsec + C "inside" host that does not implement IPsec + + === IP_{A<->B} ESP [ IP_{A<->C} ULP ] + --- IP_{A<->C} ULP + + A is a single system that wishes to communicate with the "inside" + system C. B is a "firewall" between C and the outside world that + will do ESP and tunneling on C's behalf. A discovers that it needs + to send traffic to C via B through methods not described here (Use of + the DNS' KX record might be one method for discovering this). + + For packets that flow from left to right, A and B need an IPsec + Security Association with: + + SA type of ESP tunnel-mode + Source Identity that dominates A (e.g. A's address) + Destination Identity that dominates B (e.g. B's address) + Source Address of A + Destination Address of B + + For packets to flow from right to left, A and B need an IPsec + Security Association with: + + SA type of ESP tunnel-mode + Source Identity that dominates C + Destination Identity that dominates A + Source Address of B + Destination Address of A + Proxy Address of C + + For this second SA (for packets flowing from C towards A), node A + MUST verify that the inner source address is dominated by the Source + Identity for the SA used with those packets. If node A does not do + this, an adversary could forge packets with an arbitrary Source + Identity and defeat the packet origin protections provided by IPsec. + + Now consider a slightly more complex case: + + A_1 --| |-- D_1 + |--- B ====== C ---| + A_2 --| |-- D_2 + + + +McDonald, et. al. Informational [Page 48] + +RFC 2367 PF_KEY Key Management API July 1998 + + + Key: + A_n "inside" host on net 1 that does not do IPsec. + B "firewall" for net 1 that supports IPsec. + C "firewall" for net 2 that supports IPsec. + D_n "inside" host on net 2 that does not do IPsec. + === IP_{B<->C} ESP [ IP_{A<->C} ULP ] + --- IP_{A<->C} ULP + + For A_1 to send a packet to D_1, B and C need an SA with: + + SA Type of ESP + Source Identity that dominates A_1 + Destination Identity that dominates C + Source Address of B + Destination Address of C + Proxy Address of A_1 + + For D_1 to send a packet to A_1, C and B need an SA with: + SA Type of ESP Tunnel-mode + Source Identity that dominates D_1 + Destination Identity that dominates B + Source Address of C + Destination Address of B + Proxy Address of D_1 + + Note that A_2 and D_2 could be substituted for A_1 and D_1 + (respectively) here; the association of an SA with a particular pair + of ends or group of those pairs is a policy decision on B and/or C + and not necessarily a function of key management. The same check of + the Source Identity against the inner source IP address MUST also be + performed in this case for the same reason. + + For a more detailed discussion of the use of IP Security in complex + cases, please see [Atk97]. + + NOTE: The notion of identity domination might be unfamiliar. Let H + represent some node. Let Hn represent H's fully qualified domain + name. Let Ha represent the IP address of H. Let Hs represent the IP + subnet containing Ha. Let Hd represent a fully qualified domain + name that is a parent of the fully qualified domain name of H. Let + M be a UserFQDN identity that whose right-hand part is Hn or Ha. + + Any of M, Hn, Ha, Hs, and Hd is considered to dominate H in the + example above. Hs dominates any node having an IP address within + the IP address range represented by Hs. Hd dominates any node + having a fully qualified domain name within underneath Hd. + + + + + +McDonald, et. al. Informational [Page 49] + +RFC 2367 PF_KEY Key Management API July 1998 + + +5.3 OSPF Security Example + + +---------------+ +-------------+ + |Key Mgmt Daemon| | OSPF daemon | + +---------------+ +-------------+ + | | / / | + | /------|----+ / | + | / | +---+ | Applications + ======[PF_KEY]====[PF_INET]===========[PF_ROUTE]================ + | | | | OS Kernel + +------------+ +-----------------+ +---------+ + | Key Engine | | TCP/IP, | | Routing | + | or SADB |---| including IPsec |--| Table | + +------------+ | | +---------+ + +-----------------+ + + As in the previous examples, the KMd registers itself with the Key + Engine via PF_KEY. Even though the consumer of the security + associations is in user-space, the PF_KEY and Key Engine + implementation knows enough to store SAs and to relay messages. + + When the OSPF daemon needs to communicate securely with its peers, it + would perform an SADB_GET message and retrieve the appropriate + association: + + OSPFd->Kernel: SADB_GET of OSPF, assoc, addrs + Kernel->OSPFd: SADB_GET of OSPF, assoc, addrs, keys, + + If this GET fails, the OSPFd may need to acquire a new security + association. This interaction is as follows: + + OSPFd->Kernel: SADB_ACQUIRE of OSPF, addrs, + proposal + Kernel->Registered: SADB_ACQUIRE of OSPF, + + The KMd sees this and performs actions similar to the previous + example. One difference, however, is that when the UPDATE message + comes back, the OSPFd will then perform a GET of the updated SA to + retrieve all of its parameters. + +5.4 Miscellaneous + + Some messages work well only in system maintenance programs, for + debugging, or for auditing. In a system panic situation, such as a + detected compromise, an SADB_FLUSH message should be issued for a + particular SA type, or for ALL SA types. + + + + + +McDonald, et. al. Informational [Page 50] + +RFC 2367 PF_KEY Key Management API July 1998 + + + Program->Kernel: SADB_FLUSH for ALL + + Kernel->All: SADB_FLUSH for ALL + + Some SAs may need to be explicitly deleted, either by a KMd, or by a + system maintenance program. + + Program->Kernel: SADB_DELETE for AH, association, addrs + Kernel->All: SADB_DELETE for AH, association, addrs + + Common usage of the SADB_DUMP message is discouraged. For debugging + purposes, however, it can be quite useful. The output of a DUMP + message should be read quickly, in order to avoid socket buffer + overflows. + + Program->Kernel: SADB_DUMP for ESP + Kernel->Program: SADB_DUMP for ESP, association, + Kernel->Program: SADB_DUMP for ESP, association, + Kernel->Program: SADB_DUMP for ESP, association, + + +6 Security Considerations + + This memo discusses a method for creating, reading, modifying, and + deleting Security Associations from an operating system. Only + trusted, privileged users and processes should be able to perform any + of these operations. It is unclear whether this mechanism provides + any security when used with operating systems not having the concept + of a trusted, privileged user. + + If an unprivileged user is able to perform any of these operations, + then the operating system cannot actually provide the related + security services. If an adversary knows the keys and algorithms in + use, then cryptography cannot provide any form of protection. + + This mechanism is not a panacea, but it does provide an important + operating system component that can be useful in creating a secure + internetwork. + + Users need to understand that the quality of the security provided by + an implementation of this specification depends completely upon the + overall security of the operating system, the correctness of the + PF_KEY implementation, and upon the security and correctness of the + applications that connect to PF_KEY. It is appropriate to use high + assurance development techniques when implementing PF_KEY and the + related security association components of the operating system. + + + + + +McDonald, et. al. Informational [Page 51] + +RFC 2367 PF_KEY Key Management API July 1998 + + +Acknowledgments + + The authors of this document are listed primarily in alphabetical + order. Randall Atkinson and Ron Lee provided useful feedback on + earlier versions of this document. + + At one time or other, all of the authors worked at the Center for + High Assurance Computer Systems at the U.S. Naval Research + Laboratory. This work was sponsored by the Information Security + Program Office (PMW-161), U.S. Space and Naval Warfare Systems + Command (SPAWAR) and the Computing Systems Technology Office, Defense + Advanced Research Projects Agency (DARPA/CSTO). We really appreciate + their sponsorship of our efforts and their continued support of + PF_KEY development. Without that support, PF_KEY would not exist. + + The "CONFORMANCE and COMPLIANCE" wording was taken from [MSST98]. + + Finally, the authors would like to thank those who sent in comments + and questions on the various iterations of this document. This + specification and implementations of it are discussed on the PF_KEY + mailing list. If you would like to be added to this list, send a note + to . + +References + + [AMPMC96] Randall J. Atkinson, Daniel L. McDonald, Bao G. Phan, Craig + W. Metz, and Kenneth C. Chin, "Implementation of IPv6 in 4.4-Lite + BSD", Proceedings of the 1996 USENIX Conference, San Diego, CA, + January 1996, USENIX Association. + + [Atk95a] Atkinson, R., "IP Security Architecture", RFC 1825, August + 1995. + + [Atk95b] Atkinson, R., "IP Authentication Header", RFC 1826, August + 1995. + + [Atk95c] Atkinson, R., "IP Encapsulating Security Payload", RFC 1827, + August 1995. + + [Atk97] Atkinson, R., "Key Exchange Delegation Record for the Domain + Name System", RFC 2230, October 1997. + + [BA97] Baker, F., and R. Atkinson, "RIP-2 MD5 Authentication", RFC + 2082, January 1997. + + [Biba77] K. J. Biba, "Integrity Considerations for Secure Computer + Systems", MTR-3153, The MITRE Corporation, June 1975; ESD-TR-76-372, + April 1977. + + + +McDonald, et. al. Informational [Page 52] + +RFC 2367 PF_KEY Key Management API July 1998 + + + [BL74] D. Elliot Bell and Leonard J. LaPadula, "Secure Computer + Systems: Unified Exposition and Multics Interpretation", MTR 2997, + The MITRE Corporation, April 1974. (AD/A 020 445) + + [Bra97] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [CW87] D. D. Clark and D. R. Wilson, "A Comparison of Commercial and + Military Computer Security Policies", Proceedings of the 1987 + Symposium on Security and Privacy, pp. 184-195, IEEE Computer + Society, Washington, D.C., 1987. + + [DIA] US Defense Intelligence Agency (DIA), "Compartmented Mode + Workstation Specification", Technical Report DDS-2600-6243-87. + + [GK98] Glenn, R., and S. Kent, "The NULL Encryption Algorithm and Its + Use with IPsec", Work in Progress. + + [HM97a] Harney, H., and C. Muckenhirn, "Group Key Management Protocol + (GKMP) Specification", RFC 2093, July 1997. + + [HM97b] Harney, H., and C. Muckenhirn, "Group Key Management Protocol + (GKMP) Architecture", RFC 2094, July 1997. + + [MD98] Madsen, C., and N. Doraswamy, "The ESP DES-CBC Cipher + Algorithm With Explicit IV", Work in Progress. + + [MG98a] Madsen, C., and R. Glenn, "The Use of HMAC-MD5-96 within ESP + and AH", Work in Progress. + + [MG98b] Madsen, C., and R. Glenn, "The Use of HMAC-SHA-1-96 within + ESP and AH", Work in Progress. + + [MSST98] Maughan, D., Schertler, M., Schneider, M., and J. Turner, + "Internet Security Association and Key Management Protocol (ISAKMP)", + Work in Progress. + + [Moy98] Moy, J., "OSPF Version 2", STD 54, RFC 2328, April 1998. + + [Per97] Perkins, C., "IP Mobility Support", RFC 2002, October 1996. + + [Pip98] Piper, D., "The Internet IP Security Domain of Interpretation + for ISAKMP", Work in Progress. + + [Sch96] Bruce Schneier, Applied Cryptography, p. 360, John Wiley & + Sons, Inc., 1996. + + + + + +McDonald, et. al. Informational [Page 53] + +RFC 2367 PF_KEY Key Management API July 1998 + + + [Skl91] Keith Sklower, "A Tree-based Packet Routing Table for + Berkeley UNIX", Proceedings of the Winter 1991 USENIX Conference, + Dallas, TX, USENIX Association. 1991. pp. 93-103. + +Disclaimer + + The views and specification here are those of the editors and are not + necessarily those of their employers. The employers have not passed + judgment on the merits, if any, of this work. The editors and their + employers specifically disclaim responsibility for any problems + arising from correct or incorrect implementation or use of this + specification. + +Authors' Addresses + + Daniel L. McDonald + Sun Microsystems, Inc. + 901 San Antonio Road, MS UMPK17-202 + Palo Alto, CA 94303 + + Phone: +1 650 786 6815 + EMail: danmcd@eng.sun.com + + + Craig Metz + (for Code 5544) + U.S. Naval Research Laboratory + 4555 Overlook Ave. SW + Washington, DC 20375 + + Phone: (DSN) 754-8590 + EMail: cmetz@inner.net + + + Bao G. Phan + U. S. Naval Research Laboratory + + EMail: phan@itd.nrl.navy.mil + + + + + + + + + + + + + +McDonald, et. al. Informational [Page 54] + +RFC 2367 PF_KEY Key Management API July 1998 + + +Appendix A: Promiscuous Send/Receive Message Type + + A kernel supporting PF_KEY MAY implement the following extension for + development and debugging purposes. If it does, it MUST implement the + extension as specified here. An implementation MAY require an + application to have additional privileges to perform promiscuous send + and/or receive operations. + + The SADB_X_PROMISC message allows an application to send and receive + messages in a "promiscuous mode." There are two forms of this + message: control and data. The control form consists of only a + message header. This message is used to toggle the promiscuous- + receive function. A value of one in the sadb_msg_satype field enables + promiscuous message reception for this socket, while a value of zero + in that field disables it. + + The second form of this message is the data form. This is used to + send or receive messages in their raw form. Messages in the data form + consist of a message header followed by an entire new message. There + will be two message headers in a row: one for the SADB_X_PROMISC + message, and one for the payload message. + + Data messages sent from the application are sent to either the PF_KEY + socket of a single process identified by a nonzero sadb_msg_seq or to + all PF_KEY sockets if sadb_msg_seq is zero. These messages are sent + without any processing of their contents by the PF_KEY interface + (including sanity checking). This promiscuous-send capability allows + an application to send messages as if it were the kernel. This also + allows it to send erroneous messages. + + If the promiscuous-receive function has been enabled, a copy of any + message sent via PF_KEY by another application or by the kernel is + sent to the promiscuous application. This is done before any + processing of the message's contents by the PF_KEY interface (again, + including sanity checking). This promiscuous-receive capability + allows an application to receive all messages sent by other parties + using PF_KEY. + + The messaging behavior of the SADB_X_PROMISC message is: + + Send a control-form SADB_X_PROMISC message from a user process + to the kernel. + + + + The kernel returns the SADB_X_PROMISC message to all listening + processes. + + + + +McDonald, et. al. Informational [Page 55] + +RFC 2367 PF_KEY Key Management API July 1998 + + + + + Send a data-form SADB_X_PROMISC message from a user process to + the kernel. + + + + The kernel sends the encapsulated message to the target + process(s). + + + + If promiscuous-receive is enabled, the kernel will encapsulate + and send copies of all messages sent via the PF_KEY interface. + + + + Errors: + EPERM Additional privileges are required to perform the + requested operations. + ESRCH (Data form, sending) The target process in sadb_msg_seq + does not exist or does not have an open PF_KEY Version 2 + socket. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +McDonald, et. al. Informational [Page 56] + +RFC 2367 PF_KEY Key Management API July 1998 + + +Appendix B: Passive Change Message Type + + The SADB_X_PCHANGE message is a passive-side (aka. the "listener" or + "receiver") counterpart to the SADB_ACQUIRE message. It is useful + for when key management applications wish to more effectively handle + incoming key management requests for passive-side sessions that + deviate from systemwide default security services. If a passive + session requests that only certain levels of security service be + allowed, the SADB_X_PCHANGE message expresses this change to any + registered PF_KEY sockets. Unlike SADB_ACQUIRE, this message is + purely informational, and demands no other PF_KEY interaction. + + The SADB_X_PCHANGE message is typically triggered by either a change + in an endpoint's requested security services, or when an endpoint + that made a special request disappears. In the former case, an + SADB_X_PCHANGE looks like an SADB_ACQUIRE, complete with an + sadb_proposal extension indicating the preferred algorithms, + lifetimes, and other attributes. When a passive session either + disappears, or reverts to a default behavior, an SADB_X_PCHANGE will + be issued with _no_ sadb_proposal extension, indicating that the + exception to systemwide default behavior has disappeared. + + There are two messaging behaviors for SADB_X_PCHANGE. The first is + the kernel-originated case: + + The kernel sends an SADB_X_PCHANGE message to registered + sockets. + + + + NOTE: The address(SD) extensions MUST have the port fields + filled in with the port numbers of the session + requiring keys if appropriate. + + The second is for a user-level consumer of SAs. + + Send an SADB_X_PCHANGE message from a user process to the + kernel. + + + + The kernel returns an SADB_X_PCHANGE message to registered + sockets. + + + + + + + + +McDonald, et. al. Informational [Page 57] + +RFC 2367 PF_KEY Key Management API July 1998 + + +Appendix C: Key Management Private Data Extension + + The Key Management Private Data extension is attached to either an + SADB_ADD or an SADB_UPDATE message. It attaches a single piece of + arbitrary data to a security association. It may be useful for key + managment applications that could use an SADB_DUMP or SADB_GET + message to obtain additional state if it needs to restart or recover + after a crash. The format of this extension is: + + #define SADB_X_EXT_KMPRIVATE 17 + + struct sadb_x_kmprivate { + uint16_t sadb_x_kmprivate_len; + uint16_t sadb_x_kmprivate_exttype; + uint32_t sadb_x_kmprivate_reserved; + }; + /* sizeof(struct sadb_x_kmprivate) == 8 */ + + /* followed by arbitrary data */ + + + The data following the sadb_x_kmprivate extension can be anything. + It will be stored with the actual security association in the kernel. + Like all data, it must be padded to an eight byte boundary. + + + + + + + + + + + + + + + + + + + + + + + + + + + +McDonald, et. al. Informational [Page 58] + +RFC 2367 PF_KEY Key Management API July 1998 + + +Appendix D: Sample Header File + + /* + This file defines structures and symbols for the PF_KEY Version 2 + key management interface. It was written at the U.S. Naval Research + Laboratory. This file is in the public domain. The authors ask that + you leave this credit intact on any copies of this file. + */ + #ifndef __PFKEY_V2_H + #define __PFKEY_V2_H 1 + + #define PF_KEY_V2 2 + #define PFKEYV2_REVISION 199806L + + #define SADB_RESERVED 0 + #define SADB_GETSPI 1 + #define SADB_UPDATE 2 + #define SADB_ADD 3 + #define SADB_DELETE 4 + #define SADB_GET 5 + #define SADB_ACQUIRE 6 + #define SADB_REGISTER 7 + #define SADB_EXPIRE 8 + #define SADB_FLUSH 9 + #define SADB_DUMP 10 + #define SADB_X_PROMISC 11 + #define SADB_X_PCHANGE 12 + #define SADB_MAX 12 + + struct sadb_msg { + uint8_t sadb_msg_version; + uint8_t sadb_msg_type; + uint8_t sadb_msg_errno; + uint8_t sadb_msg_satype; + uint16_t sadb_msg_len; + uint16_t sadb_msg_reserved; + uint32_t sadb_msg_seq; + uint32_t sadb_msg_pid; + }; + + struct sadb_ext { + uint16_t sadb_ext_len; + uint16_t sadb_ext_type; + }; + + struct sadb_sa { + uint16_t sadb_sa_len; + uint16_t sadb_sa_exttype; + + + +McDonald, et. al. Informational [Page 59] + +RFC 2367 PF_KEY Key Management API July 1998 + + + uint32_t sadb_sa_spi; + uint8_t sadb_sa_replay; + uint8_t sadb_sa_state; + uint8_t sadb_sa_auth; + uint8_t sadb_sa_encrypt; + uint32_t sadb_sa_flags; + }; + + struct sadb_lifetime { + uint16_t sadb_lifetime_len; + uint16_t sadb_lifetime_exttype; + uint32_t sadb_lifetime_allocations; + uint64_t sadb_lifetime_bytes; + uint64_t sadb_lifetime_addtime; + uint64_t sadb_lifetime_usetime; + }; + + struct sadb_address { + uint16_t sadb_address_len; + uint16_t sadb_address_exttype; + uint8_t sadb_address_proto; + uint8_t sadb_address_prefixlen; + uint16_t sadb_address_reserved; + }; + + struct sadb_key { + uint16_t sadb_key_len; + uint16_t sadb_key_exttype; + uint16_t sadb_key_bits; + uint16_t sadb_key_reserved; + }; + + struct sadb_ident { + uint16_t sadb_ident_len; + uint16_t sadb_ident_exttype; + uint16_t sadb_ident_type; + uint16_t sadb_ident_reserved; + uint64_t sadb_ident_id; + }; + + struct sadb_sens { + uint16_t sadb_sens_len; + uint16_t sadb_sens_exttype; + uint32_t sadb_sens_dpd; + uint8_t sadb_sens_sens_level; + uint8_t sadb_sens_sens_len; + uint8_t sadb_sens_integ_level; + uint8_t sadb_sens_integ_len; + + + +McDonald, et. al. Informational [Page 60] + +RFC 2367 PF_KEY Key Management API July 1998 + + + uint32_t sadb_sens_reserved; + }; + + struct sadb_prop { + uint16_t sadb_prop_len; + uint16_t sadb_prop_exttype; + uint8_t sadb_prop_replay; + uint8_t sadb_prop_reserved[3]; + }; + + struct sadb_comb { + uint8_t sadb_comb_auth; + uint8_t sadb_comb_encrypt; + uint16_t sadb_comb_flags; + uint16_t sadb_comb_auth_minbits; + uint16_t sadb_comb_auth_maxbits; + uint16_t sadb_comb_encrypt_minbits; + uint16_t sadb_comb_encrypt_maxbits; + uint32_t sadb_comb_reserved; + uint32_t sadb_comb_soft_allocations; + uint32_t sadb_comb_hard_allocations; + uint64_t sadb_comb_soft_bytes; + uint64_t sadb_comb_hard_bytes; + uint64_t sadb_comb_soft_addtime; + uint64_t sadb_comb_hard_addtime; + uint64_t sadb_comb_soft_usetime; + uint64_t sadb_comb_hard_usetime; + }; + + struct sadb_supported { + uint16_t sadb_supported_len; + uint16_t sadb_supported_exttype; + uint32_t sadb_supported_reserved; + }; + + struct sadb_alg { + uint8_t sadb_alg_id; + uint8_t sadb_alg_ivlen; + uint16_t sadb_alg_minbits; + uint16_t sadb_alg_maxbits; + uint16_t sadb_alg_reserved; + }; + + struct sadb_spirange { + uint16_t sadb_spirange_len; + uint16_t sadb_spirange_exttype; + uint32_t sadb_spirange_min; + uint32_t sadb_spirange_max; + + + +McDonald, et. al. Informational [Page 61] + +RFC 2367 PF_KEY Key Management API July 1998 + + + uint32_t sadb_spirange_reserved; + }; + + struct sadb_x_kmprivate { + uint16_t sadb_x_kmprivate_len; + uint16_t sadb_x_kmprivate_exttype; + uint32_t sadb_x_kmprivate_reserved; + }; + + #define SADB_EXT_RESERVED 0 + #define SADB_EXT_SA 1 + #define SADB_EXT_LIFETIME_CURRENT 2 + #define SADB_EXT_LIFETIME_HARD 3 + #define SADB_EXT_LIFETIME_SOFT 4 + #define SADB_EXT_ADDRESS_SRC 5 + #define SADB_EXT_ADDRESS_DST 6 + #define SADB_EXT_ADDRESS_PROXY 7 + #define SADB_EXT_KEY_AUTH 8 + #define SADB_EXT_KEY_ENCRYPT 9 + #define SADB_EXT_IDENTITY_SRC 10 + #define SADB_EXT_IDENTITY_DST 11 + #define SADB_EXT_SENSITIVITY 12 + #define SADB_EXT_PROPOSAL 13 + #define SADB_EXT_SUPPORTED_AUTH 14 + #define SADB_EXT_SUPPORTED_ENCRYPT 15 + #define SADB_EXT_SPIRANGE 16 + #define SADB_X_EXT_KMPRIVATE 17 + #define SADB_EXT_MAX 17 + #define SADB_SATYPE_UNSPEC 0 + #define SADB_SATYPE_AH 2 + #define SADB_SATYPE_ESP 3 + #define SADB_SATYPE_RSVP 5 + #define SADB_SATYPE_OSPFV2 6 + #define SADB_SATYPE_RIPV2 7 + #define SADB_SATYPE_MIP 8 + #define SADB_SATYPE_MAX 8 + + #define SADB_SASTATE_LARVAL 0 + #define SADB_SASTATE_MATURE 1 + #define SADB_SASTATE_DYING 2 + #define SADB_SASTATE_DEAD 3 + #define SADB_SASTATE_MAX 3 + + #define SADB_SAFLAGS_PFS 1 + + #define SADB_AALG_NONE 0 + #define SADB_AALG_MD5HMAC 2 + #define SADB_AALG_SHA1HMAC 3 + + + +McDonald, et. al. Informational [Page 62] + +RFC 2367 PF_KEY Key Management API July 1998 + + + #define SADB_AALG_MAX 3 + + #define SADB_EALG_NONE 0 + #define SADB_EALG_DESCBC 2 + #define SADB_EALG_3DESCBC 3 + #define SADB_EALG_NULL 11 + #define SADB_EALG_MAX 11 + + #define SADB_IDENTTYPE_RESERVED 0 + #define SADB_IDENTTYPE_PREFIX 1 + #define SADB_IDENTTYPE_FQDN 2 + #define SADB_IDENTTYPE_USERFQDN 3 + #define SADB_IDENTTYPE_MAX 3 + + #define SADB_KEY_FLAGS_MAX 0 + #endif /* __PFKEY_V2_H */ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +McDonald, et. al. Informational [Page 63] + +RFC 2367 PF_KEY Key Management API July 1998 + + +Appendix E: Change Log + + The following changes were made between 05 and 06: + + * Last change before becoming an informational RFC. Removed all + Internet-Draft references. Also standardized citation strings. + Now cite RFC 2119 for MUST, etc. + + * New appendix on optional KM private data extension. + + * Fixed example to indicate the ACQUIRE messages with errno mean + KM failure. + + * Added SADB_EALG_NULL. + + * Clarified proxy examples to match definition of PROXY address being + the inner packet's source address. (Basically a sign-flip. The + example still shows how to protect against policy vulnerabilities + in tunnel endpoints.) + + * Loosened definition of a destination address to include broadcast. + + * Recommended that LARVAL security associations have implicit short + lifetimes. + + The following changes were made between 04 and 05: + + * New appendix on Passive Change message. + + * New sadb_address_prefixlen field. + + * Small clarifications on sadb_ident_id usage. + + * New PFKEYV2_REVISION value. + + * Small clarification on what a PROXY address is. + + * Corrected sadb_spirange_{min,max} language. + + * In ADD messages that are in response to an ACQUIRE, the + sadb_msg_seq MUST be the same as that of the originating ACQUIRE. + + * Corrected ACQUIRE message behavior, ACQUIRE message SHOULD send up + PROXY addresses when it needs them. + + * Clarification on SADB_EXPIRE and user-level security protocols. + + The following changes were made between 03 and 04: + + + +McDonald, et. al. Informational [Page 64] + +RFC 2367 PF_KEY Key Management API July 1998 + + + * Stronger language about manual keying. + + * PFKEYV2_REVISION, ala POSIX. + + * Put in language about sockaddr ports in ACQUIRE messages. + + * Mention of asymmetric algorithms. + + * New sadb_ident_id field for easier construction of USER_FQDN + identity strings. + + * Caveat about source addresses not always used for collision + detection. (e.g. IPsec) + + The following changes were made between 02 and 03: + + + * Formatting changes. + + * Many editorial cleanups, rewordings, clarifications. + + * Restrictions that prevent many strange and invalid cases. + + * Added definitions section. + + * Removed connection identity type (this will reappear when it is + more clear what it should look like). + + * Removed 5.2.1 (Why involve the kernel?). + + * Removed INBOUND, OUTBOUND, and FORWARD flags; they can be computed + from src, dst, and proxy and you had to anyway for sanity checking. + + * Removed REPLAY flag; sadb_sa_replay==0 means the same thing. + + * Renamed bit lengths to "bits" to avoid potential confusion. + + * Explicitly listed lengths for structures. + + * Reworked identities to always use a string format. + + * Removed requirements for support of shutdown() and SO_USELOOPBACK. + + * 64 bit alignment and 64 bit lengths instead of 32 bit. + + * time_t replaced with uint64 in lifetimes. + + + + + +McDonald, et. al. Informational [Page 65] + +RFC 2367 PF_KEY Key Management API July 1998 + + + * Inserted Appendix A (SADB_X_PROMISC) and Appendix B (SAMPLE HEADER + FILE). + + * Explicit error if PF_KEY_V2 not set at socket() call. + + * More text on SO_USELOOPBACK. + + * Made fields names and symbol names more consistent. + + * Explicit error if PF_KEY_V2 is not in sadb_msg_version field. + + * Bytes lifetime field now a 64-bit quantity. + + * Explicit len/exttype wording. + + * Flattening out of extensions (LIFETIME_HARD, LIFETIME_SOFT, etc.) + + * UI example (0x123 == 0x1230 or 0x0123). + + * Cleaned up and fixed some message behavior examples. + + The following changes were made between 01 and 02: + + * Mentioned that people COULD use these same messages between user + progs. (Also mentioned why you still might want to use the actual + socket.) + + * Various wordsmithing changes. + + * Took out netkey/ directory, and make net/pfkeyv2.h + + * Inserted PF_KEY_V2 proto argument per C. Metz. + + * Mentioned other socket calls and how their PF_KEY behavior is + undefined. + + * SADB_EXPIRE now communicates both hard and soft lifetime expires. + + * New "association" extension, even smaller base header. + + * Lifetime extension improvements. + + * Length now first in extensions. + + * Errors can be sent from kernel to user, also. + + * Examples section inserted. + + + + +McDonald, et. al. Informational [Page 66] + +RFC 2367 PF_KEY Key Management API July 1998 + + + * Some bitfield cleanups, including STATE and SA_OPTIONS cleanup. + + * Key splitting now only across auth algorithm and encryption + algorithm. Thanks for B. Sommerfeld for clues here. + + The following changes were made between 00 and 01: + + * Added this change log. + + * Simplified TLV header syntax. + + * Splitting of algorithms. This may be controversial, but it allows + PF_KEY to be used for more than just IPsec. It also allows some + kinds of policies to be placed in the KMd easier. + + * Added solid definitions and formats for certificate identities, + multiple keys, etc. + + * Specified how keys are to be layed out (most-to-least bits). + + * Changed sequence number semantics to be like an RPC transaction ID + number. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +McDonald, et. al. Informational [Page 67] + +RFC 2367 PF_KEY Key Management API July 1998 + + +F. Full Copyright Statement + + Copyright (C) The Internet Society (1998). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + + + + + + + + + + + + + + + + + + + + + + + +McDonald, et. al. Informational [Page 68] + diff --git a/crypto/dist/ipsec-tools/src/racoon/rfc/rfc2407.txt b/crypto/dist/ipsec-tools/src/racoon/rfc/rfc2407.txt new file mode 100644 index 0000000000000..7b2f87c854ca1 --- /dev/null +++ b/crypto/dist/ipsec-tools/src/racoon/rfc/rfc2407.txt @@ -0,0 +1,1795 @@ + + + + + + +Network Working Group D. Piper +Request for Comments: 2407 Network Alchemy +Category: Standards Track November 1998 + + + The Internet IP Security Domain of Interpretation for ISAKMP + +Status of this Memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (1998). All Rights Reserved. + +IESG Note + + Section 4.4.4.2 states, "All implememtations within the IPSEC DOI + MUST support ESP_DES...". Recent work in the area of cryptanalysis + suggests that DES may not be sufficiently strong for many + applications. Therefore, it is very likely that the IETF will + deprecate the use of ESP_DES as a mandatory cipher suite in the near + future. It will remain as an optional use protocol. Although the + IPsec working group and the IETF in general have not settled on an + alternative algorithm (taking into account concerns of security and + performance), implementers may want to heed the recommendations of + section 4.4.4.3 on the use of ESP_3DES. + +1. Abstract + + The Internet Security Association and Key Management Protocol + (ISAKMP) defines a framework for security association management and + cryptographic key establishment for the Internet. This framework + consists of defined exchanges, payloads, and processing guidelines + that occur within a given Domain of Interpretation (DOI). This + document defines the Internet IP Security DOI (IPSEC DOI), which + instantiates ISAKMP for use with IP when IP uses ISAKMP to negotiate + security associations. + + For a list of changes since the previous version of the IPSEC DOI, + please see Section 7. + + + + + + +Piper Standards Track [Page 1] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +2. Introduction + + Within ISAKMP, a Domain of Interpretation is used to group related + protocols using ISAKMP to negotiate security associations. Security + protocols sharing a DOI choose security protocol and cryptographic + transforms from a common namespace and share key exchange protocol + identifiers. They also share a common interpretation of DOI-specific + payload data content, including the Security Association and + Identification payloads. + + Overall, ISAKMP places the following requirements on a DOI + definition: + + o define the naming scheme for DOI-specific protocol identifiers + o define the interpretation for the Situation field + o define the set of applicable security policies + o define the syntax for DOI-specific SA Attributes (Phase II) + o define the syntax for DOI-specific payload contents + o define additional Key Exchange types, if needed + o define additional Notification Message types, if needed + + The remainder of this document details the instantiation of these + requirements for using the IP Security (IPSEC) protocols to provide + authentication, integrity, and/or confidentiality for IP packets sent + between cooperating host systems and/or firewalls. + + For a description of the overall IPSEC architecture, see [ARCH], + [AH], and [ESP]. + +3. Terms and Definitions + + The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, + SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, when they appear in this + document, are to be interpreted as described in [RFC 2119]. + +4.1 IPSEC Naming Scheme + + Within ISAKMP, all DOI's must be registered with the IANA in the + "Assigned Numbers" RFC [STD-2]. The IANA Assigned Number for the + Internet IP Security DOI (IPSEC DOI) is one (1). Within the IPSEC + DOI, all well-known identifiers MUST be registered with the IANA + under the IPSEC DOI. Unless otherwise noted, all tables within this + document refer to IANA Assigned Numbers for the IPSEC DOI. See + Section 6 for further information relating to the IANA registry for + the IPSEC DOI. + + All multi-octet binary values are stored in network byte order. + + + + +Piper Standards Track [Page 2] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +4.2 IPSEC Situation Definition + + Within ISAKMP, the Situation provides information that can be used by + the responder to make a policy determination about how to process the + incoming Security Association request. For the IPSEC DOI, the + Situation field is a four (4) octet bitmask with the following + values. + + Situation Value + --------- ----- + SIT_IDENTITY_ONLY 0x01 + SIT_SECRECY 0x02 + SIT_INTEGRITY 0x04 + +4.2.1 SIT_IDENTITY_ONLY + + The SIT_IDENTITY_ONLY type specifies that the security association + will be identified by source identity information present in an + associated Identification Payload. See Section 4.6.2 for a complete + description of the various Identification types. All IPSEC DOI + implementations MUST support SIT_IDENTITY_ONLY by including an + Identification Payload in at least one of the Phase I Oakley + exchanges ([IKE], Section 5) and MUST abort any association setup + that does not include an Identification Payload. + + If an initiator supports neither SIT_SECRECY nor SIT_INTEGRITY, the + situation consists only of the 4 octet situation bitmap and does not + include the Labeled Domain Identifier field (Figure 1, Section 4.6.1) + or any subsequent label information. Conversely, if the initiator + supports either SIT_SECRECY or SIT_INTEGRITY, the Labeled Domain + Identifier MUST be included in the situation payload. + +4.2.2 SIT_SECRECY + + The SIT_SECRECY type specifies that the security association is being + negotiated in an environment that requires labeled secrecy. If + SIT_SECRECY is present in the Situation bitmap, the Situation field + will be followed by variable-length data that includes a sensitivity + level and compartment bitmask. See Section 4.6.1 for a complete + description of the Security Association Payload format. + + If an initiator does not support SIT_SECRECY, SIT_SECRECY MUST NOT be + set in the Situation bitmap and no secrecy level or category bitmaps + shall be included. + + If a responder does not support SIT_SECRECY, a SITUATION-NOT- + SUPPORTED Notification Payload SHOULD be returned and the security + association setup MUST be aborted. + + + +Piper Standards Track [Page 3] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +4.2.3 SIT_INTEGRITY + + The SIT_INTEGRITY type specifies that the security association is + being negotiated in an environment that requires labeled integrity. + If SIT_INTEGRITY is present in the Situation bitmap, the Situation + field will be followed by variable-length data that includes an + integrity level and compartment bitmask. If SIT_SECRECY is also in + use for the association, the integrity information immediately + follows the variable-length secrecy level and categories. See + section 4.6.1 for a complete description of the Security Association + Payload format. + + If an initiator does not support SIT_INTEGRITY, SIT_INTEGRITY MUST + NOT be set in the Situation bitmap and no integrity level or category + bitmaps shall be included. + + If a responder does not support SIT_INTEGRITY, a SITUATION-NOT- + SUPPORTED Notification Payload SHOULD be returned and the security + association setup MUST be aborted. + +4.3 IPSEC Security Policy Requirements + + The IPSEC DOI does not impose specific security policy requirements + on any implementation. Host system policy issues are outside of the + scope of this document. + + However, the following sections touch on some of the issues that must + be considered when designing an IPSEC DOI host implementation. This + section should be considered only informational in nature. + +4.3.1 Key Management Issues + + It is expected that many systems choosing to implement ISAKMP will + strive to provide a protected domain of execution for a combined IKE + key management daemon. On protected-mode multiuser operating + systems, this key management daemon will likely exist as a separate + privileged process. + + In such an environment, a formalized API to introduce keying material + into the TCP/IP kernel may be desirable. The IP Security + architecture does not place any requirements for structure or flow + between a host TCP/IP kernel and its key management provider. + + + + + + + + + +Piper Standards Track [Page 4] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +4.3.2 Static Keying Issues + + Host systems that implement static keys, either for use directly by + IPSEC, or for authentication purposes (see [IKE] Section 5.4), should + take steps to protect the static keying material when it is not + residing in a protected memory domain or actively in use by the + TCP/IP kernel. + + For example, on a laptop, one might choose to store the static keys + in a configuration store that is, itself, encrypted under a private + password. + + Depending on the operating system and utility software installed, it + may not be possible to protect the static keys once they've been + loaded into the TCP/IP kernel, however they should not be trivially + recoverable on initial system startup without having to satisfy some + additional form of authentication. + +4.3.3 Host Policy Issues + + It is not realistic to assume that the transition to IPSEC will occur + overnight. Host systems must be prepared to implement flexible + policy lists that describe which systems they desire to speak + securely with and which systems they require speak securely to them. + Some notion of proxy firewall addresses may also be required. + + A minimal approach is probably a static list of IP addresses, network + masks, and a security required flag or flags. + + A more flexible implementation might consist of a list of wildcard + DNS names (e.g. '*.foo.bar'), an in/out bitmask, and an optional + firewall address. The wildcard DNS name would be used to match + incoming or outgoing IP addresses, the in/out bitmask would be used + to determine whether or not security was to be applied and in which + direction, and the optional firewall address would be used to + indicate whether or not tunnel mode would be needed to talk to the + target system though an intermediate firewall. + +4.3.4 Certificate Management + + Host systems implementing a certificate-based authentication scheme + will need a mechanism for obtaining and managing a database of + certificates. + + Secure DNS is to be one certificate distribution mechanism, however + the pervasive availability of secure DNS zones, in the short term, is + doubtful for many reasons. What's far more likely is that hosts will + + + + +Piper Standards Track [Page 5] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + need an ability to import certificates that they acquire through + secure, out-of-band mechanisms, as well as an ability to export their + own certificates for use by other systems. + + However, manual certificate management should not be done so as to + preclude the ability to introduce dynamic certificate discovery + mechanisms and/or protocols as they become available. + +4.4 IPSEC Assigned Numbers + + The following sections list the Assigned Numbers for the IPSEC DOI: + Situation Identifiers, Protocol Identifiers, Transform Identifiers, + AH, ESP, and IPCOMP Transform Identifiers, Security Association + Attribute Type Values, Labeled Domain Identifiers, ID Payload Type + Values, and Notify Message Type Values. + +4.4.1 IPSEC Security Protocol Identifier + + The ISAKMP proposal syntax was specifically designed to allow for the + simultaneous negotiation of multiple Phase II security protocol + suites within a single negotiation. As a result, the protocol suites + listed below form the set of protocols that can be negotiated at the + same time. It is a host policy decision as to what protocol suites + might be negotiated together. + + The following table lists the values for the Security Protocol + Identifiers referenced in an ISAKMP Proposal Payload for the IPSEC + DOI. + + Protocol ID Value + ----------- ----- + RESERVED 0 + PROTO_ISAKMP 1 + PROTO_IPSEC_AH 2 + PROTO_IPSEC_ESP 3 + PROTO_IPCOMP 4 + +4.4.1.1 PROTO_ISAKMP + + The PROTO_ISAKMP type specifies message protection required during + Phase I of the ISAKMP protocol. The specific protection mechanism + used for the IPSEC DOI is described in [IKE]. All implementations + within the IPSEC DOI MUST support PROTO_ISAKMP. + + NB: ISAKMP reserves the value one (1) across all DOI definitions. + + + + + + +Piper Standards Track [Page 6] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +4.4.1.2 PROTO_IPSEC_AH + + The PROTO_IPSEC_AH type specifies IP packet authentication. The + default AH transform provides data origin authentication, integrity + protection, and replay detection. For export control considerations, + confidentiality MUST NOT be provided by any PROTO_IPSEC_AH transform. + +4.4.1.3 PROTO_IPSEC_ESP + + The PROTO_IPSEC_ESP type specifies IP packet confidentiality. + Authentication, if required, must be provided as part of the ESP + transform. The default ESP transform includes data origin + authentication, integrity protection, replay detection, and + confidentiality. + +4.4.1.4 PROTO_IPCOMP + + The PROTO_IPCOMP type specifies IP payload compression as defined in + [IPCOMP]. + +4.4.2 IPSEC ISAKMP Transform Identifiers + + As part of an ISAKMP Phase I negotiation, the initiator's choice of + Key Exchange offerings is made using some host system policy + description. The actual selection of Key Exchange mechanism is made + using the standard ISAKMP Proposal Payload. The following table + lists the defined ISAKMP Phase I Transform Identifiers for the + Proposal Payload for the IPSEC DOI. + + Transform Value + --------- ----- + RESERVED 0 + KEY_IKE 1 + + Within the ISAKMP and IPSEC DOI framework it is possible to define + key establishment protocols other than IKE (Oakley). Previous + versions of this document defined types both for manual keying and + for schemes based on use of a generic Key Distribution Center (KDC). + These identifiers have been removed from the current document. + + The IPSEC DOI can still be extended later to include values for + additional non-Oakley key establishment protocols for ISAKMP and + IPSEC, such as Kerberos [RFC-1510] or the Group Key Management + Protocol (GKMP) [RFC-2093]. + + + + + + + +Piper Standards Track [Page 7] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +4.4.2.1 KEY_IKE + + The KEY_IKE type specifies the hybrid ISAKMP/Oakley Diffie-Hellman + key exchange (IKE) as defined in the [IKE] document. All + implementations within the IPSEC DOI MUST support KEY_IKE. + +4.4.3 IPSEC AH Transform Identifiers + + The Authentication Header Protocol (AH) defines one mandatory and + several optional transforms used to provide authentication, + integrity, and replay detection. The following table lists the + defined AH Transform Identifiers for the ISAKMP Proposal Payload for + the IPSEC DOI. + + Note: the Authentication Algorithm attribute MUST be specified to + identify the appropriate AH protection suite. For example, AH_MD5 + can best be thought of as a generic AH transform using MD5. To + request the HMAC construction with AH, one specifies the AH_MD5 + transform ID along with the Authentication Algorithm attribute set to + HMAC-MD5. This is shown using the "Auth(HMAC-MD5)" notation in the + following sections. + + Transform ID Value + ------------ ----- + RESERVED 0-1 + AH_MD5 2 + AH_SHA 3 + AH_DES 4 + + Note: all mandatory-to-implement algorithms are listed as "MUST" + implement (e.g. AH_MD5) in the following sections. All other + algorithms are optional and MAY be implemented in any particular + implementation. + +4.4.3.1 AH_MD5 + + The AH_MD5 type specifies a generic AH transform using MD5. The + actual protection suite is determined in concert with an associated + SA attribute list. A generic MD5 transform is currently undefined. + + All implementations within the IPSEC DOI MUST support AH_MD5 along + with the Auth(HMAC-MD5) attribute. This suite is defined as the + HMAC-MD5-96 transform described in [HMACMD5]. + + The AH_MD5 type along with the Auth(KPDK) attribute specifies the AH + transform (Key/Pad/Data/Key) described in RFC-1826. + + + + + +Piper Standards Track [Page 8] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + Use of AH_MD5 with any other Authentication Algorithm attribute value + is currently undefined. + +4.4.3.2 AH_SHA + + The AH_SHA type specifies a generic AH transform using SHA-1. The + actual protection suite is determined in concert with an associated + SA attribute list. A generic SHA transform is currently undefined. + + All implementations within the IPSEC DOI MUST support AH_SHA along + with the Auth(HMAC-SHA) attribute. This suite is defined as the + HMAC-SHA-1-96 transform described in [HMACSHA]. + + Use of AH_SHA with any other Authentication Algorithm attribute value + is currently undefined. + +4.4.3.3 AH_DES + + The AH_DES type specifies a generic AH transform using DES. The + actual protection suite is determined in concert with an associated + SA attribute list. A generic DES transform is currently undefined. + + The IPSEC DOI defines AH_DES along with the Auth(DES-MAC) attribute + to be a DES-MAC transform. Implementations are not required to + support this mode. + + Use of AH_DES with any other Authentication Algorithm attribute value + is currently undefined. + +4.4.4 IPSEC ESP Transform Identifiers + + The Encapsulating Security Payload (ESP) defines one mandatory and + many optional transforms used to provide data confidentiality. The + following table lists the defined ESP Transform Identifiers for the + ISAKMP Proposal Payload for the IPSEC DOI. + + Note: when authentication, integrity protection, and replay detection + are required, the Authentication Algorithm attribute MUST be + specified to identify the appropriate ESP protection suite. For + example, to request HMAC-MD5 authentication with 3DES, one specifies + the ESP_3DES transform ID with the Authentication Algorithm attribute + set to HMAC-MD5. For additional processing requirements, see Section + 4.5 (Authentication Algorithm). + + + + + + + + +Piper Standards Track [Page 9] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + Transform ID Value + ------------ ----- + RESERVED 0 + ESP_DES_IV64 1 + ESP_DES 2 + ESP_3DES 3 + ESP_RC5 4 + ESP_IDEA 5 + ESP_CAST 6 + ESP_BLOWFISH 7 + ESP_3IDEA 8 + ESP_DES_IV32 9 + ESP_RC4 10 + ESP_NULL 11 + + Note: all mandatory-to-implement algorithms are listed as "MUST" + implement (e.g. ESP_DES) in the following sections. All other + algorithms are optional and MAY be implemented in any particular + implementation. + +4.4.4.1 ESP_DES_IV64 + + The ESP_DES_IV64 type specifies the DES-CBC transform defined in + RFC-1827 and RFC-1829 using a 64-bit IV. + +4.4.4.2 ESP_DES + + The ESP_DES type specifies a generic DES transform using DES-CBC. + The actual protection suite is determined in concert with an + associated SA attribute list. A generic transform is currently + undefined. + + All implementations within the IPSEC DOI MUST support ESP_DES along + with the Auth(HMAC-MD5) attribute. This suite is defined as the + [DES] transform, with authentication and integrity provided by HMAC + MD5 [HMACMD5]. + +4.4.4.3 ESP_3DES + + The ESP_3DES type specifies a generic triple-DES transform. The + actual protection suite is determined in concert with an associated + SA attribute list. The generic transform is currently undefined. + + All implementations within the IPSEC DOI are strongly encouraged to + support ESP_3DES along with the Auth(HMAC-MD5) attribute. This suite + is defined as the [ESPCBC] transform, with authentication and + integrity provided by HMAC MD5 [HMACMD5]. + + + + +Piper Standards Track [Page 10] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +4.4.4.4 ESP_RC5 + + The ESP_RC5 type specifies the RC5 transform defined in [ESPCBC]. + +4.4.4.5 ESP_IDEA + + The ESP_IDEA type specifies the IDEA transform defined in [ESPCBC]. + +4.4.4.6 ESP_CAST + + The ESP_CAST type specifies the CAST transform defined in [ESPCBC]. + +4.4.4.7 ESP_BLOWFISH + + The ESP_BLOWFISH type specifies the BLOWFISH transform defined in + [ESPCBC]. + +4.4.4.8 ESP_3IDEA + + The ESP_3IDEA type is reserved for triple-IDEA. + +4.4.4.9 ESP_DES_IV32 + + The ESP_DES_IV32 type specifies the DES-CBC transform defined in + RFC-1827 and RFC-1829 using a 32-bit IV. + +4.4.4.10 ESP_RC4 + + The ESP_RC4 type is reserved for RC4. + +4.4.4.11 ESP_NULL + + The ESP_NULL type specifies no confidentiality is to be provided by + ESP. ESP_NULL is used when ESP is being used to tunnel packets which + require only authentication, integrity protection, and replay + detection. + + All implementations within the IPSEC DOI MUST support ESP_NULL. The + ESP NULL transform is defined in [ESPNULL]. See the Authentication + Algorithm attribute description in Section 4.5 for additional + requirements relating to the use of ESP_NULL. + +4.4.5 IPSEC IPCOMP Transform Identifiers + + The IP Compression (IPCOMP) transforms define optional compression + algorithms that can be negotiated to provide for IP payload + compression ([IPCOMP]). The following table lists the defined IPCOMP + Transform Identifiers for the ISAKMP Proposal Payload within the + + + +Piper Standards Track [Page 11] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + IPSEC DOI. + + Transform ID Value + ------------ ----- + RESERVED 0 + IPCOMP_OUI 1 + IPCOMP_DEFLATE 2 + IPCOMP_LZS 3 + +4.4.5.1 IPCOMP_OUI + + The IPCOMP_OUI type specifies a proprietary compression transform. + The IPCOMP_OUI type must be accompanied by an attribute which further + identifies the specific vendor algorithm. + +4.4.5.2 IPCOMP_DEFLATE + + The IPCOMP_DEFLATE type specifies the use of the "zlib" deflate + algorithm as specified in [DEFLATE]. + +4.4.5.3 IPCOMP_LZS + + The IPCOMP_LZS type specifies the use of the Stac Electronics LZS + algorithm as specified in [LZS]. + +4.5 IPSEC Security Association Attributes + + The following SA attribute definitions are used in Phase II of an IKE + negotiation. Attribute types can be either Basic (B) or Variable- + Length (V). Encoding of these attributes is defined in the base + ISAKMP specification. + + Attributes described as basic MUST NOT be encoded as variable. + Variable length attributes MAY be encoded as basic attributes if + their value can fit into two octets. See [IKE] for further + information on attribute encoding in the IPSEC DOI. All restrictions + listed in [IKE] also apply to the IPSEC DOI. + + + + + + + + + + + + + + +Piper Standards Track [Page 12] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + Attribute Types + + class value type + ------------------------------------------------- + SA Life Type 1 B + SA Life Duration 2 V + Group Description 3 B + Encapsulation Mode 4 B + Authentication Algorithm 5 B + Key Length 6 B + Key Rounds 7 B + Compress Dictionary Size 8 B + Compress Private Algorithm 9 V + + Class Values + + SA Life Type + SA Duration + + Specifies the time-to-live for the overall security + association. When the SA expires, all keys negotiated under + the association (AH or ESP) must be renegotiated. The life + type values are: + + RESERVED 0 + seconds 1 + kilobytes 2 + + Values 3-61439 are reserved to IANA. Values 61440-65535 are + for private use. For a given Life Type, the value of the + Life Duration attribute defines the actual length of the + component lifetime -- either a number of seconds, or a number + of Kbytes that can be protected. + + If unspecified, the default value shall be assumed to be + 28800 seconds (8 hours). + + An SA Life Duration attribute MUST always follow an SA Life + Type which describes the units of duration. + + See Section 4.5.4 for additional information relating to + lifetime notification. + + Group Description + + Specifies the Oakley Group to be used in a PFS QM + negotiation. For a list of supported values, see Appendix A + of [IKE]. + + + +Piper Standards Track [Page 13] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + Encapsulation Mode + RESERVED 0 + Tunnel 1 + Transport 2 + + Values 3-61439 are reserved to IANA. Values 61440-65535 are + for private use. + + If unspecified, the default value shall be assumed to be + unspecified (host-dependent). + + Authentication Algorithm + RESERVED 0 + HMAC-MD5 1 + HMAC-SHA 2 + DES-MAC 3 + KPDK 4 + + Values 5-61439 are reserved to IANA. Values 61440-65535 are + for private use. + + There is no default value for Auth Algorithm, as it must be + specified to correctly identify the applicable AH or ESP + transform, except in the following case. + + 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. + + Key Length + RESERVED 0 + + There is no default value for Key Length, as it must be + specified for transforms using ciphers with variable key + lengths. For fixed length ciphers, the Key Length attribute + MUST NOT be sent. + + Key Rounds + RESERVED 0 + + There is no default value for Key Rounds, as it must be + specified for transforms using ciphers with varying numbers + of rounds. + + + + + +Piper Standards Track [Page 14] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + Compression Dictionary Size + RESERVED 0 + + Specifies the log2 maximum size of the dictionary. + + There is no default value for dictionary size. + + Compression Private Algorithm + + Specifies a private vendor compression algorithm. The first + three (3) octets must be an IEEE assigned company_id (OUI). + The next octet may be a vendor specific compression subtype, + followed by zero or more octets of vendor data. + +4.5.1 Required Attribute Support + + To ensure basic interoperability, all implementations MUST be + prepared to negotiate all of the following attributes. + + SA Life Type + SA Duration + Auth Algorithm + +4.5.2 Attribute Parsing Requirement (Lifetime) + + To allow for flexible semantics, the IPSEC DOI requires that a + conforming ISAKMP implementation MUST correctly parse an attribute + list that contains multiple instances of the same attribute class, so + long as the different attribute entries do not conflict with one + another. Currently, the only attributes which requires this + treatment are Life Type and Duration. + + To see why this is important, the following example shows the binary + encoding of a four entry attribute list that specifies an SA Lifetime + of either 100MB or 24 hours. (See Section 3.3 of [ISAKMP] for a + complete description of the attribute encoding format.) + + Attribute #1: + 0x80010001 (AF = 1, type = SA Life Type, value = seconds) + + Attribute #2: + 0x00020004 (AF = 0, type = SA Duration, length = 4 bytes) + 0x00015180 (value = 0x15180 = 86400 seconds = 24 hours) + + Attribute #3: + 0x80010002 (AF = 1, type = SA Life Type, value = KB) + + + + + +Piper Standards Track [Page 15] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + Attribute #4: + 0x00020004 (AF = 0, type = SA Duration, length = 4 bytes) + 0x000186A0 (value = 0x186A0 = 100000KB = 100MB) + + If conflicting attributes are detected, an ATTRIBUTES-NOT-SUPPORTED + Notification Payload SHOULD be returned and the security association + setup MUST be aborted. + +4.5.3 Attribute Negotiation + + If an implementation receives a defined IPSEC DOI attribute (or + attribute value) which it does not support, an ATTRIBUTES-NOT-SUPPORT + SHOULD be sent and the security association setup MUST be aborted, + unless the attribute value is in the reserved range. + + If an implementation receives an attribute value in the reserved + range, an implementation MAY chose to continue based on local policy. + +4.5.4 Lifetime Notification + + When an initiator offers an SA lifetime greater than what the + responder desires based on their local policy, the responder has + three choices: 1) fail the negotiation entirely; 2) complete the + negotiation but use a shorter lifetime than what was offered; 3) + complete the negotiation and send an advisory notification to the + initiator indicating the responder's true lifetime. The choice of + what the responder actually does is implementation specific and/or + based on local policy. + + To ensure interoperability in the latter case, the IPSEC DOI requires + the following only when the responder wishes to notify the initiator: + if the initiator offers an SA lifetime longer than the responder is + willing to accept, the responder SHOULD include an ISAKMP + Notification Payload in the exchange that includes the responder's + IPSEC SA payload. Section 4.6.3.1 defines the payload layout for the + RESPONDER-LIFETIME Notification Message type which MUST be used for + this purpose. + +4.6 IPSEC Payload Content + + The following sections describe those ISAKMP payloads whose data + representations are dependent on the applicable DOI. + +4.6.1 Security Association Payload + + The following diagram illustrates the content of the Security + Association Payload for the IPSEC DOI. See Section 4.2 for a + description of the Situation bitmap. + + + +Piper Standards Track [Page 16] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Domain of Interpretation (IPSEC) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Situation (bitmap) ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Labeled Domain Identifier ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Secrecy Length (in octets) ! RESERVED ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ~ Secrecy Level ~ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Secrecy Cat. Length (in bits) ! RESERVED ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ~ Secrecy Category Bitmap ~ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Integrity Length (in octets) ! RESERVED ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ~ Integrity Level ~ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Integ. Cat. Length (in bits) ! RESERVED ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ~ Integrity Category Bitmap ~ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 1: Security Association Payload Format + + The Security Association Payload is defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of + the next payload in the message. If the current payload is the + last in the message, this field will be zero (0). + + o RESERVED (1 octet) - Unused, must be zero (0). + + o Payload Length (2 octets) - Length, in octets, of the current + payload, including the generic header. + + o Domain of Interpretation (4 octets) - Specifies the IPSEC DOI, + which has been assigned the value one (1). + + o Situation (4 octets) - Bitmask used to interpret the remainder + of the Security Association Payload. See Section 4.2 for a + complete list of values. + + + + + +Piper Standards Track [Page 17] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + o Labeled Domain Identifier (4 octets) - IANA Assigned Number used + to interpret the Secrecy and Integrity information. + + o Secrecy Length (2 octets) - Specifies the length, in octets, of + the secrecy level identifier, excluding pad bits. + + o RESERVED (2 octets) - Unused, must be zero (0). + + o Secrecy Level (variable length) - Specifies the mandatory + secrecy level required. The secrecy level MUST be padded with + zero (0) to align on the next 32-bit boundary. + + o Secrecy Category Length (2 octets) - Specifies the length, in + bits, of the secrecy category (compartment) bitmap, excluding + pad bits. + + o RESERVED (2 octets) - Unused, must be zero (0). + + o Secrecy Category Bitmap (variable length) - A bitmap used to + designate secrecy categories (compartments) that are required. + The bitmap MUST be padded with zero (0) to align on the next + 32-bit boundary. + + o Integrity Length (2 octets) - Specifies the length, in octets, + of the integrity level identifier, excluding pad bits. + + o RESERVED (2 octets) - Unused, must be zero (0). + + o Integrity Level (variable length) - Specifies the mandatory + integrity level required. The integrity level MUST be padded + with zero (0) to align on the next 32-bit boundary. + + o Integrity Category Length (2 octets) - Specifies the length, in + bits, of the integrity category (compartment) bitmap, excluding + pad bits. + + o RESERVED (2 octets) - Unused, must be zero (0). + + o Integrity Category Bitmap (variable length) - A bitmap used to + designate integrity categories (compartments) that are required. + The bitmap MUST be padded with zero (0) to align on the next + 32-bit boundary. + +4.6.1.1 IPSEC Labeled Domain Identifiers + + The following table lists the assigned values for the Labeled Domain + Identifier field contained in the Situation field of the Security + Association Payload. + + + +Piper Standards Track [Page 18] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + Domain Value + ------- ----- + RESERVED 0 + +4.6.2 Identification Payload Content + + The Identification Payload is used to identify the initiator of the + Security Association. The identity of the initiator SHOULD be used + by the responder to determine the correct host system security policy + requirement for the association. For example, a host might choose to + require authentication and integrity without confidentiality (AH) + from a certain set of IP addresses and full authentication with + confidentiality (ESP) from another range of IP addresses. The + Identification Payload provides information that can be used by the + responder to make this decision. + + During Phase I negotiations, the ID port and protocol fields MUST be + set to zero or to UDP port 500. If an implementation receives any + other values, this MUST be treated as an error and the security + association setup MUST be aborted. This event SHOULD be auditable. + + The following diagram illustrates the content of the Identification + Payload. + + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ID Type ! Protocol ID ! Port ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ~ Identification Data ~ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 2: Identification Payload Format + + The Identification Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of + the next payload in the message. If the current payload is the + last in the message, this field will be zero (0). + + o RESERVED (1 octet) - Unused, must be zero (0). + + o Payload Length (2 octets) - Length, in octets, of the + identification data, including the generic header. + + o Identification Type (1 octet) - Value describing the identity + information found in the Identification Data field. + + + +Piper Standards Track [Page 19] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + o Protocol ID (1 octet) - Value specifying an associated IP + protocol ID (e.g. UDP/TCP). A value of zero means that the + Protocol ID field should be ignored. + + o Port (2 octets) - Value specifying an associated port. A value + of zero means that the Port field should be ignored. + + o Identification Data (variable length) - Value, as indicated by + the Identification Type. + +4.6.2.1 Identification Type Values + + The following table lists the assigned values for the Identification + Type field found in the Identification Payload. + + ID Type Value + ------- ----- + RESERVED 0 + ID_IPV4_ADDR 1 + ID_FQDN 2 + ID_USER_FQDN 3 + ID_IPV4_ADDR_SUBNET 4 + ID_IPV6_ADDR 5 + ID_IPV6_ADDR_SUBNET 6 + ID_IPV4_ADDR_RANGE 7 + ID_IPV6_ADDR_RANGE 8 + ID_DER_ASN1_DN 9 + ID_DER_ASN1_GN 10 + ID_KEY_ID 11 + + For types where the ID entity is variable length, the size of the ID + entity is computed from size in the ID payload header. + + When an IKE exchange is authenticated using certificates (of any + format), any ID's used for input to local policy decisions SHOULD be + contained in the certificate used in the authentication of the + exchange. + +4.6.2.2 ID_IPV4_ADDR + + The ID_IPV4_ADDR type specifies a single four (4) octet IPv4 address. + +4.6.2.3 ID_FQDN + + The ID_FQDN type specifies a fully-qualified domain name string. An + example of a ID_FQDN is, "foo.bar.com". The string should not + contain any terminators. + + + + +Piper Standards Track [Page 20] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +4.6.2.4 ID_USER_FQDN + + The ID_USER_FQDN type specifies a fully-qualified username string, An + example of a ID_USER_FQDN is, "piper@foo.bar.com". The string should + not contain any terminators. + +4.6.2.5 ID_IPV4_ADDR_SUBNET + + The ID_IPV4_ADDR_SUBNET type specifies a range of IPv4 addresses, + represented by two four (4) octet values. The first value is an IPv4 + address. The second is an IPv4 network mask. Note that ones (1s) in + the network mask indicate that the corresponding bit in the address + is fixed, while zeros (0s) indicate a "wildcard" bit. + +4.6.2.6 ID_IPV6_ADDR + + The ID_IPV6_ADDR type specifies a single sixteen (16) octet IPv6 + address. + +4.6.2.7 ID_IPV6_ADDR_SUBNET + + The ID_IPV6_ADDR_SUBNET type specifies a range of IPv6 addresses, + represented by two sixteen (16) octet values. The first value is an + IPv6 address. The second is an IPv6 network mask. Note that ones + (1s) in the network mask indicate that the corresponding bit in the + address is fixed, while zeros (0s) indicate a "wildcard" bit. + +4.6.2.8 ID_IPV4_ADDR_RANGE + + The ID_IPV4_ADDR_RANGE type specifies a range of IPv4 addresses, + represented by two four (4) octet values. The first value is the + beginning IPv4 address (inclusive) and the second value is the ending + IPv4 address (inclusive). All addresses falling between the two + specified addresses are considered to be within the list. + +4.6.2.9 ID_IPV6_ADDR_RANGE + + The ID_IPV6_ADDR_RANGE type specifies a range of IPv6 addresses, + represented by two sixteen (16) octet values. The first value is the + beginning IPv6 address (inclusive) and the second value is the ending + IPv6 address (inclusive). All addresses falling between the two + specified addresses are considered to be within the list. + +4.6.2.10 ID_DER_ASN1_DN + + The ID_DER_ASN1_DN type specifies the binary DER encoding of an ASN.1 + X.500 Distinguished Name [X.501] of the principal whose certificates + are being exchanged to establish the SA. + + + +Piper Standards Track [Page 21] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +4.6.2.11 ID_DER_ASN1_GN + + The ID_DER_ASN1_GN type specifies the binary DER encoding of an ASN.1 + X.500 GeneralName [X.509] of the principal whose certificates are + being exchanged to establish the SA. + +4.6.2.12 ID_KEY_ID + + The ID_KEY_ID type specifies an opaque byte stream which may be used + to pass vendor-specific information necessary to identify which pre- + shared key should be used to authenticate Aggressive mode + negotiations. + +4.6.3 IPSEC Notify Message Types + + ISAKMP defines two blocks of Notify Message codes, one for errors and + one for status messages. ISAKMP also allocates a portion of each + block for private use within a DOI. The IPSEC DOI defines the + following private message types for its own use. + + Notify Messages - Error Types Value + ----------------------------- ----- + RESERVED 8192 + + Notify Messages - Status Types Value + ------------------------------ ----- + RESPONDER-LIFETIME 24576 + REPLAY-STATUS 24577 + INITIAL-CONTACT 24578 + + Notification Status Messages MUST be sent under the protection of an + ISAKMP SA: either as a payload in the last Main Mode exchange; in a + separate Informational Exchange after Main Mode or Aggressive Mode + processing is complete; or as a payload in any Quick Mode exchange. + These messages MUST NOT be sent in Aggressive Mode exchange, since + Aggressive Mode does not provide the necessary protection to bind the + Notify Status Message to the exchange. + + Nota Bene: a Notify payload is fully protected only in Quick Mode, + where the entire payload is included in the HASH(n) digest. In Main + Mode, while the notify payload is encrypted, it is not currently + included in the HASH(n) digests. As a result, an active substitution + attack on the Main Mode ciphertext could cause the notify status + message type to be corrupted. (This is true, in general, for the + last message of any Main Mode exchange.) While the risk is small, a + corrupt notify message might cause the receiver to abort the entire + negotiation thinking that the sender encountered a fatal error. + + + + +Piper Standards Track [Page 22] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + Implementation Note: the ISAKMP protocol does not guarantee delivery + of Notification Status messages when sent in an ISAKMP Informational + Exchange. To ensure receipt of any particular message, the sender + SHOULD include a Notification Payload in a defined Main Mode or Quick + Mode exchange which is protected by a retransmission timer. + +4.6.3.1 RESPONDER-LIFETIME + + The RESPONDER-LIFETIME status message may be used to communicate the + IPSEC SA lifetime chosen by the responder. + + When present, the Notification Payload MUST have the following + format: + + o Payload Length - set to length of payload + size of data (var) + o DOI - set to IPSEC DOI (1) + o Protocol ID - set to selected Protocol ID from chosen SA + o SPI Size - set to either sixteen (16) (two eight-octet ISAKMP + cookies) or four (4) (one IPSEC SPI) + o Notify Message Type - set to RESPONDER-LIFETIME (Section 4.6.3) + o SPI - set to the two ISAKMP cookies or to the sender's inbound + IPSEC SPI + o Notification Data - contains an ISAKMP attribute list with the + responder's actual SA lifetime(s) + + Implementation Note: saying that the Notification Data field contains + an attribute list is equivalent to saying that the Notification Data + field has zero length and the Notification Payload has an associated + attribute list. + +4.6.3.2 REPLAY-STATUS + + The REPLAY-STATUS status message may be used for positive + confirmation of the responder's election on whether or not he is to + perform anti-replay detection. + + When present, the Notification Payload MUST have the following + format: + + o Payload Length - set to length of payload + size of data (4) + o DOI - set to IPSEC DOI (1) + o Protocol ID - set to selected Protocol ID from chosen SA + o SPI Size - set to either sixteen (16) (two eight-octet ISAKMP + cookies) or four (4) (one IPSEC SPI) + o Notify Message Type - set to REPLAY-STATUS + o SPI - set to the two ISAKMP cookies or to the sender's inbound + IPSEC SPI + o Notification Data - a 4 octet value: + + + +Piper Standards Track [Page 23] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + 0 = replay detection disabled + 1 = replay detection enabled + +4.6.3.3 INITIAL-CONTACT + + The INITIAL-CONTACT status message may be used when one side wishes + to inform the other that this is the first SA being established with + the remote system. The receiver of this Notification Message might + then elect to delete any existing SA's it has for the sending system + under the assumption that the sending system has rebooted and no + longer has access to the original SA's and their associated keying + material. When used, the content of the Notification Data field + SHOULD be null (i.e. the Payload Length should be set to the fixed + length of Notification Payload). + + When present, the Notification Payload MUST have the following + format: + + o Payload Length - set to length of payload + size of data (0) + o DOI - set to IPSEC DOI (1) + o Protocol ID - set to selected Protocol ID from chosen SA + o SPI Size - set to sixteen (16) (two eight-octet ISAKMP cookies) + o Notify Message Type - set to INITIAL-CONTACT + o SPI - set to the two ISAKMP cookies + o Notification Data - + +4.7 IPSEC Key Exchange Requirements + + The IPSEC DOI introduces no additional Key Exchange types. + +5. Security Considerations + + This entire memo pertains to the Internet Key Exchange protocol + ([IKE]), which combines ISAKMP ([ISAKMP]) and Oakley ([OAKLEY]) to + provide for the derivation of cryptographic keying material in a + secure and authenticated manner. Specific discussion of the various + security protocols and transforms identified in this document can be + found in the associated base documents and in the cipher references. + +6. IANA Considerations + + This document contains many "magic" numbers to be maintained by the + IANA. This section explains the criteria to be used by the IANA to + assign additional numbers in each of these lists. All values not + explicitly defined in previous sections are reserved to IANA. + + + + + + +Piper Standards Track [Page 24] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +6.1 IPSEC Situation Definition + + The Situation Definition is a 32-bit bitmask which represents the + environment under which the IPSEC SA proposal and negotiation is + carried out. Requests for assignments of new situations must be + accompanied by an RFC which describes the interpretation for the + associated bit. + + If the RFC is not on the standards-track (i.e., it is an + informational or experimental RFC), it must be explicitly reviewed + and approved by the IESG before the RFC is published and the + transform identifier is assigned. + + The upper two bits are reserved for private use amongst cooperating + systems. + +6.2 IPSEC Security Protocol Identifiers + + The Security Protocol Identifier is an 8-bit value which identifies a + security protocol suite being negotiated. Requests for assignments + of new security protocol identifiers must be accompanied by an RFC + which describes the requested security protocol. [AH] and [ESP] are + examples of security protocol documents. + + If the RFC is not on the standards-track (i.e., it is an + informational or experimental RFC), it must be explicitly reviewed + and approved by the IESG before the RFC is published and the + transform identifier is assigned. + + The values 249-255 are reserved for private use amongst cooperating + systems. + +6.3 IPSEC ISAKMP Transform Identifiers + + The IPSEC ISAKMP Transform Identifier is an 8-bit value which + identifies a key exchange protocol to be used for the negotiation. + Requests for assignments of new ISAKMP transform identifiers must be + accompanied by an RFC which describes the requested key exchange + protocol. [IKE] is an example of one such document. + + If the RFC is not on the standards-track (i.e., it is an + informational or experimental RFC), it must be explicitly reviewed + and approved by the IESG before the RFC is published and the + transform identifier is assigned. + + The values 249-255 are reserved for private use amongst cooperating + systems. + + + + +Piper Standards Track [Page 25] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +6.4 IPSEC AH Transform Identifiers + + The IPSEC AH Transform Identifier is an 8-bit value which identifies + a particular algorithm to be used to provide integrity protection for + AH. Requests for assignments of new AH transform identifiers must be + accompanied by an RFC which describes how to use the algorithm within + the AH framework ([AH]). + + If the RFC is not on the standards-track (i.e., it is an + informational or experimental RFC), it must be explicitly reviewed + and approved by the IESG before the RFC is published and the + transform identifier is assigned. + + The values 249-255 are reserved for private use amongst cooperating + systems. + +6.5 IPSEC ESP Transform Identifiers + + The IPSEC ESP Transform Identifier is an 8-bit value which identifies + a particular algorithm to be used to provide secrecy protection for + ESP. Requests for assignments of new ESP transform identifiers must + be accompanied by an RFC which describes how to use the algorithm + within the ESP framework ([ESP]). + + If the RFC is not on the standards-track (i.e., it is an + informational or experimental RFC), it must be explicitly reviewed + and approved by the IESG before the RFC is published and the + transform identifier is assigned. + + The values 249-255 are reserved for private use amongst cooperating + systems. + +6.6 IPSEC IPCOMP Transform Identifiers + + The IPSEC IPCOMP Transform Identifier is an 8-bit value which + identifier a particular algorithm to be used to provide IP-level + compression before ESP. Requests for assignments of new IPCOMP + transform identifiers must be accompanied by an RFC which describes + how to use the algorithm within the IPCOMP framework ([IPCOMP]). In + addition, the requested algorithm must be published and in the public + domain. + + If the RFC is not on the standards-track (i.e., it is an + informational or experimental RFC), it must be explicitly reviewed + and approved by the IESG before the RFC is published and the + transform identifier is assigned. + + + + + +Piper Standards Track [Page 26] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + The values 1-47 are reserved for algorithms for which an RFC has been + approved for publication. The values 48-63 are reserved for private + use amongst cooperating systems. The values 64-255 are reserved for + future expansion. + +6.7 IPSEC Security Association Attributes + + The IPSEC Security Association Attribute consists of a 16-bit type + and its associated value. IPSEC SA attributes are used to pass + miscellaneous values between ISAKMP peers. Requests for assignments + of new IPSEC SA attributes must be accompanied by an Internet Draft + which describes the attribute encoding (Basic/Variable-Length) and + its legal values. Section 4.5 of this document provides an example + of such a description. + + The values 32001-32767 are reserved for private use amongst + cooperating systems. + +6.8 IPSEC Labeled Domain Identifiers + + The IPSEC Labeled Domain Identifier is a 32-bit value which + identifies a namespace in which the Secrecy and Integrity levels and + categories values are said to exist. Requests for assignments of new + IPSEC Labeled Domain Identifiers should be granted on demand. No + accompanying documentation is required, though Internet Drafts are + encouraged when appropriate. + + The values 0x80000000-0xffffffff are reserved for private use amongst + cooperating systems. + +6.9 IPSEC Identification Type + + The IPSEC Identification Type is an 8-bit value which is used as a + discriminant for interpretation of the variable-length Identification + Payload. Requests for assignments of new IPSEC Identification Types + must be accompanied by an RFC which describes how to use the + identification type within IPSEC. + + If the RFC is not on the standards-track (i.e., it is an + informational or experimental RFC), it must be explicitly reviewed + and approved by the IESG before the RFC is published and the + transform identifier is assigned. + + The values 249-255 are reserved for private use amongst cooperating + systems. + + + + + + +Piper Standards Track [Page 27] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +6.10 IPSEC Notify Message Types + + The IPSEC Notify Message Type is a 16-bit value taken from the range + of values reserved by ISAKMP for each DOI. There is one range for + error messages (8192-16383) and a different range for status messages + (24576-32767). Requests for assignments of new Notify Message Types + must be accompanied by an Internet Draft which describes how to use + the identification type within IPSEC. + + The values 16001-16383 and the values 32001-32767 are reserved for + private use amongst cooperating systems. + +7. Change Log + +7.1 Changes from V9 + + o add explicit reference to [IPCOMP], [DEFLATE], and [LZS] + o allow RESPONDER-LIFETIME and REPLAY-STATUS to be directed + at an IPSEC SPI in addition to the ISAKMP "SPI" + o added padding exclusion to Secrecy and Integrity Length text + o added forward reference to Section 4.5 in Section 4.4.4 + o update document references + +7.2 Changes from V8 + + o update IPCOMP identifier range to better reflect IPCOMP draft + o update IANA considerations per Jeff/Ted's suggested text + o eliminate references to DES-MAC ID ([DESMAC]) + o correct bug in Notify section; ISAKMP Notify values are 16-bits + +7.3 Changes from V7 + + o corrected name of IPCOMP (IP Payload Compression) + o corrected references to [ESPCBC] + o added missing Secrecy Level and Integrity Level to Figure 1 + o removed ID references to PF_KEY and ARCFOUR + o updated Basic/Variable text to align with [IKE] + o updated document references and add intro pointer to [ARCH] + o updated Notification requirements; remove aggressive reference + o added clarification about protection for Notify payloads + o restored RESERVED to ESP transform ID namespace; moved ESP_NULL + o added requirement for ESP_NULL support and [ESPNULL] reference + o added clarification on Auth Alg use with AH/ESP + o added restriction against using conflicting AH/Auth combinations + +7.4 Changes from V6 + + The following changes were made relative to the IPSEC DOI V6: + + + +Piper Standards Track [Page 28] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + o added IANA Considerations section + o moved most IANA numbers to IANA Considerations section + o added prohibition on sending (V) encoding for (B) attributes + o added prohibition on sending Key Length attribute for fixed + length ciphers (e.g. DES) + o replaced references to ISAKMP/Oakley with IKE + o renamed ESP_ARCFOUR to ESP_RC4 + o updated Security Considerations section + o updated document references + +7.5 Changes from V5 + + The following changes were made relative to the IPSEC DOI V5: + + o changed SPI size in Lifetime Notification text + o changed REPLAY-ENABLED to REPLAY-STATUS + o moved RESPONDER-LIFETIME payload definition from Section 4.5.4 + to Section 4.6.3.1 + o added explicit payload layout for 4.6.3.3 + o added Implementation Note to Section 4.6.3 introduction + o changed AH_SHA text to require SHA-1 in addition to MD5 + o updated document references + +7.6 Changes from V4 + + The following changes were made relative to the IPSEC DOI V4: + + o moved compatibility AH KPDK authentication method from AH + transform ID to Authentication Algorithm identifier + o added REPLAY-ENABLED notification message type per Architecture + o added INITIAL-CONTACT notification message type per list + o added text to ensure protection for Notify Status messages + o added Lifetime qualification to attribute parsing section + o added clarification that Lifetime notification is optional + o removed private Group Description list (now points at [IKE]) + o replaced Terminology with pointer to RFC-2119 + o updated HMAC MD5 and SHA-1 ID references + o updated Section 1 (Abstract) + o updated Section 4.4 (IPSEC Assigned Numbers) + o added restriction for ID port/protocol values for Phase I + +7.7 Changes from V3 to V4 + + The following changes were made relative to the IPSEC DOI V3, that + was posted to the IPSEC mailing list prior to the Munich IETF: + + o added ESP transform identifiers for NULL and ARCFOUR + + + + +Piper Standards Track [Page 29] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + o renamed HMAC Algorithm to Auth Algorithm to accommodate + DES-MAC and optional authentication/integrity for ESP + o added AH and ESP DES-MAC algorithm identifiers + o removed KEY_MANUAL and KEY_KDC identifier definitions + o added lifetime duration MUST follow lifetype attribute to + SA Life Type and SA Life Duration attribute definition + o added lifetime notification and IPSEC DOI message type table + o added optional authentication and confidentiality + restrictions to MAC Algorithm attribute definition + o corrected attribute parsing example (used obsolete attribute) + o corrected several Internet Draft document references + o added ID_KEY_ID per ipsec list discussion (18-Mar-97) + o removed Group Description default for PFS QM ([IKE] MUST) + +Acknowledgments + + This document is derived, in part, from previous works by Douglas + Maughan, Mark Schertler, Mark Schneider, Jeff Turner, Dan Harkins, + and Dave Carrel. Matt Thomas, Roy Pereira, Greg Carter, and Ran + Atkinson also contributed suggestions and, in many cases, text. + +References + + [AH] Kent, S., and R. Atkinson, "IP Authentication Header", RFC + 2402, November 1998. + + [ARCH] Kent, S., and R. Atkinson, "Security Architecture for the + Internet Protocol", RFC 2401, November 1998. + + [DEFLATE] Pereira, R., "IP Payload Compression Using DEFLATE", RFC + 2394, August 1998. + + [ESP] Kent, S., and R. Atkinson, "IP Encapsulating Security + Payload (ESP)", RFC 2406, November 1998. + + [ESPCBC] Pereira, R., and R. Adams, "The ESP CBC-Mode Cipher + Algorithms", RFC 2451, November 1998. + + [ESPNULL] Glenn, R., and S. Kent, "The NULL Encryption Algorithm and + Its Use With IPsec", RFC 2410, November 1998. + + [DES] Madson, C., and N. Doraswamy, "The ESP DES-CBC Cipher + Algorithm With Explicit IV", RFC 2405, November 1998. + + [HMACMD5] Madson, C., and R. Glenn, "The Use of HMAC-MD5 within ESP + and AH", RFC 2403, November 1998. + + + + + +Piper Standards Track [Page 30] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + + [HMACSHA] Madson, C., and R. Glenn, "The Use of HMAC-SHA-1-96 within + ESP and AH", RFC 2404, November 1998. + + [IKE] Harkins, D., and D. Carrel, D., "The Internet Key Exchange + (IKE)", RFC 2409, November 1998. + + [IPCOMP] Shacham, A., Monsour, R., Pereira, R., and M. Thomas, "IP + Payload Compression Protocol (IPComp)", RFC 2393, August + 1998. + + [ISAKMP] Maughan, D., Schertler, M., Schneider, M., and J. Turner, + "Internet Security Association and Key Management Protocol + (ISAKMP)", RFC 2408, November 1998. + + [LZS] Friend, R., and R. Monsour, "IP Payload Compression Using + LZS", RFC 2395, August 1998. + + [OAKLEY] Orman, H., "The OAKLEY Key Determination Protocol", RFC + 2412, November 1998. + + [X.501] ISO/IEC 9594-2, "Information Technology - Open Systems + Interconnection - The Directory: Models", CCITT/ITU + Recommendation X.501, 1993. + + [X.509] ISO/IEC 9594-8, "Information Technology - Open Systems + Interconnection - The Directory: Authentication + Framework", CCITT/ITU Recommendation X.509, 1993. + +Author's Address + + Derrell Piper + Network Alchemy + 1521.5 Pacific Ave + Santa Cruz, California, 95060 + United States of America + + Phone: +1 408 460-3822 + EMail: ddp@network-alchemy.com + + + + + + + + + + + + + +Piper Standards Track [Page 31] + +RFC 2407 IP Security Domain of Interpretation November 1998 + + +Full Copyright Statement + + Copyright (C) The Internet Society (1998). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + + + + + + + + + + + + + + + + + + + + + + + +Piper Standards Track [Page 32] + diff --git a/crypto/dist/ipsec-tools/src/racoon/rfc/rfc2408.txt b/crypto/dist/ipsec-tools/src/racoon/rfc/rfc2408.txt new file mode 100644 index 0000000000000..c3af56268c9ca --- /dev/null +++ b/crypto/dist/ipsec-tools/src/racoon/rfc/rfc2408.txt @@ -0,0 +1,4819 @@ + + + + + + +Network Working Group D. Maughan +Request for Comments: 2408 National Security Agency +Category: Standards Track M. Schertler + Securify, Inc. + M. Schneider + National Security Agency + J. Turner + RABA Technologies, Inc. + November 1998 + + + Internet Security Association and Key Management Protocol (ISAKMP) + +Status of this Memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (1998). All Rights Reserved. + +Abstract + + This memo describes a protocol utilizing security concepts necessary + for establishing Security Associations (SA) and cryptographic keys in + an Internet environment. A Security Association protocol that + negotiates, establishes, modifies and deletes Security Associations + and their attributes is required for an evolving Internet, where + there will be numerous security mechanisms and several options for + each security mechanism. The key management protocol must be robust + in order to handle public key generation for the Internet community + at large and private key requirements for those private networks with + that requirement. The Internet Security Association and Key + Management Protocol (ISAKMP) defines the procedures for + authenticating a communicating peer, creation and management of + Security Associations, key generation techniques, and threat + mitigation (e.g. denial of service and replay attacks). All of + these are necessary to establish and maintain secure communications + (via IP Security Service or any other security protocol) in an + Internet environment. + + + + + + + +Maughan, et. al. Standards Track [Page 1] + +RFC 2408 ISAKMP November 1998 + + +Table of Contents + + 1 Introduction 4 + 1.1 Requirements Terminology . . . . . . . . . . . . . . . . . 5 + 1.2 The Need for Negotiation . . . . . . . . . . . . . . . . . 5 + 1.3 What can be Negotiated? . . . . . . . . . . . . . . . . . 6 + 1.4 Security Associations and Management . . . . . . . . . . . 7 + 1.4.1 Security Associations and Registration . . . . . . . . 7 + 1.4.2 ISAKMP Requirements . . . . . . . . . . . . . . . . . 8 + 1.5 Authentication . . . . . . . . . . . . . . . . . . . . . . 8 + 1.5.1 Certificate Authorities . . . . . . . . . . . . . . . 9 + 1.5.2 Entity Naming . . . . . . . . . . . . . . . . . . . . 9 + 1.5.3 ISAKMP Requirements . . . . . . . . . . . . . . . . . 10 + 1.6 Public Key Cryptography . . . . . . . . . . . . . . . . . . 10 + 1.6.1 Key Exchange Properties . . . . . . . . . . . . . . . 11 + 1.6.2 ISAKMP Requirements . . . . . . . . . . . . . . . . . 12 + 1.7 ISAKMP Protection . . . . . . . . . . . . . . . . . . . . . 12 + 1.7.1 Anti-Clogging (Denial of Service) . . . . . . . . . . 12 + 1.7.2 Connection Hijacking . . . . . . . . . . . . . . . . . 13 + 1.7.3 Man-in-the-Middle Attacks . . . . . . . . . . . . . . 13 + 1.8 Multicast Communications . . . . . . . . . . . . . . . . . 13 + 2 Terminology and Concepts 14 + 2.1 ISAKMP Terminology . . . . . . . . . . . . . . . . . . . . 14 + 2.2 ISAKMP Placement . . . . . . . . . . . . . . . . . . . . . 16 + 2.3 Negotiation Phases . . . . . . . . . . . . . . . . . . . . 16 + 2.4 Identifying Security Associations . . . . . . . . . . . . . 17 + 2.5 Miscellaneous . . . . . . . . . . . . . . . . . . . . . . . 20 + 2.5.1 Transport Protocol . . . . . . . . . . . . . . . . . . 20 + 2.5.2 RESERVED Fields . . . . . . . . . . . . . . . . . . . 20 + 2.5.3 Anti-Clogging Token ("Cookie") Creation . . . . . . . 20 + 3 ISAKMP Payloads 21 + 3.1 ISAKMP Header Format . . . . . . . . . . . . . . . . . . . 21 + 3.2 Generic Payload Header . . . . . . . . . . . . . . . . . . 25 + 3.3 Data Attributes . . . . . . . . . . . . . . . . . . . . . . 25 + 3.4 Security Association Payload . . . . . . . . . . . . . . . 27 + 3.5 Proposal Payload . . . . . . . . . . . . . . . . . . . . . 28 + 3.6 Transform Payload . . . . . . . . . . . . . . . . . . . . . 29 + 3.7 Key Exchange Payload . . . . . . . . . . . . . . . . . . . 31 + 3.8 Identification Payload . . . . . . . . . . . . . . . . . . 32 + 3.9 Certificate Payload . . . . . . . . . . . . . . . . . . . . 33 + 3.10 Certificate Request Payload . . . . . . . . . . . . . . . 34 + 3.11 Hash Payload . . . . . . . . . . . . . . . . . . . . . . 36 + 3.12 Signature Payload . . . . . . . . . . . . . . . . . . . . 37 + 3.13 Nonce Payload . . . . . . . . . . . . . . . . . . . . . . 37 + 3.14 Notification Payload . . . . . . . . . . . . . . . . . . 38 + 3.14.1 Notify Message Types . . . . . . . . . . . . . . . . 40 + 3.15 Delete Payload . . . . . . . . . . . . . . . . . . . . . 41 + 3.16 Vendor ID Payload . . . . . . . . . . . . . . . . . . . . 43 + + + +Maughan, et. al. Standards Track [Page 2] + +RFC 2408 ISAKMP November 1998 + + + 4 ISAKMP Exchanges 44 + 4.1 ISAKMP Exchange Types . . . . . . . . . . . . . . . . . . . 45 + 4.1.1 Notation . . . . . . . . . . . . . . . . . . . . . . . 46 + 4.2 Security Association Establishment . . . . . . . . . . . . 46 + 4.2.1 Security Association Establishment Examples . . . . . 48 + 4.3 Security Association Modification . . . . . . . . . . . . . 50 + 4.4 Base Exchange . . . . . . . . . . . . . . . . . . . . . . . 51 + 4.5 Identity Protection Exchange . . . . . . . . . . . . . . . 52 + 4.6 Authentication Only Exchange . . . . . . . . . . . . . . . 54 + 4.7 Aggressive Exchange . . . . . . . . . . . . . . . . . . . . 55 + 4.8 Informational Exchange . . . . . . . . . . . . . . . . . . 57 + 5 ISAKMP Payload Processing 58 + 5.1 General Message Processing . . . . . . . . . . . . . . . . 58 + 5.2 ISAKMP Header Processing . . . . . . . . . . . . . . . . . 59 + 5.3 Generic Payload Header Processing . . . . . . . . . . . . . 61 + 5.4 Security Association Payload Processing . . . . . . . . . . 62 + 5.5 Proposal Payload Processing . . . . . . . . . . . . . . . . 63 + 5.6 Transform Payload Processing . . . . . . . . . . . . . . . 64 + 5.7 Key Exchange Payload Processing . . . . . . . . . . . . . . 65 + 5.8 Identification Payload Processing . . . . . . . . . . . . . 66 + 5.9 Certificate Payload Processing . . . . . . . . . . . . . . 66 + 5.10 Certificate Request Payload Processing . . . . . . . . . 67 + 5.11 Hash Payload Processing . . . . . . . . . . . . . . . . . 69 + 5.12 Signature Payload Processing . . . . . . . . . . . . . . 69 + 5.13 Nonce Payload Processing . . . . . . . . . . . . . . . . 70 + 5.14 Notification Payload Processing . . . . . . . . . . . . . 71 + 5.15 Delete Payload Processing . . . . . . . . . . . . . . . . 73 + 6 Conclusions 75 + A ISAKMP Security Association Attributes 77 + A.1 Background/Rationale . . . . . . . . . . . . . . . . . . . 77 + A.2 Internet IP Security DOI Assigned Value . . . . . . . . . . 77 + A.3 Supported Security Protocols . . . . . . . . . . . . . . . 77 + A.4 ISAKMP Identification Type Values . . . . . . . . . . . . . 78 + A.4.1 ID_IPV4_ADDR . . . . . . . . . . . . . . . . . . . . . 78 + A.4.2 ID_IPV4_ADDR_SUBNET . . . . . . . . . . . . . . . . . . 78 + A.4.3 ID_IPV6_ADDR . . . . . . . . . . . . . . . . . . . . . 78 + A.4.4 ID_IPV6_ADDR_SUBNET . . . . . . . . . . . . . . . . . 78 + B Defining a new Domain of Interpretation 79 + B.1 Situation . . . . . . . . . . . . . . . . . . . . . . . . . 79 + B.2 Security Policies . . . . . . . . . . . . . . . . . . . . . 80 + B.3 Naming Schemes . . . . . . . . . . . . . . . . . . . . . . 80 + B.4 Syntax for Specifying Security Services . . . . . . . . . . 80 + B.5 Payload Specification . . . . . . . . . . . . . . . . . . . 80 + B.6 Defining new Exchange Types . . . . . . . . . . . . . . . . 80 + Security Considerations 81 + IANA Considerations 81 + Domain of Interpretation 81 + Supported Security Protocols 82 + + + +Maughan, et. al. Standards Track [Page 3] + +RFC 2408 ISAKMP November 1998 + + + Acknowledgements 82 + References 82 + Authors' Addresses 85 + Full Copyright Statement 86 + +List of Figures + + 1 ISAKMP Relationships . . . . . . . . . . . . . . . . . . . 16 + 2 ISAKMP Header Format . . . . . . . . . . . . . . . . . . . 22 + 3 Generic Payload Header . . . . . . . . . . . . . . . . . . 25 + 4 Data Attributes . . . . . . . . . . . . . . . . . . . . . . 26 + 5 Security Association Payload . . . . . . . . . . . . . . . 27 + 6 Proposal Payload Format . . . . . . . . . . . . . . . . . . 28 + 7 Transform Payload Format . . . . . . . . . . . . . . . . . 30 + 8 Key Exchange Payload Format . . . . . . . . . . . . . . . . 31 + 9 Identification Payload Format . . . . . . . . . . . . . . . 32 + 10 Certificate Payload Format . . . . . . . . . . . . . . . . 33 + 11 Certificate Request Payload Format . . . . . . . . . . . . 34 + 12 Hash Payload Format . . . . . . . . . . . . . . . . . . . . 36 + 13 Signature Payload Format . . . . . . . . . . . . . . . . . 37 + 14 Nonce Payload Format . . . . . . . . . . . . . . . . . . . 38 + 15 Notification Payload Format . . . . . . . . . . . . . . . . 39 + 16 Delete Payload Format . . . . . . . . . . . . . . . . . . . 42 + 17 Vendor ID Payload Format . . . . . . . . . . . . . . . . . 44 + +1 Introduction + + This document describes an Internet Security Association and Key + Management Protocol (ISAKMP). ISAKMP combines the security concepts + of authentication, key management, and security associations to + establish the required security for government, commercial, and + private communications on the Internet. + + The Internet Security Association and Key Management Protocol + (ISAKMP) defines procedures and packet formats to establish, + negotiate, modify and delete Security Associations (SA). SAs contain + all the information required for execution of various network + security services, such as the IP layer services (such as header + authentication and payload encapsulation), transport or application + layer services, or self-protection of negotiation traffic. ISAKMP + defines payloads for exchanging key generation and authentication + data. These formats provide a consistent framework for transferring + key and authentication data which is independent of the key + generation technique, encryption algorithm and authentication + mechanism. + + + + + + +Maughan, et. al. Standards Track [Page 4] + +RFC 2408 ISAKMP November 1998 + + + ISAKMP is distinct from key exchange protocols in order to cleanly + separate the details of security association management (and key + management) from the details of key exchange. There may be many + different key exchange protocols, each with different security + properties. However, a common framework is required for agreeing to + the format of SA attributes, and for negotiating, modifying, and + deleting SAs. ISAKMP serves as this common framework. + + Separating the functionality into three parts adds complexity to the + security analysis of a complete ISAKMP implementation. However, the + separation is critical for interoperability between systems with + differing security requirements, and should also simplify the + analysis of further evolution of a ISAKMP server. + + ISAKMP is intended to support the negotiation of SAs for security + protocols at all layers of the network stack (e.g., IPSEC, TLS, TLSP, + OSPF, etc.). By centralizing the management of the security + associations, ISAKMP reduces the amount of duplicated functionality + within each security protocol. ISAKMP can also reduce connection + setup time, by negotiating a whole stack of services at once. + + The remainder of section 1 establishes the motivation for security + negotiation and outlines the major components of ISAKMP, i.e. + Security Associations and Management, Authentication, Public Key + Cryptography, and Miscellaneous items. Section 2 presents the + terminology and concepts associated with ISAKMP. Section 3 describes + the different ISAKMP payload formats. Section 4 describes how the + payloads of ISAKMP are composed together as exchange types to + establish security associations and perform key exchanges in an + authenticated manner. Additionally, security association + modification, deletion, and error notification are discussed. + Section 5 describes the processing of each payload within the context + of ISAKMP exchanges, including error handling and associated actions. + The appendices provide the attribute values necessary for ISAKMP and + requirement for defining a new Domain of Interpretation (DOI) within + ISAKMP. + +1.1 Requirements Terminology + + The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, + SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, when they appear in this + document, are to be interpreted as described in [RFC-2119]. + +1.2 The Need for Negotiation + + ISAKMP extends the assertion in [DOW92] that authentication and key + exchanges must be combined for better security to include security + association exchanges. The security services required for + + + +Maughan, et. al. Standards Track [Page 5] + +RFC 2408 ISAKMP November 1998 + + + communications depends on the individual network configurations and + environments. Organizations are setting up Virtual Private Networks + (VPN), also known as Intranets, that will require one set of security + functions for communications within the VPN and possibly many + different security functions for communications outside the VPN to + support geographically separate organizational components, customers, + suppliers, sub-contractors (with their own VPNs), government, and + others. Departments within large organizations may require a number + of security associations to separate and protect data (e.g. + personnel data, company proprietary data, medical) on internal + networks and other security associations to communicate within the + same department. Nomadic users wanting to "phone home" represent + another set of security requirements. These requirements must be + tempered with bandwidth challenges. Smaller groups of people may + meet their security requirements by setting up "Webs of Trust". + ISAKMP exchanges provide these assorted networking communities the + ability to present peers with the security functionality that the + user supports in an authenticated and protected manner for agreement + upon a common set of security attributes, i.e. an interoperable + security association. + +1.3 What can be Negotiated? + + Security associations must support different encryption algorithms, + authentication mechanisms, and key establishment algorithms for other + security protocols, as well as IP Security. Security associations + must also support host-oriented certificates for lower layer + protocols and user- oriented certificates for higher level protocols. + Algorithm and mechanism independence is required in applications such + as e-mail, remote login, and file transfer, as well as in session + oriented protocols, routing protocols, and link layer protocols. + ISAKMP provides a common security association and key establishment + protocol for this wide range of security protocols, applications, + security requirements, and network environments. + + ISAKMP is not bound to any specific cryptographic algorithm, key + generation technique, or security mechanism. This flexibility is + beneficial for a number of reasons. First, it supports the dynamic + communications environment described above. Second, the independence + from specific security mechanisms and algorithms provides a forward + migration path to better mechanisms and algorithms. When improved + security mechanisms are developed or new attacks against current + encryption algorithms, authentication mechanisms and key exchanges + are discovered, ISAKMP will allow the updating of the algorithms and + mechanisms without having to develop a completely new KMP or patch + the current one. + + + + + +Maughan, et. al. Standards Track [Page 6] + +RFC 2408 ISAKMP November 1998 + + + ISAKMP has basic requirements for its authentication and key exchange + components. These requirements guard against denial of service, + replay / reflection, man-in-the-middle, and connection hijacking + attacks. This is important because these are the types of attacks + that are targeted against protocols. Complete Security Association + (SA) support, which provides mechanism and algorithm independence, + and protection from protocol threats are the strengths of ISAKMP. + +1.4 Security Associations and Management + + A Security Association (SA) is a relationship between two or more + entities that describes how the entities will utilize security + services to communicate securely. This relationship is represented + by a set of information that can be considered a contract between the + entities. The information must be agreed upon and shared between all + the entities. Sometimes the information alone is referred to as an + SA, but this is just a physical instantiation of the existing + relationship. The existence of this relationship, represented by the + information, is what provides the agreed upon security information + needed by entities to securely interoperate. All entities must + adhere to the SA for secure communications to be possible. When + accessing SA attributes, entities use a pointer or identifier refered + to as the Security Parameter Index (SPI). [SEC-ARCH] provides details + on IP Security Associations (SA) and Security Parameter Index (SPI) + definitions. + +1.4.1 Security Associations and Registration + + The SA attributes required and recommended for the IP Security (AH, + ESP) are defined in [SEC-ARCH]. The attributes specified for an IP + Security SA include, but are not limited to, authentication + mechanism, cryptographic algorithm, algorithm mode, key length, and + Initialization Vector (IV). Other protocols that provide algorithm + and mechanism independent security MUST define their requirements for + SA attributes. The separation of ISAKMP from a specific SA + definition is important to ensure ISAKMP can es tablish SAs for all + possible security protocols and applications. + + NOTE: See [IPDOI] for a discussion of SA attributes that should be + considered when defining a security protocol or application. + + In order to facilitate easy identification of specific attributes + (e.g. a specific encryption algorithm) among different network + entites the attributes must be assigned identifiers and these + identifiers must be registered by a central authority. The Internet + Assigned Numbers Authority (IANA) provides this function for the + Internet. + + + + +Maughan, et. al. Standards Track [Page 7] + +RFC 2408 ISAKMP November 1998 + + +1.4.2 ISAKMP Requirements + + Security Association (SA) establishment MUST be part of the key + management protocol defined for IP based networks. The SA concept is + required to support security protocols in a diverse and dynamic + networking environment. Just as authentication and key exchange must + be linked to provide assurance that the key is established with the + authenticated party [DOW92], SA establishment must be linked with the + authentication and the key exchange protocol. + + ISAKMP provides the protocol exchanges to establish a security + association between negotiating entities followed by the + establishment of a security association by these negotiating entities + in behalf of some protocol (e.g. ESP/AH). First, an initial protocol + exchange allows a basic set of security attributes to be agreed upon. + This basic set provides protection for subsequent ISAKMP exchanges. + It also indicates the authentication method and key exchange that + will be performed as part of the ISAKMP protocol. If a basic set of + security attributes is already in place between the negotiating + server entities, the initial ISAKMP exchange may be skipped and the + establishment of a security association can be done directly. After + the basic set of security attributes has been agreed upon, initial + identity authenticated, and required keys generated, the established + SA can be used for subsequent communications by the entity that + invoked ISAKMP. The basic set of SA attributes that MUST be + implemented to provide ISAKMP interoperability are defined in + Appendix A. + +1.5 Authentication + + A very important step in establishing secure network communications + is authentication of the entity at the other end of the + communication. Many authentication mechanisms are available. + Authentication mechanisms fall into two catagories of strength - weak + and strong. Sending cleartext keys or other unprotected + authenticating information over a network is weak, due to the threat + of reading them with a network sniffer. Additionally, sending one- + way hashed poorly-chosen keys with low entropy is also weak, due to + the threat of brute-force guessing attacks on the sniffed messages. + While passwords can be used for establishing identity, they are not + considered in this context because of recent statements from the + Internet Architecture Board [IAB]. Digital signatures, such as the + Digital Signature Standard (DSS) and the Rivest-Shamir-Adleman (RSA) + signature, are public key based strong authentication mechanisms. + When using public key digital signatures each entity requires a + public key and a private key. Certificates are an essential part of + a digital signature authentication mechanism. Certificates bind a + specific entity's identity (be it host, network, user, or + + + +Maughan, et. al. Standards Track [Page 8] + +RFC 2408 ISAKMP November 1998 + + + application) to its public keys and possibly other security-related + information such as privileges, clearances, and compartments. + Authentication based on digital signatures requires a trusted third + party or certificate authority to create, sign and properly + distribute certificates. For more detailed information on digital + signatures, such as DSS and RSA, and certificates see [Schneier]. + +1.5.1 Certificate Authorities + + Certificates require an infrastructure for generation, verification, + revocation, management and distribution. The Internet Policy + Registration Authority (IPRA) [RFC-1422] has been established to + direct this infrastructure for the IETF. The IPRA certifies Policy + Certification Authorities (PCA). PCAs control Certificate Authorities + (CA) which certify users and subordinate entities. Current + certificate related work includes the Domain Name System (DNS) + Security Extensions [DNSSEC] which will provide signed entity keys in + the DNS. The Public Key Infrastucture (PKIX) working group is + specifying an Internet profile for X.509 certificates. There is also + work going on in industry to develop X.500 Directory Services which + would provide X.509 certificates to users. The U.S. Post Office is + developing a (CA) hierarchy. The NIST Public Key Infrastructure + Working Group has also been doing work in this area. The DOD Multi + Level Information System Security Initiative (MISSI) program has + begun deploying a certificate infrastructure for the U.S. Government. + Alternatively, if no infrastructure exists, the PGP Web of Trust + certificates can be used to provide user authentication and privacy + in a community of users who know and trust each other. + +1.5.2 Entity Naming + + An entity's name is its identity and is bound to its public keys in + certificates. The CA MUST define the naming semantics for the + certificates it issues. See the UNINETT PCA Policy Statements + [Berge] for an example of how a CA defines its naming policy. When + the certificate is verified, the name is verified and that name will + have meaning within the realm of that CA. An example is the DNS + security extensions which make DNS servers CAs for the zones and + nodes they serve. Resource records are provided for public keys and + signatures on those keys. The names associated with the keys are IP + addresses and domain names which have meaning to entities accessing + the DNS for this information. A Web of Trust is another example. + When webs of trust are set up, names are bound with the public keys. + In PGP the name is usually the entity's e-mail address which has + meaning to those, and only those, who understand e-mail. Another web + of trust could use an entirely different naming scheme. + + + + + +Maughan, et. al. Standards Track [Page 9] + +RFC 2408 ISAKMP November 1998 + + +1.5.3 ISAKMP Requirements + + Strong authentication MUST be provided on ISAKMP exchanges. Without + being able to authenticate the entity at the other end, the Security + Association (SA) and session key established are suspect. Without + authentication you are unable to trust an entity's identification, + which makes access control questionable. While encryption (e.g. + ESP) and integrity (e.g. AH) will protect subsequent communications + from passive eavesdroppers, without authentication it is possible + that the SA and key may have been established with an adversary who + performed an active man-in-the-middle attack and is now stealing all + your personal data. + + A digital signature algorithm MUST be used within ISAKMP's + authentication component. However, ISAKMP does not mandate a + specific signature algorithm or certificate authority (CA). ISAKMP + allows an entity initiating communications to indicate which CAs it + supports. After selection of a CA, the protocol provides the + messages required to support the actual authentication exchange. The + protocol provides a facility for identification of different + certificate authorities, certificate types (e.g. X.509, PKCS #7, + PGP, DNS SIG and KEY records), and the exchange of the certificates + identified. + + ISAKMP utilizes digital signatures, based on public key cryptography, + for authentication. There are other strong authentication systems + available, which could be specified as additional optional + authentication mechanisms for ISAKMP. Some of these authentication + systems rely on a trusted third party called a key distribution + center (KDC) to distribute secret session keys. An example is + Kerberos, where the trusted third party is the Kerberos server, which + holds secret keys for all clients and servers within its network + domain. A client's proof that it holds its secret key provides + authenticaton to a server. + + The ISAKMP specification does not specify the protocol for + communicating with the trusted third parties (TTP) or certificate + directory services. These protocols are defined by the TTP and + directory service themselves and are outside the scope of this + specification. The use of these additional services and protocols + will be described in a Key Exchange specific document. + +1.6 Public Key Cryptography + + Public key cryptography is the most flexible, scalable, and efficient + way for users to obtain the shared secrets and session keys needed to + support the large number of ways Internet users will interoperate. + Many key generation algorithms, that have different properties, are + + + +Maughan, et. al. Standards Track [Page 10] + +RFC 2408 ISAKMP November 1998 + + + available to users (see [DOW92], [ANSI], and [Oakley]). Properties + of key exchange protocols include the key establishment method, + authentication, symmetry, perfect forward secrecy, and back traffic + protection. + + NOTE: Cryptographic keys can protect information for a considerable + length of time. However, this is based on the assumption that keys + used for protection of communications are destroyed after use and not + kept for any reason. + +1.6.1 Key Exchange Properties + + Key Establishment (Key Generation / Key Transport): The two common + methods of using public key cryptography for key establishment are + key transport and key generation. An example of key transport is the + use of the RSA algorithm to encrypt a randomly generated session key + (for encrypting subsequent communications) with the recipient's + public key. The encrypted random key is then sent to the recipient, + who decrypts it using his private key. At this point both sides have + the same session key, however it was created based on input from only + one side of the communications. The benefit of the key transport + method is that it has less computational overhead than the following + method. The Diffie-Hellman (D-H) algorithm illustrates key + generation using public key cryptography. The D-H algorithm is begun + by two users exchanging public information. Each user then + mathematically combines the other's public information along with + their own secret information to compute a shared secret value. This + secret value can be used as a session key or as a key encryption key + for encrypting a randomly generated session key. This method + generates a session key based on public and secret information held + by both users. The benefit of the D-H algorithm is that the key used + for encrypting messages is based on information held by both users + and the independence of keys from one key exchange to another + provides perfect forward secrecy. Detailed descriptions of these + algorithms can be found in [Schneier]. There are a number of + variations on these two key generation schemes and these variations + do not necessarily interoperate. + + Key Exchange Authentication: Key exchanges may be authenticated + during the protocol or after protocol completion. Authentication of + the key exchange during the protocol is provided when each party + provides proof it has the secret session key before the end of the + protocol. Proof can be provided by encrypting known data in the + secret session key during the protocol echange. Authentication after + the protocol must occur in subsequent commu nications. + Authentication during the protocol is preferred so subsequent + communications are not initiated if the secret session key is not + established with the desired party. + + + +Maughan, et. al. Standards Track [Page 11] + +RFC 2408 ISAKMP November 1998 + + + Key Exchange Symmetry: A key exchange provides symmetry if either + party can initiate the exchange and exchanged messages can cross in + transit without affecting the key that is generated. This is + desirable so that computation of the keys does not require either + party to know who initated the exchange. While key exchange symmetry + is desirable, symmetry in the entire key management protocol may + provide a vulnerablity to reflection attacks. + + Perfect Forward Secrecy: As described in [DOW92], an authenticated + key exchange protocol provides perfect forward secrecy if disclosure + of longterm secret keying material does not compromise the secrecy of + the exchanged keys from previous communications. The property of + perfect forward secrecy does not apply to key exchange without + authentication. + +1.6.2 ISAKMP Requirements + + An authenticated key exchange MUST be supported by ISAKMP. Users + SHOULD choose additional key establishment algorithms based on their + requirements. ISAKMP does not specify a specific key exchange. + However, [IKE] describes a proposal for using the Oakley key exchange + [Oakley] in conjunction with ISAKMP. Requirements that should be + evaluated when choosing a key establishment algorithm include + establishment method (generation vs. transport), perfect forward + secrecy, computational overhead, key escrow, and key strength. Based + on user requirements, ISAKMP allows an entity initiating + communications to indicate which key exchanges it supports. After + selection of a key exchange, the protocol provides the messages + required to support the actual key establishment. + +1.7 ISAKMP Protection + +1.7.1 Anti-Clogging (Denial of Service) + + Of the numerous security services available, protection against + denial of service always seems to be one of the most difficult to + address. A "cookie" or anti-clogging token (ACT) is aimed at + protecting the computing resources from attack without spending + excessive CPU resources to determine its authenticity. An exchange + prior to CPU-intensive public key operations can thwart some denial + of service attempts (e.g. simple flooding with bogus IP source + addresses). Absolute protection against denial of service is + impossible, but this anti-clogging token provides a technique for + making it easier to handle. The use of an anti-clogging token was + introduced by Karn and Simpson in [Karn]. + + + + + + +Maughan, et. al. Standards Track [Page 12] + +RFC 2408 ISAKMP November 1998 + + + It should be noted that in the exchanges shown in section 4, the + anticlogging mechanism should be used in conjuction with a garbage- + state collection mechanism; an attacker can still flood a server + using packets with bogus IP addresses and cause state to be created. + Such aggressive memory management techniques SHOULD be employed by + protocols using ISAKMP that do not go through an initial, anti- + clogging only phase, as was done in [Karn]. + +1.7.2 Connection Hijacking + + ISAKMP prevents connection hijacking by linking the authentication, + key exchange and security association exchanges. This linking + prevents an attacker from allowing the authentication to complete and + then jumping in and impersonating one entity to the other during the + key and security association exchanges. + +1.7.3 Man-in-the-Middle Attacks + + Man-in-the-Middle attacks include interception, insertion, deletion, + and modification of messages, reflecting messages back at the sender, + replaying old messages and redirecting messages. ISAKMP features + prevent these types of attacks from being successful. The linking of + the ISAKMP exchanges prevents the insertion of messages in the + protocol exchange. The ISAKMP protocol state machine is defined so + deleted messages will not cause a partial SA to be created, the state + machine will clear all state and return to idle. The state machine + also prevents reflection of a message from causing harm. The + requirement for a new cookie with time variant material for each new + SA establishment prevents attacks that involve replaying old + messages. The ISAKMP strong authentication requirement prevents an + SA from being established with anyone other than the intended party. + Messages may be redirected to a different destination or modified but + this will be detected and an SA will not be established. The ISAKMP + specification defines where abnormal processing has occurred and + recommends notifying the appropriate party of this abnormality. + +1.8 Multicast Communications + + It is expected that multicast communications will require the same + security services as unicast communications and may introduce the + need for additional security services. The issues of distributing + SPIs for multicast traffic are presented in [SEC-ARCH]. Multicast + security issues are also discussed in [RFC-1949] and [BC]. A future + extension to ISAKMP will support multicast key distribution. For an + introduction to the issues related to multicast security, consult the + Internet Drafts, [RFC-2094] and [RFC-2093], describing Sparta's + research in this area. + + + + +Maughan, et. al. Standards Track [Page 13] + +RFC 2408 ISAKMP November 1998 + + +2 Terminology and Concepts + +2.1 ISAKMP Terminology + + Security Protocol: A Security Protocol consists of an entity at a + single point in the network stack, performing a security service for + network communication. For example, IPSEC ESP and IPSEC AH are two + different security protocols. TLS is another example. Security + Protocols may perform more than one service, for example providing + integrity and confidentiality in one module. + + Protection Suite: A protection suite is a list of the security + services that must be applied by various security protocols. For + example, a protection suite may consist of DES encryption in IP ESP, + and keyed MD5 in IP AH. All of the protections in a suite must be + treated as a single unit. This is necessary because security + services in different security protocols can have subtle + interactions, and the effects of a suite must be analyzed and + verified as a whole. + + Security Association (SA): A Security Association is a security- + protocol- specific set of parameters that completely defines the + services and mechanisms necessary to protect traffic at that security + protocol location. These parameters can include algorithm + identifiers, modes, cryptographic keys, etc. The SA is referred to + by its associated security protocol (for example, "ISAKMP SA", "ESP + SA", "TLS SA"). + + ISAKMP SA: An SA used by the ISAKMP servers to protect their own + traffic. Sections 2.3 and 2.4 provide more details about ISAKMP SAs. + + Security Parameter Index (SPI): An identifier for a Security + Assocation, relative to some security protocol. Each security + protocol has its own "SPI-space". A (security protocol, SPI) pair + may uniquely identify an SA. The uniqueness of the SPI is + implementation dependent, but could be based per system, per + protocol, or other options. Depending on the DOI, additional + information (e.g. host address) may be necessary to identify an SA. + The DOI will also determine which SPIs (i.e. initiator's or + responder's) are sent during communication. + + Domain of Interpretation: A Domain of Interpretation (DOI) defines + payload formats, exchange types, and conventions for naming + security-relevant information such as security policies or + cryptographic algorithms and modes. A Domain of Interpretation (DOI) + identifier is used to interpret the payloads of ISAKMP payloads. A + system SHOULD support multiple Domains of Interpretation + simultaneously. The concept of a DOI is based on previous work by + + + +Maughan, et. al. Standards Track [Page 14] + +RFC 2408 ISAKMP November 1998 + + + the TSIG CIPSO Working Group, but extends beyond security label + interpretation to include naming and interpretation of security + services. A DOI defines: + + o A "situation": the set of information that will be used to + determine the required security services. + + o The set of security policies that must, and may, be supported. + + o A syntax for the specification of proposed security services. + + o A scheme for naming security-relevant information, including + encryption algorithms, key exchange algorithms, security policy + attributes, and certificate authorities. + + o The specific formats of the various payload contents. + + o Additional exchange types, if required. + + The rules for the IETF IP Security DOI are presented in [IPDOI]. + Specifications of the rules for customized DOIs will be presented in + separate documents. + + Situation: A situation contains all of the security-relevant + information that a system considers necessary to decide the security + services required to protect the session being negotiated. The + situation may include addresses, security classifications, modes of + operation (normal vs. emergency), etc. + + Proposal: A proposal is a list, in decreasing order of preference, of + the protection suites that a system considers acceptable to protect + traffic under a given situation. + + Payload: ISAKMP defines several types of payloads, which are used to + transfer information such as security association data, or key + exchange data, in DOI-defined formats. A payload consists of a + generic payload header and a string of octects that is opaque to + ISAKMP. ISAKMP uses DOI- specific functionality to synthesize and + interpret these payloads. Multiple payloads can be sent in a single + ISAKMP message. See section 3 for more details on the payload types, + and [IPDOI] for the formats of the IETF IP Security DOI payloads. + + Exchange Type: An exchange type is a specification of the number of + messages in an ISAKMP exchange, and the payload types that are + contained in each of those messages. Each exchange type is designed + to provide a particular set of security services, such as anonymity + of the participants, perfect forward secrecy of the keying material, + authentication of the participants, etc. Section 4.1 defines the + + + +Maughan, et. al. Standards Track [Page 15] + +RFC 2408 ISAKMP November 1998 + + + default set of ISAKMP exchange types. Other exchange types can be + added to support additional key exchanges, if required. + +2.2 ISAKMP Placement + + Figure 1 is a high level view of the placement of ISAKMP within a + system context in a network architecture. An important part of + negotiating security services is to consider the entire "stack" of + individual SAs as a unit. This is referred to as a "protection + suite". + + +------------+ +--------+ +--------------+ + ! DOI ! ! ! ! Application ! + ! Definition ! <----> ! ISAKMP ! ! Process ! + +------------+ --> ! ! !--------------! + +--------------+ ! +--------+ ! Appl Protocol! + ! Key Exchange ! ! ^ ^ +--------------+ + ! Definition !<-- ! ! ^ + +--------------+ ! ! ! + ! ! ! + !----------------! ! ! + v ! ! + +-------+ v v + ! API ! +---------------------------------------------+ + +-------+ ! Socket Layer ! + ! !---------------------------------------------! + v ! Transport Protocol (TCP / UDP) ! + +----------+ !---------------------------------------------! + ! Security ! <----> ! IP ! + ! Protocol ! !---------------------------------------------! + +----------+ ! Link Layer Protocol ! + +---------------------------------------------+ + + + Figure 1: ISAKMP Relationships + +2.3 Negotiation Phases + + ISAKMP offers two "phases" of negotiation. In the first phase, two + entities (e.g. ISAKMP servers) agree on how to protect further + negotiation traffic between themselves, establishing an ISAKMP SA. + This ISAKMP SA is then used to protect the negotiations for the + Protocol SA being requested. Two entities (e.g. ISAKMP servers) can + negotiate (and have active) multiple ISAKMP SAs. + + + + + + + +Maughan, et. al. Standards Track [Page 16] + +RFC 2408 ISAKMP November 1998 + + + The second phase of negotiation is used to establish security + associations for other security protocols. This second phase can be + used to establish many security associations. The security + associations established by ISAKMP during this phase can be used by a + security protocol to protect many message/data exchanges. + + While the two-phased approach has a higher start-up cost for most + simple scenarios, there are several reasons that it is beneficial for + most cases. + + First, entities (e.g. ISAKMP servers) can amortize the cost of the + first phase across several second phase negotiations. This allows + multiple SAs to be established between peers over time without having + to start over for each communication. + + Second, security services negotiated during the first phase provide + security properties for the second phase. For example, after the + first phase of negotiation, the encryption provided by the ISAKMP SA + can provide identity protection, potentially allowing the use of + simpler second-phase exchanges. On the other hand, if the channel + established during the first phase is not adequate to protect + identities, then the second phase must negotiate adequate security + mechanisms. + + Third, having an ISAKMP SA in place considerably reduces the cost of + ISAKMP management activity - without the "trusted path" that an + ISAKMP SA gives you, the entities (e.g. ISAKMP servers) would have + to go through a complete re-authentication for each error + notification or deletion of an SA. + + Negotiation during each phase is accomplished using ISAKMP-defined + exchanges (see section 4) or exchanges defined for a key exchange + within a DOI. + + Note that security services may be applied differently in each + negotiation phase. For example, different parties are being + authenticated during each of the phases of negotiation. During the + first phase, the parties being authenticated may be the ISAKMP + servers/hosts, while during the second phase, users or application + level programs are being authenticated. + +2.4 Identifying Security Associations + + While bootstrapping secure channels between systems, ISAKMP cannot + assume the existence of security services, and must provide some + protections for itself. Therefore, ISAKMP considers an ISAKMP + Security Association to be different than other types, and manages + ISAKMP SAs itself, in their own name space. ISAKMP uses the two + + + +Maughan, et. al. Standards Track [Page 17] + +RFC 2408 ISAKMP November 1998 + + + cookie fields in the ISAKMP header to identify ISAKMP SAs. The + Message ID in the ISAKMP Header and the SPI field in the Proposal + payload are used during SA establishment to identify the SA for other + security protocols. The interpretation of these four fields is + dependent on the operation taking place. + + The following table shows the presence or absence of several fields + during SA establishment. The following fields are necessary for + various operations associated with SA establishment: cookies in the + ISAKMP header, the ISAKMP Header Message ID field, and the SPI field + in the Proposal payload. An 'X' in the column means the value MUST + be present. An 'NA' in the column means a value in the column is Not + Applicable to the operation. + + # Operation I-Cookie R-Cookie Message ID SPI + (1) Start ISAKMP SA negotiation X 0 0 0 + (2) Respond ISAKMP SA negotiation X X 0 0 + (3) Init other SA negotiation X X X X + (4) Respond other SA negotiation X X X X + (5) Other (KE, ID, etc.) X X X/0 NA + (6) Security Protocol (ESP, AH) NA NA NA X + + In the first line (1) of the table, the initiator includes the + Initiator Cookie field in the ISAKMP Header, using the procedures + outlined in sections 2.5.3 and 3.1. + + In the second line (2) of the table, the responder includes the + Initiator and Responder Cookie fields in the ISAKMP Header, using the + procedures outlined in sections 2.5.3 and 3.1. Additional messages + may be exchanged between ISAKMP peers, depending on the ISAKMP + exchange type used during the phase 1 negotiation. Once the phase 1 + exchange is completed, the Initiator and Responder cookies are + included in the ISAKMP Header of all subsequent communications + between the ISAKMP peers. + + During phase 1 negotiations, the initiator and responder cookies + determine the ISAKMP SA. Therefore, the SPI field in the Proposal + payload is redundant and MAY be set to 0 or it MAY contain the + transmitting entity's cookie. + + In the third line (3) of the table, the initiator associates a + Message ID with the Protocols contained in the SA Proposal. This + Message ID and the initiator's SPI(s) to be associated with each + protocol in the Proposal are sent to the responder. The SPI(s) will + be used by the security protocols once the phase 2 negotiation is + completed. + + + + + +Maughan, et. al. Standards Track [Page 18] + +RFC 2408 ISAKMP November 1998 + + + In the fourth line (4) of the table, the responder includes the same + Message ID and the responder's SPI(s) to be associated with each + protocol in the accepted Proposal. This information is returned to + the initiator. + + In the fifth line (5) of the table, the initiator and responder use + the Message ID field in the ISAKMP Header to keep track of the in- + progress protocol negotiation. This is only applicable for a phase 2 + exchange and the value MUST be 0 for a phase 1 exchange because the + combined cookies identify the ISAKMP SA. The SPI field in the + Proposal payload is not applicable because the Proposal payload is + only used during the SA negotiation message exchange (steps 3 and 4). + + In the sixth line (6) of the table, the phase 2 negotiation is + complete. The security protocols use the SPI(s) to determine which + security services and mechanisms to apply to the communication + between them. The SPI value shown in the sixth line (6) is not the + SPI field in the Proposal payload, but the SPI field contained within + the security protocol header. + + During the SA establishment, a SPI MUST be generated. ISAKMP is + designed to handle variable sized SPIs. This is accomplished by + using the SPI Size field within the Proposal payload during SA + establishment. Handling of SPIs will be outlined by the DOI + specification (e.g. [IPDOI]). + + When a security association (SA) is initially established, one side + assumes the role of initiator and the other the role of responder. + Once the SA is established, both the original initiator and responder + can initiate a phase 2 negotiation with the peer entity. Thus, + ISAKMP SAs are bidirectional in nature. + + Additionally, ISAKMP allows both initiator and responder to have some + control during the negotiation process. While ISAKMP is designed to + allow an SA negotiation that includes multiple proposals, the + initiator can maintain some control by only making one proposal in + accordance with the initiator's local security policy. Once the + initiator sends a proposal containing more than one proposal (which + are sent in decreasing preference order), the initiator relinquishes + control to the responder. Once the responder is controlling the SA + establishment, the responder can make its policy take precedence over + the initiator within the context of the multiple options offered by + the initiator. This is accomplished by selecting the proposal best + suited for the responder's local security policy and returning this + selection to the initiator. + + + + + + +Maughan, et. al. Standards Track [Page 19] + +RFC 2408 ISAKMP November 1998 + + +2.5 Miscellaneous + +2.5.1 Transport Protocol + + ISAKMP can be implemented over any transport protocol or over IP + itself. Implementations MUST include send and receive capability for + ISAKMP using the User Datagram Protocol (UDP) on port 500. UDP Port + 500 has been assigned to ISAKMP by the Internet Assigned Numbers + Authority (IANA). Implementations MAY additionally support ISAKMP + over other transport protocols or over IP itself. + +2.5.2 RESERVED Fields + + The existence of RESERVED fields within ISAKMP payloads are used + strictly to preserve byte alignment. All RESERVED fields in the + ISAKMP protocol MUST be set to zero (0) when a packet is issued. The + receiver SHOULD check the RESERVED fields for a zero (0) value and + discard the packet if other values are found. + +2.5.3 Anti-Clogging Token ("Cookie") Creation + + The details of cookie generation are implementation dependent, but + MUST satisfy these basic requirements (originally stated by Phil Karn + in [Karn]): + + 1. The cookie must depend on the specific parties. This + prevents an attacker from obtaining a cookie using a real IP + address and UDP port, and then using it to swamp the victim + with Diffie-Hellman requests from randomly chosen IP + addresses or ports. + + 2. It must not be possible for anyone other than the issuing + entity to generate cookies that will be accepted by that + entity. This implies that the issuing entity must use local + secret information in the generation and subsequent + verification of a cookie. It must not be possible to deduce + this secret information from any particular cookie. + + 3. The cookie generation function must be fast to thwart + attacks intended to sabotage CPU resources. + + Karn's suggested method for creating the cookie is to perform a fast + hash (e.g. MD5) over the IP Source and Destination Address, the UDP + Source and Destination Ports and a locally generated secret random + value. ISAKMP requires that the cookie be unique for each SA + establishment to help prevent replay attacks, therefore, the date and + time MUST be added to the information hashed. The generated cookies + are placed in the ISAKMP Header (described in section 3.1) Initiator + + + +Maughan, et. al. Standards Track [Page 20] + +RFC 2408 ISAKMP November 1998 + + + and Responder cookie fields. These fields are 8 octets in length, + thus, requiring a generated cookie to be 8 octets. Notify and Delete + messages (see sections 3.14, 3.15, and 4.8) are uni-directional + transmissions and are done under the protection of an existing ISAKMP + SA, thus, not requiring the generation of a new cookie. One + exception to this is the transmission of a Notify message during a + Phase 1 exchange, prior to completing the establishment of an SA. + Sections 3.14 and 4.8 provide additional details. + +3 ISAKMP Payloads + + ISAKMP payloads provide modular building blocks for constructing + ISAKMP messages. The presence and ordering of payloads in ISAKMP is + defined by and dependent upon the Exchange Type Field located in the + ISAKMP Header (see Figure 2). The ISAKMP payload types are discussed + in sections 3.4 through 3.15. The descriptions of the ISAKMP + payloads, messages, and exchanges (see Section 4) are shown using + network octet ordering. + +3.1 ISAKMP Header Format + + An ISAKMP message has a fixed header format, shown in Figure 2, + followed by a variable number of payloads. A fixed header simplifies + parsing, providing the benefit of protocol parsing software that is + less complex and easier to implement. The fixed header contains the + information required by the protocol to maintain state, process + payloads and possibly prevent denial of service or replay attacks. + + The ISAKMP Header fields are defined as follows: + + o Initiator Cookie (8 octets) - Cookie of entity that initiated SA + establishment, SA notification, or SA deletion. + + o Responder Cookie (8 octets) - Cookie of entity that is responding + to an SA establishment request, SA notification, or SA deletion. + + + + + + + + + + + + + + + + +Maughan, et. al. Standards Track [Page 21] + +RFC 2408 ISAKMP November 1998 + + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Initiator ! + ! Cookie ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Responder ! + ! Cookie ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Message ID ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 2: ISAKMP Header Format + + o Next Payload (1 octet) - Indicates the type of the first payload + in the message. The format for each payload is defined in + sections 3.4 through 3.16. The processing for the payloads is + defined in section 5. + + + Next Payload Type Value + NONE 0 + Security Association (SA) 1 + Proposal (P) 2 + Transform (T) 3 + Key Exchange (KE) 4 + Identification (ID) 5 + Certificate (CERT) 6 + Certificate Request (CR) 7 + Hash (HASH) 8 + Signature (SIG) 9 + Nonce (NONCE) 10 + Notification (N) 11 + Delete (D) 12 + Vendor ID (VID) 13 + RESERVED 14 - 127 + Private USE 128 - 255 + + o Major Version (4 bits) - indicates the major version of the ISAKMP + protocol in use. Implementations based on this version of the + ISAKMP Internet-Draft MUST set the Major Version to 1. + Implementations based on previous versions of ISAKMP Internet- + Drafts MUST set the Major Version to 0. Implementations SHOULD + + + +Maughan, et. al. Standards Track [Page 22] + +RFC 2408 ISAKMP November 1998 + + + never accept packets with a major version number larger than its + own. + + o Minor Version (4 bits) - indicates the minor version of the + ISAKMP protocol in use. Implementations based on this version of + the ISAKMP Internet-Draft MUST set the Minor Version to 0. + Implementations based on previous versions of ISAKMP Internet- + Drafts MUST set the Minor Version to 1. Implementations SHOULD + never accept packets with a minor version number larger than its + own, given the major version numbers are identical. + + o Exchange Type (1 octet) - indicates the type of exchange being + used. This dictates the message and payload orderings in the + ISAKMP exchanges. + + + Exchange Type Value + NONE 0 + Base 1 + Identity Protection 2 + Authentication Only 3 + Aggressive 4 + Informational 5 + ISAKMP Future Use 6 - 31 + DOI Specific Use 32 - 239 + Private Use 240 - 255 + + o Flags (1 octet) - indicates specific options that are set for the + ISAKMP exchange. The flags listed below are specified in the + Flags field beginning with the least significant bit, i.e the + Encryption bit is bit 0 of the Flags field, the Commit bit is bit + 1 of the Flags field, and the Authentication Only bit is bit 2 of + the Flags field. The remaining bits of the Flags field MUST be + set to 0 prior to transmission. + + -- E(ncryption Bit) (1 bit) - If set (1), all payloads following + the header are encrypted using the encryption algorithm + identified in the ISAKMP SA. The ISAKMP SA Identifier is the + combination of the initiator and responder cookie. It is + RECOMMENDED that encryption of communications be done as soon + as possible between the peers. For all ISAKMP exchanges + described in section 4.1, the encryption SHOULD begin after + both parties have exchanged Key Exchange payloads. If the + E(ncryption Bit) is not set (0), the payloads are not + encrypted. + + + + + + +Maughan, et. al. Standards Track [Page 23] + +RFC 2408 ISAKMP November 1998 + + + -- C(ommit Bit) (1 bit) - This bit is used to signal key exchange + synchronization. It is used to ensure that encrypted material + is not received prior to completion of the SA establishment. + The Commit Bit can be set (at anytime) by either party + participating in the SA establishment, and can be used during + both phases of an ISAKMP SA establishment. However, the value + MUST be reset after the Phase 1 negotiation. If set(1), the + entity which did not set the Commit Bit MUST wait for an + Informational Exchange containing a Notify payload (with the + CONNECTED Notify Message) from the entity which set the Commit + Bit. In this instance, the Message ID field of the + Informational Exchange MUST contain the Message ID of the + original ISAKMP Phase 2 SA negotiation. This is done to + ensure that the Informational Exchange with the CONNECTED + Notify Message can be associated with the correct Phase 2 SA. + The receipt and processing of the Informational Exchange + indicates that the SA establishment was successful and either + entity can now proceed with encrypted traffic communication. + In addition to synchronizing key exchange, the Commit Bit can + be used to protect against loss of transmissions over + unreliable networks and guard against the need for multiple + re-transmissions. + + NOTE: It is always possible that the final message of an + exchange can be lost. In this case, the entity expecting to + receive the final message of an exchange would receive the + Phase 2 SA negotiation message following a Phase 1 exchange or + encrypted traffic following a Phase 2 exchange. Handling of + this situation is not standardized, but we propose the + following possibilities. If the entity awaiting the + Informational Exchange can verify the received message (i.e. + Phase 2 SA negotiation message or encrypted traffic), then + they MAY consider the SA was established and continue + processing. The other option is to retransmit the last ISAKMP + message to force the other entity to retransmit the final + message. This suggests that implementations may consider + retaining the last message (locally) until they are sure the + SA is established. + + -- A(uthentication Only Bit) (1 bit) - This bit is intended for + use with the Informational Exchange with a Notify payload and + will allow the transmission of information with integrity + checking, but no encryption (e.g. "emergency mode"). Section + 4.8 states that a Phase 2 Informational Exchange MUST be sent + under the protection of an ISAKMP SA. This is the only + exception to that policy. If the Authentication Only bit is + set (1), only authentication security services will be applied + to the entire Notify payload of the Informational Exchange and + + + +Maughan, et. al. Standards Track [Page 24] + +RFC 2408 ISAKMP November 1998 + + + the payload will not be encrypted. + + o Message ID (4 octets) - Unique Message Identifier used to + identify protocol state during Phase 2 negotiations. This value + is randomly generated by the initiator of the Phase 2 + negotiation. In the event of simultaneous SA establishments + (i.e. collisions), the value of this field will likely be + different because they are independently generated and, thus, two + security associations will progress toward establishment. + However, it is unlikely there will be absolute simultaneous + establishments. During Phase 1 negotiations, the value MUST be + set to 0. + + o Length (4 octets) - Length of total message (header + payloads) + in octets. Encryption can expand the size of an ISAKMP message. + +3.2 Generic Payload Header + + Each ISAKMP payload defined in sections 3.4 through 3.16 begins with + a generic header, shown in Figure 3, which provides a payload + "chaining" capability and clearly defines the boundaries of a + payload. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 3: Generic Payload Header + + The Generic Payload Header fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. If the current payload is the last + in the message, then this field will be 0. This field provides + the "chaining" capability. + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the current + payload, including the generic payload header. + +3.3 Data Attributes + + There are several instances within ISAKMP where it is necessary to + represent Data Attributes. An example of this is the Security + Association (SA) Attributes contained in the Transform payload + + + +Maughan, et. al. Standards Track [Page 25] + +RFC 2408 ISAKMP November 1998 + + + (described in section 3.6). These Data Attributes are not an ISAKMP + payload, but are contained within ISAKMP payloads. The format of the + Data Attributes provides the flexibility for representation of many + different types of information. There can be multiple Data + Attributes within a payload. The length of the Data Attributes will + either be 4 octets or defined by the Attribute Length field. This is + done using the Attribute Format bit described below. Specific + information about the attributes for each domain will be described in + a DOI document, e.g. IPSEC DOI [IPDOI]. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + !A! Attribute Type ! AF=0 Attribute Length ! + !F! ! AF=1 Attribute Value ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . AF=0 Attribute Value . + . AF=1 Not Transmitted . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 4: Data Attributes + + The Data Attributes fields are defined as follows: + + o Attribute Type (2 octets) - Unique identifier for each type of + attribute. These attributes are defined as part of the DOI- + specific information. + + The most significant bit, or Attribute Format (AF), indicates + whether the data attributes follow the Type/Length/Value (TLV) + format or a shortened Type/Value (TV) format. If the AF bit is a + zero (0), then the Data Attributes are of the Type/Length/Value + (TLV) form. If the AF bit is a one (1), then the Data Attributes + are of the Type/Value form. + + o Attribute Length (2 octets) - Length in octets of the Attribute + Value. When the AF bit is a one (1), the Attribute Value is only + 2 octets and the Attribute Length field is not present. + + o Attribute Value (variable length) - Value of the attribute + associated with the DOI-specific Attribute Type. If the AF bit + is a zero (0), this field has a variable length defined by the + Attribute Length field. If the AF bit is a one (1), the + Attribute Value has a length of 2 octets. + + + + + + +Maughan, et. al. Standards Track [Page 26] + +RFC 2408 ISAKMP November 1998 + + +3.4 Security Association Payload + + The Security Association Payload is used to negotiate security + attributes and to indicate the Domain of Interpretation (DOI) and + Situation under which the negotiation is taking place. Figure 5 + shows the format of the Security Association payload. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Domain of Interpretation (DOI) ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Situation ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 5: Security Association Payload + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. If the current payload is the last + in the message, then this field will be 0. This field MUST NOT + contain the values for the Proposal or Transform payloads as they + are considered part of the security association negotiation. For + example, this field would contain the value "10" (Nonce payload) + in the first message of a Base Exchange (see Section 4.4) and the + value "0" in the first message of an Identity Protect Exchange + (see Section 4.5). + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the entire + Security Association payload, including the SA payload, all + Proposal payloads, and all Transform payloads associated with the + proposed Security Association. + + o Domain of Interpretation (4 octets) - Identifies the DOI (as + described in Section 2.1) under which this negotiation is taking + place. The DOI is a 32-bit unsigned integer. A DOI value of 0 + during a Phase 1 exchange specifies a Generic ISAKMP SA which can + be used for any protocol during the Phase 2 exchange. The + necessary SA Attributes are defined in A.4. A DOI value of 1 is + assigned to the IPsec DOI [IPDOI]. All other DOI values are + reserved to IANA for future use. IANA will not normally assign a + DOI value without referencing some public specification, such as + + + +Maughan, et. al. Standards Track [Page 27] + +RFC 2408 ISAKMP November 1998 + + + an Internet RFC. Other DOI's can be defined using the description + in appendix B. This field MUST be present within the Security + Association payload. + + o Situation (variable length) - A DOI-specific field that + identifies the situation under which this negotiation is taking + place. The Situation is used to make policy decisions regarding + the security attributes being negotiated. Specifics for the IETF + IP Security DOI Situation are detailed in [IPDOI]. This field + MUST be present within the Security Association payload. + +3.5 Proposal Payload + + The Proposal Payload contains information used during Security + Association negotiation. The proposal consists of security + mechanisms, or transforms, to be used to secure the communications + channel. Figure 6 shows the format of the Proposal Payload. A + description of its use can be found in section 4.2. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Proposal # ! Protocol-Id ! SPI Size !# of Transforms! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! SPI (variable) ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 6: Proposal Payload Format + + The Proposal Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. This 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. + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the entire + Proposal payload, including generic payload header, the Proposal + payload, and all Transform payloads associated with this + proposal. In the event there are multiple proposals with the + same proposal number (see section 4.2), the Payload Length field + + + +Maughan, et. al. Standards Track [Page 28] + +RFC 2408 ISAKMP November 1998 + + + only applies to the current Proposal payload and not to all + Proposal payloads. + + o Proposal # (1 octet) - Identifies the Proposal number for the + current payload. A description of the use of this field is found + in section 4.2. + + o Protocol-Id (1 octet) - Specifies the protocol identifier for the + current negotiation. Examples might include IPSEC ESP, IPSEC AH, + OSPF, TLS, etc. + + o SPI Size (1 octet) - Length in octets of the SPI as defined by + the Protocol-Id. In the case of ISAKMP, the Initiator and + Responder cookie pair from the ISAKMP Header is the ISAKMP SPI, + therefore, the SPI Size is irrelevant and MAY be from zero (0) to + sixteen (16). If the SPI Size is non-zero, the content of the + SPI field MUST be ignored. If the SPI Size is not a multiple of + 4 octets it will have some impact on the SPI field and the + alignment of all payloads in the message. The Domain of + Interpretation (DOI) will dictate the SPI Size for other + protocols. + + o # of Transforms (1 octet) - Specifies the number of transforms + for the Proposal. Each of these is contained in a Transform + payload. + + o SPI (variable) - The sending entity's SPI. In the event the SPI + Size is not a multiple of 4 octets, there is no padding applied + to the payload, however, it can be applied at the end of the + message. + + The payload type for the Proposal Payload is two (2). + +3.6 Transform Payload + + The Transform Payload contains information used during Security + Association negotiation. The Transform payload consists of a + specific security mechanism, or transforms, to be used to secure the + communications channel. The Transform payload also contains the + security association attributes associated with the specific + transform. These SA attributes are DOI-specific. Figure 7 shows the + format of the Transform Payload. A description of its use can be + found in section 4.2. + + + + + + + + +Maughan, et. al. Standards Track [Page 29] + +RFC 2408 ISAKMP November 1998 + + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Transform # ! Transform-Id ! RESERVED2 ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ SA Attributes ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 7: Transform Payload Format + + The Transform Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. This 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. + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the current + payload, including the generic payload header, Transform values, + and all SA Attributes. + + o Transform # (1 octet) - Identifies the Transform number for the + current payload. If there is more than one transform proposed + for a specific protocol within the Proposal payload, then each + Transform payload has a unique Transform number. A description + of the use of this field is found in section 4.2. + + o Transform-Id (1 octet) - Specifies the Transform identifier for + the protocol within the current proposal. These transforms are + defined by the DOI and are dependent on the protocol being + negotiated. + + o RESERVED2 (2 octets) - Unused, set to 0. + + o SA Attributes (variable length) - This field contains the + security association attributes as defined for the transform + given in the Transform-Id field. The SA Attributes SHOULD be + represented using the Data Attributes format described in section + 3.3. If the SA Attributes are not aligned on 4-byte boundaries, + + + +Maughan, et. al. Standards Track [Page 30] + +RFC 2408 ISAKMP November 1998 + + + then subsequent payloads will not be aligned and any padding will + be added at the end of the message to make the message 4-octet + aligned. + + The payload type for the Transform Payload is three (3). + +3.7 Key Exchange Payload + + The Key Exchange Payload supports a variety of key exchange + techniques. Example key exchanges are Oakley [Oakley], Diffie- + Hellman, the enhanced Diffie-Hellman key exchange described in X9.42 + [ANSI], and the RSA-based key exchange used by PGP. Figure 8 shows + the format of the Key Exchange payload. + + The Key Exchange Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + nextpayload in the message. If the current payload is the last + in the message, then this field will be 0. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Key Exchange Data ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 8: Key Exchange Payload Format + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the current + payload, including the generic payload header. + + o Key Exchange Data (variable length) - Data required to generate a + session key. The interpretation of this data is specified by the + DOI and the associated Key Exchange algorithm. This field may + also contain pre-placed key indicators. + + The payload type for the Key Exchange Payload is four (4). + + + + + + + +Maughan, et. al. Standards Track [Page 31] + +RFC 2408 ISAKMP November 1998 + + +3.8 Identification Payload + + The Identification Payload contains DOI-specific data used to + exchange identification information. This information is used for + determining the identities of communicating peers and may be used for + determining authenticity of information. Figure 9 shows the format + of the Identification Payload. + + The Identification Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. If the current payload is the last + in the message, then this field will be 0. + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the current + payload, including the generic payload header. + + o ID Type (1 octet) - Specifies the type of Identification being + used. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ID Type ! DOI Specific ID Data ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Identification Data ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 9: Identification Payload Format + + This field is DOI-dependent. + + o DOI Specific ID Data (3 octets) - Contains DOI specific + Identification data. If unused, then this field MUST be set to + 0. + + o Identification Data (variable length) - Contains identity + information. The values for this field are DOI-specific and the + format is specified by the ID Type field. Specific details for + the IETF IP Security DOI Identification Data are detailed in + [IPDOI]. + + + +Maughan, et. al. Standards Track [Page 32] + +RFC 2408 ISAKMP November 1998 + + + The payload type for the Identification Payload is five (5). + +3.9 Certificate Payload + + The Certificate Payload provides a means to transport certificates or + other certificate-related information via ISAKMP and can appear in + any ISAKMP message. Certificate payloads SHOULD be included in an + exchange whenever an appropriate directory service (e.g. Secure DNS + [DNSSEC]) is not available to distribute certificates. The + Certificate payload MUST be accepted at any point during an exchange. + Figure 10 shows the format of the Certificate Payload. + + NOTE: Certificate types and formats are not generally bound to a DOI + - it is expected that there will only be a few certificate types, and + that most DOIs will accept all of these types. + + The Certificate Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. If the current payload is the last + in the message, then this field will be 0. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Cert Encoding ! ! + +-+-+-+-+-+-+-+-+ ! + ~ Certificate Data ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 10: Certificate Payload Format + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the current + payload, including the generic payload header. + + o Certificate Encoding (1 octet) - This field indicates the type of + certificate or certificate-related information contained in the + Certificate Data field. + + + + + + + +Maughan, et. al. Standards Track [Page 33] + +RFC 2408 ISAKMP November 1998 + + + Certificate Type Value + NONE 0 + PKCS #7 wrapped X.509 certificate 1 + PGP Certificate 2 + DNS Signed Key 3 + X.509 Certificate - Signature 4 + X.509 Certificate - Key Exchange 5 + Kerberos Tokens 6 + Certificate Revocation List (CRL) 7 + Authority Revocation List (ARL) 8 + SPKI Certificate 9 + X.509 Certificate - Attribute 10 + RESERVED 11 - 255 + + o Certificate Data (variable length) - Actual encoding of + certificate data. The type of certificate is indicated by the + Certificate Encoding field. + + The payload type for the Certificate Payload is six (6). + +3.10 Certificate Request Payload + + The Certificate Request Payload provides a means to request + certificates via ISAKMP and can appear in any message. Certificate + Request payloads SHOULD be included in an exchange whenever an + appropriate directory service (e.g. Secure DNS [DNSSEC]) is not + available to distribute certificates. The Certificate Request + payload MUST be accepted at any point during the exchange. The + responder to the Certificate Request payload MUST send its + certificate, if certificates are supported, based on the values + contained in the payload. If multiple certificates are required, + then multiple Certificate Request payloads SHOULD be transmitted. + Figure 11 shows the format of the Certificate Request Payload. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Cert. Type ! ! + +-+-+-+-+-+-+-+-+ ! + ~ Certificate Authority ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 11: Certificate Request Payload Format + + + + +Maughan, et. al. Standards Track [Page 34] + +RFC 2408 ISAKMP November 1998 + + + The Certificate Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. If the current payload is the last + in the message, then this field will be 0. + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the current + payload, including the generic payload header. + + o Certificate Type (1 octet) - Contains an encoding of the type of + certificate requested. Acceptable values are listed in section + 3.9. + + o Certificate Authority (variable length) - Contains an encoding of + an acceptable certificate authority for the type of certificate + requested. As an example, for an X.509 certificate this field + would contain the Distinguished Name encoding of the Issuer Name + of an X.509 certificate authority acceptable to the sender of + this payload. This would be included to assist the responder in + determining how much of the certificate chain would need to be + sent in response to this request. If there is no specific + certificate authority requested, this field SHOULD not be + included. + + The payload type for the Certificate Request Payload is seven (7). + + + + + + + + + + + + + + + + + + + + + + + + +Maughan, et. al. Standards Track [Page 35] + +RFC 2408 ISAKMP November 1998 + + +3.11 Hash Payload + + The Hash Payload contains data generated by the hash function + (selected during the SA establishment exchange), over some part of + the message and/or ISAKMP state. This payload may be used to verify + the integrity of the data in an ISAKMP message or for authentication + of the negotiating entities. Figure 12 shows the format of the Hash + Payload. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Hash Data ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 12: Hash Payload Format + + The Hash Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. If the current payload is the last + in the message, then this field will be 0. + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the current + payload, including the generic payload header. + + o Hash Data (variable length) - Data that results from applying the + hash routine to the ISAKMP message and/or state. + + + + + + + + + + + + + + + + +Maughan, et. al. Standards Track [Page 36] + +RFC 2408 ISAKMP November 1998 + + +3.12 Signature Payload + + The Signature Payload contains data generated by the digital + signature function (selected during the SA establishment exchange), + over some part of the message and/or ISAKMP state. This payload is + used to verify the integrity of the data in the ISAKMP message, and + may be of use for non-repudiation services. Figure 13 shows the + format of the Signature Payload. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Signature Data ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 13: Signature Payload Format + + The Signature Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. If the current payload is the last + in the message, then this field will be 0. + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the current + payload, including the generic payload header. + + o Signature Data (variable length) - Data that results from + applying the digital signature function to the ISAKMP message + and/or state. + + The payload type for the Signature Payload is nine (9). + +3.13 Nonce Payload + + The Nonce Payload contains random data used to guarantee liveness + during an exchange and protect against replay attacks. Figure 14 + shows the format of the Nonce Payload. If nonces are used by a + particular key exchange, the use of the Nonce payload will be + dictated by the key exchange. The nonces may be transmitted as part + of the key exchange data, or as a separate payload. However, this is + defined by the key exchange, not by ISAKMP. + + + +Maughan, et. al. Standards Track [Page 37] + +RFC 2408 ISAKMP November 1998 + + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Nonce Data ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 14: Nonce Payload Format + + The Nonce Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. If the current payload is the last + in the message, then this field will be 0. + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the current + payload, including the generic payload header. + + o Nonce Data (variable length) - Contains the random data generated + by the transmitting entity. + + The payload type for the Nonce Payload is ten (10). + +3.14 Notification Payload + + The Notification Payload can contain both ISAKMP and DOI-specific + data and is used to transmit informational data, such as error + conditions, to an ISAKMP peer. It is possible to send multiple + Notification payloads in a single ISAKMP message. Figure 15 shows + the format of the Notification Payload. + + Notification which occurs during, or is concerned with, a Phase 1 + negotiation is identified by the Initiator and Responder cookie pair + in the ISAKMP Header. The Protocol Identifier, in this case, is + ISAKMP and the SPI value is 0 because the cookie pair in the ISAKMP + Header identifies the ISAKMP SA. If the notification takes place + prior to the completed exchange of keying information, then the + notification will be unprotected. + + + + + + + +Maughan, et. al. Standards Track [Page 38] + +RFC 2408 ISAKMP November 1998 + + + Notification which occurs during, or is concerned with, a Phase 2 + negotiation is identified by the Initiator and Responder cookie pair + in the ISAKMP Header and the Message ID and SPI associated with the + current negotiation. One example for this type of notification is to + indicate why a proposal was rejected. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Domain of Interpretation (DOI) ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Protocol-ID ! SPI Size ! Notify Message Type ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Security Parameter Index (SPI) ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Notification Data ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 15: Notification Payload Format + + The Notification Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. If the current payload is the last + in the message, then this field will be 0. + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the current + payload, including the generic payload header. + + o Domain of Interpretation (4 octets) - Identifies the DOI (as + described in Section 2.1) under which this notification is taking + place. For ISAKMP this value is zero (0) and for the IPSEC DOI + it is one (1). Other DOI's can be defined using the description + in appendix B. + + o Protocol-Id (1 octet) - Specifies the protocol identifier for the + current notification. Examples might include ISAKMP, IPSEC ESP, + IPSEC AH, OSPF, TLS, etc. + + + + +Maughan, et. al. Standards Track [Page 39] + +RFC 2408 ISAKMP November 1998 + + + o SPI Size (1 octet) - Length in octets of the SPI as defined by + the Protocol-Id. In the case of ISAKMP, the Initiator and + Responder cookie pair from the ISAKMP Header is the ISAKMP SPI, + therefore, the SPI Size is irrelevant and MAY be from zero (0) to + sixteen (16). If the SPI Size is non-zero, the content of the + SPI field MUST be ignored. The Domain of Interpretation (DOI) + will dictate the SPI Size for other protocols. + + o Notify Message Type (2 octets) - Specifies the type of + notification message (see section 3.14.1). Additional text, if + specified by the DOI, is placed in the Notification Data field. + + o SPI (variable length) - Security Parameter Index. The receiving + entity's SPI. The use of the SPI field is described in section + 2.4. The length of this field is determined by the SPI Size + field and is not necessarily aligned to a 4 octet boundary. + + o Notification Data (variable length) - Informational or error data + transmitted in addition to the Notify Message Type. Values for + this field are DOI-specific. + + The payload type for the Notification Payload is eleven (11). + +3.14.1 Notify Message Types + + Notification information can be error messages specifying why an SA + could not be established. It can also be status data that a process + managing an SA database wishes to communicate with a peer process. + For example, a secure front end or security gateway may use the + Notify message to synchronize SA communication. The table below + lists the Nofitication messages and their corresponding values. + Values in the Private Use range are expected to be DOI-specific + values. + + NOTIFY MESSAGES - ERROR TYPES + + Errors Value + INVALID-PAYLOAD-TYPE 1 + DOI-NOT-SUPPORTED 2 + SITUATION-NOT-SUPPORTED 3 + INVALID-COOKIE 4 + INVALID-MAJOR-VERSION 5 + INVALID-MINOR-VERSION 6 + INVALID-EXCHANGE-TYPE 7 + INVALID-FLAGS 8 + INVALID-MESSAGE-ID 9 + INVALID-PROTOCOL-ID 10 + INVALID-SPI 11 + + + +Maughan, et. al. Standards Track [Page 40] + +RFC 2408 ISAKMP November 1998 + + + INVALID-TRANSFORM-ID 12 + ATTRIBUTES-NOT-SUPPORTED 13 + NO-PROPOSAL-CHOSEN 14 + BAD-PROPOSAL-SYNTAX 15 + PAYLOAD-MALFORMED 16 + INVALID-KEY-INFORMATION 17 + INVALID-ID-INFORMATION 18 + INVALID-CERT-ENCODING 19 + INVALID-CERTIFICATE 20 + CERT-TYPE-UNSUPPORTED 21 + INVALID-CERT-AUTHORITY 22 + INVALID-HASH-INFORMATION 23 + AUTHENTICATION-FAILED 24 + INVALID-SIGNATURE 25 + ADDRESS-NOTIFICATION 26 + NOTIFY-SA-LIFETIME 27 + CERTIFICATE-UNAVAILABLE 28 + UNSUPPORTED-EXCHANGE-TYPE 29 + UNEQUAL-PAYLOAD-LENGTHS 30 + RESERVED (Future Use) 31 - 8191 + Private Use 8192 - 16383 + + + + NOTIFY MESSAGES - STATUS TYPES + Status Value + CONNECTED 16384 + RESERVED (Future Use) 16385 - 24575 + DOI-specific codes 24576 - 32767 + Private Use 32768 - 40959 + RESERVED (Future Use) 40960 - 65535 + +3.15 Delete Payload + + The Delete Payload contains a protocol-specific security association + identifier that the sender has removed from its security association + database and is, therefore, no longer valid. Figure 16 shows the + format of the Delete Payload. It is possible to send multiple SPIs + in a Delete payload, however, each SPI MUST be for the same protocol. + Mixing of Protocol Identifiers MUST NOT be performed with the Delete + payload. + + Deletion which is concerned with an ISAKMP SA will contain a + Protocol-Id of ISAKMP and the SPIs are the initiator and responder + cookies from the ISAKMP Header. Deletion which is concerned with a + Protocol SA, such as ESP or AH, will contain the Protocol-Id of that + protocol (e.g. ESP, AH) and the SPI is the sending entity's SPI(s). + + + + +Maughan, et. al. Standards Track [Page 41] + +RFC 2408 ISAKMP November 1998 + + + NOTE: The Delete Payload is not a request for the responder to delete + an SA, but an advisory from the initiator to the responder. If the + responder chooses to ignore the message, the next communication from + the responder to the initiator, using that security association, will + fail. A responder is not expected to acknowledge receipt of a Delete + payload. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Domain of Interpretation (DOI) ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Protocol-Id ! SPI Size ! # of SPIs ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Security Parameter Index(es) (SPI) ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 16: Delete Payload Format + + The Delete Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. If the current payload is the last + in the message, then this field will be 0. + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the current + payload, including the generic payload header. + + o Domain of Interpretation (4 octets) - Identifies the DOI (as + described in Section 2.1) under which this deletion is taking + place. For ISAKMP this value is zero (0) and for the IPSEC DOI + it is one (1). Other DOI's can be defined using the description + in appendix B. + + o Protocol-Id (1 octet) - ISAKMP can establish security + associations for various protocols, including ISAKMP and IPSEC. + This field identifies which security association database to + apply the delete request. + + + + + + +Maughan, et. al. Standards Track [Page 42] + +RFC 2408 ISAKMP November 1998 + + + o SPI Size (1 octet) - Length in octets of the SPI as defined by + the Protocol-Id. In the case of ISAKMP, the Initiator and + Responder cookie pair is the ISAKMP SPI. In this case, the SPI + Size would be 16 octets for each SPI being deleted. + + o # of SPIs (2 octets) - The number of SPIs contained in the Delete + payload. The size of each SPI is defined by the SPI Size field. + + o Security Parameter Index(es) (variable length) - Identifies the + specific security association(s) to delete. Values for this + field are DOI and protocol specific. The length of this field is + determined by the SPI Size and # of SPIs fields. + + The payload type for the Delete Payload is twelve (12). + +3.16 Vendor ID Payload + + The Vendor ID Payload contains a vendor defined constant. The + constant is used by vendors to identify and recognize remote + instances of their implementations. This mechanism allows a vendor + to experiment with new features while maintaining backwards + compatibility. This is not a general extension facility of ISAKMP. + Figure 17 shows the format of the Vendor ID Payload. + + The Vendor ID payload is not an announcement from the sender that it + will send private payload types. A vendor sending the Vendor ID MUST + not make any assumptions about private payloads that it may send + unless a Vendor ID is received as well. Multiple Vendor ID payloads + MAY be sent. An implementation is NOT REQUIRED to understand any + Vendor ID payloads. An implementation is NOT REQUIRED to send any + Vendor ID payload at all. If a private payload was sent without + prior agreement to send it, a compliant implementation may reject a + proposal with a notify message of type INVALID-PAYLOAD-TYPE. + + If a Vendor ID payload is sent, it MUST be sent during the Phase 1 + negotiation. Reception of a familiar Vendor ID payload in the Phase + 1 negotiation allows an implementation to make use of Private USE + payload numbers (128-255), described in section 3.1 for vendor + specific extensions during Phase 2 negotiations. The definition of + "familiar" is left to implementations to determine. Some vendors may + wish to implement another vendor's extension prior to + standardization. However, this practice SHOULD not be widespread and + vendors should work towards standardization instead. + + The vendor defined constant MUST be unique. The choice of hash and + text to hash is left to the vendor to decide. As an example, vendors + could generate their vendor id by taking a plain (non-keyed) hash of + a string containing the product name, and the version of the product. + + + +Maughan, et. al. Standards Track [Page 43] + +RFC 2408 ISAKMP November 1998 + + + A hash is used instead of a vendor registry to avoid local + cryptographic policy problems with having a list of "approved" + products, to keep away from maintaining a list of vendors, and to + allow classified products to avoid having to appear on any list. For + instance: + + "Example Company IPsec. Version 97.1" + + (not including the quotes) has MD5 hash: + 48544f9b1fe662af98b9b39e50c01a5a, when using MD5file. Vendors may + include all of the hash, or just a portion of it, as the payload + length will bound the data. There are no security implications of + this hash, so its choice is arbitrary. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Vendor ID (VID) ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Figure 17: Vendor ID Payload Format + + The Vendor ID Payload fields are defined as follows: + + o Next Payload (1 octet) - Identifier for the payload type of the + next payload in the message. If the current payload is the last + in the message, then this field will be 0. + + o RESERVED (1 octet) - Unused, set to 0. + + o Payload Length (2 octets) - Length in octets of the current + payload, including the generic payload header. + + o Vendor ID (variable length) - Hash of the vendor string plus + version (as described above). + + The payload type for the Vendor ID Payload is thirteen (13). + +4 ISAKMP Exchanges + + ISAKMP supplies the basic syntax of a message exchange. The basic + building blocks for ISAKMP messages are the payload types described + in section 3. This section describes the procedures for SA + + + +Maughan, et. al. Standards Track [Page 44] + +RFC 2408 ISAKMP November 1998 + + + establishment and SA modification, followed by a default set of + exchanges that MAY be used for initial interoperability. Other + exchanges will be defined depending on the DOI and key exchange. + [IPDOI] and [IKE] are examples of how this is achieved. Appendix B + explains the procedures for accomplishing these additions. + +4.1 ISAKMP Exchange Types + + ISAKMP allows the creation of exchanges for the establishment of + Security Associations and keying material. There are currently five + default Exchange Types defined for ISAKMP. Sections 4.4 through 4.8 + describe these exchanges. Exchanges define the content and ordering + of ISAKMP messages during communications between peers. Most + exchanges will include all the basic payload types - SA, KE, ID, SIG + - and may include others. The primary difference between exchange + types is the ordering of the messages and the payload ordering within + each message. While the ordering of payloads within messages is not + mandated, for processing efficiency it is RECOMMENDED that the + Security Association payload be the first payload within an exchange. + Processing of each payload within an exchange is described in section + 5. + + Sections 4.4 through 4.8 provide a default set of ISAKMP exchanges. + These exchanges provide different security protection for the + exchange itself and information exchanged. The diagrams in each of + the following sections show the message ordering for each exchange + type as well as the payloads included in each message, and provide + basic notes describing what has happened after each message exchange. + None of the examples include any "optional payloads", like + certificate and certificate request. Additionally, none of the + examples include an initial exchange of ISAKMP Headers (containing + initiator and responder cookies) which would provide protection + against clogging (see section 2.5.3). + + The defined exchanges are not meant to satisfy all DOI and key + exchange protocol requirements. If the defined exchanges meet the + DOI requirements, then they can be used as outlined. If the defined + exchanges do not meet the security requirements defined by the DOI, + then the DOI MUST specify new exchange type(s) and the valid + sequences of payloads that make up a successful exchange, and how to + build and interpret those payloads. All ISAKMP implementations MUST + implement the Informational Exchange and SHOULD implement the other + four exchanges. However, this is dependent on the definition of the + DOI and associated key exchange protocols. + + + + + + + +Maughan, et. al. Standards Track [Page 45] + +RFC 2408 ISAKMP November 1998 + + + As discussed above, these exchange types can be used in either phase + of negotiation. However, they may provide different security + properties in each of the phases. With each of these exchanges, the + combination of cookies and SPI fields identifies whether this + exchange is being used in the first or second phase of a negotiation. + +4.1.1 Notation + + The following notation is used to describe the ISAKMP exchange types, + shown in the next section, with the message formats and associated + payloads: + + HDR is an ISAKMP header whose exchange type defines the payload + orderings + SA is an SA negotiation payload with one or more Proposal and + Transform payloads. An initiator MAY provide multiple proposals + for negotiation; a responder MUST reply with only one. + KE is the key exchange payload. + IDx is the identity payload for "x". x can be: "ii" or "ir" + for the ISAKMP initiator and responder, respectively, or x can + be: "ui", "ur" (when the ISAKMP daemon is a proxy negotiator), + for the user initiator and responder, respectively. + HASH is the hash payload. + SIG is the signature payload. The data to sign is exchange-specific. + AUTH is a generic authentication mechanism, such as HASH or SIG. + NONCE is the nonce payload. + '*' signifies payload encryption after the ISAKMP header. This + encryption MUST begin immediately after the ISAKMP header and + all payloads following the ISAKMP header MUST be encrypted. + + => signifies "initiator to responder" communication + <= signifies "responder to initiator" communication + +4.2 Security Association Establishment + + The Security Association, Proposal, and Transform payloads are used + to build ISAKMP messages for the negotiation and establishment of + SAs. An SA establishment message consists of a single SA payload + followed by at least one, and possibly many, Proposal payloads and at + least one, and possibly many, Transform payloads associated with each + Proposal payload. Because these payloads are considered together, + the SA payload will point to any following payloads and not to the + Proposal payload included with the SA payload. The SA Payload + contains the DOI and Situation for the proposed SA. Each Proposal + payload contains a Security Parameter Index (SPI) and ensures that + the SPI is associated with the Protocol-Id in accordance with the + Internet Security Architecture [SEC-ARCH]. Proposal payloads may or + may not have the same SPI, as this is implementation dependent. Each + + + +Maughan, et. al. Standards Track [Page 46] + +RFC 2408 ISAKMP November 1998 + + + Transform Payload contains the specific security mechanisms to be + used for the designated protocol. It is expected that the Proposal + and Transform payloads will be used only during SA establishment + negotiation. The creation of payloads for security association + negotiation and establishment described here in this section are + applicable for all ISAKMP exchanges described later in sections 4.4 + through 4.8. The examples shown in 4.2.1 contain only the SA, + Proposal, and Transform payloads and do not contain other payloads + that might exist for a given ISAKMP exchange. + + The Proposal payload provides the initiating entity with the + capability to present to the responding entity the security protocols + and associated security mechanisms for use with the security + association being negotiated. If the SA establishment negotiation is + for a combined protection suite consisting of multiple protocols, + then there MUST be multiple Proposal payloads each with the same + Proposal number. These proposals MUST be considered as a unit and + MUST NOT be separated by a proposal with a different proposal number. + The use of the same Proposal number in multiple Proposal payloads + provides a logical AND operation, i.e. Protocol 1 AND Protocol 2. + The first example below shows an ESP AND AH protection suite. If the + SA establishment negotiation is for different protection suites, then + there MUST be multiple Proposal payloads each with a monotonically + increasing Proposal number. The different proposals MUST be + presented in the initiator's preference order. The use of different + Proposal numbers in multiple Proposal payloads provides a logical OR + operation, i.e. Proposal 1 OR Proposal 2, where each proposal may + have more than one protocol. The second example below shows either + an AH AND ESP protection suite OR just an ESP protection suite. Note + that the Next Payload field of the Proposal payload points to another + Proposal payload (if it exists). The existence of a Proposal payload + implies the existence of one or more Transform payloads. + + The Transform payload provides the initiating entity with the + capability to present to the responding entity multiple mechanisms, + or transforms, for a given protocol. The Proposal payload identifies + a Protocol for which services and mechanisms are being negotiated. + The Transform payload allows the initiating entity to present several + possible supported transforms for that proposed protocol. There may + be several transforms associated with a specific Proposal payload + each identified in a separate Transform payload. The multiple + transforms MUST be presented with monotonically increasing numbers in + the initiator's preference order. The receiving entity MUST select a + single transform for each protocol in a proposal or reject the entire + proposal. The use of the Transform number in multiple Transform + payloads provides a second level OR operation, i.e. Transform 1 OR + Transform 2 OR Transform 3. Example 1 below shows two possible + transforms for ESP and a single transform for AH. Example 2 below + + + +Maughan, et. al. Standards Track [Page 47] + +RFC 2408 ISAKMP November 1998 + + + shows one transform for AH AND one transform for ESP OR two + transforms for ESP alone. Note that the Next Payload field of the + Transform payload points to another Transform payload or 0. The + Proposal payload delineates the different proposals. + + When responding to a Security Association payload, the responder MUST + send a Security Association payload with the selected proposal, which + may consist of multiple Proposal payloads and their associated + Transform payloads. Each of the Proposal payloads MUST contain a + single Transform payload associated with the Protocol. The responder + SHOULD retain the Proposal # field in the Proposal payload and the + Transform # field in each Transform payload of the selected Proposal. + Retention of Proposal and Transform numbers should speed the + initiator's protocol processing by negating the need to compare the + respondor's selection with every offered option. These values enable + the initiator to perform the comparison directly and quickly. The + initiator MUST verify that the Security Association payload received + from the responder matches one of the proposals sent initially. + +4.2.1 Security Association Establishment Examples + + This example shows a Proposal for a combined protection suite with + two different protocols. The first protocol is presented with two + transforms supported by the proposer. The second protocol is + presented with a single transform. An example for this proposal + might be: Protocol 1 is ESP with Transform 1 as 3DES and Transform 2 + as DES AND Protocol 2 is AH with Transform 1 as SHA. The responder + MUST select from the two transforms proposed for ESP. The resulting + protection suite will be either (1) 3DES AND SHA OR (2) DES AND SHA, + depending on which ESP transform was selected by the responder. Note + this example is shown using the Base Exchange. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + /+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = Nonce ! RESERVED ! Payload Length ! + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +SA Pay ! Domain of Interpretation (DOI) ! + \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! Situation ! + >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = Proposal ! RESERVED ! Payload Length ! + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Prop 1 ! Proposal # = 1! Protocol-Id ! SPI Size !# of Trans. = 2! +Prot 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! SPI (variable) ! + >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = Transform! RESERVED ! Payload Length ! + + + +Maughan, et. al. Standards Track [Page 48] + +RFC 2408 ISAKMP November 1998 + + + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Tran 1 ! Transform # 1 ! Transform ID ! RESERVED2 ! + \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! SA Attributes ! + >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = 0 ! RESERVED ! Payload Length ! + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Tran 2 ! Transform # 2 ! Transform ID ! RESERVED2 ! + \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! SA Attributes ! + >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = 0 ! RESERVED ! Payload Length ! + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Prop 1 ! Proposal # = 1! Protocol ID ! SPI Size !# of Trans. = 1! +Prot 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! SPI (variable) ! + >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = 0 ! RESERVED ! Payload Length ! + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Tran 1 ! Transform # 1 ! Transform ID ! RESERVED2 ! + \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! SA Attributes ! + \+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + This second example shows a Proposal for two different protection + suites. The SA Payload was omitted for space reasons. The first + protection suite is presented with one transform for the first + protocol and one transform for the second protocol. The second + protection suite is presented with two transforms for a single + protocol. An example for this proposal might be: Proposal 1 with + Protocol 1 as AH with Transform 1 as MD5 AND Protocol 2 as ESP with + Transform 1 as 3DES. This is followed by Proposal 2 with Protocol 1 + as ESP with Transform 1 as DES and Transform 2 as 3DES. The responder + MUST select from the two different proposals. If the second Proposal + is selected, the responder MUST select from the two transforms for + ESP. The resulting protection suite will be either (1) MD5 AND 3DES + OR the selection between (2) DES OR (3) 3DES. + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + /+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = Proposal ! RESERVED ! Payload Length ! + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Prop 1 ! Proposal # = 1! Protocol ID ! SPI Size !# of Trans. = 1! +Prot 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! SPI (variable) ! + >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = 0 ! RESERVED ! Payload Length ! + + + +Maughan, et. al. Standards Track [Page 49] + +RFC 2408 ISAKMP November 1998 + + + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Tran 1 ! Transform # 1 ! Transform ID ! RESERVED2 ! + \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! SA Attributes ! + >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = Proposal ! RESERVED ! Payload Length ! + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Prop 1 ! Proposal # = 1! Protocol ID ! SPI Size !# of Trans. = 1! +Prot 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! SPI (variable) ! + >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = 0 ! RESERVED ! Payload Length ! + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Tran 1 ! Transform # 1 ! Transform ID ! RESERVED2 ! + \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! SA Attributes ! + >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = 0 ! RESERVED ! Payload Length ! + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Prop 2 ! Proposal # = 2! Protocol ID ! SPI Size !# of Trans. = 2! +Prot 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! SPI (variable) ! + >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = Transform! RESERVED ! Payload Length ! + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Tran 1 ! Transform # 1 ! Transform ID ! RESERVED2 ! + \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! SA Attributes ! + >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + / ! NP = 0 ! RESERVED ! Payload Length ! + / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Tran 2 ! Transform # 2 ! Transform ID ! RESERVED2 ! + \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + \ ! SA Attributes ! + \+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +4.3 Security Association Modification + + Security Association modification within ISAKMP is accomplished by + creating a new SA and initiating communications using that new SA. + Deletion of the old SA can be done anytime after the new SA is + established. Deletion of the old SA is dependent on local security + policy. Modification of SAs by using a "Create New SA followed by + Delete Old SA" method is done to avoid potential vulnerabilities in + synchronizing modification of existing SA attributes. The procedure + for creating new SAs is outlined in section 4.2. The procedure for + deleting SAs is outlined in section 5.15. + + + + +Maughan, et. al. Standards Track [Page 50] + +RFC 2408 ISAKMP November 1998 + + + Modification of an ISAKMP SA (phase 1 negotiation) follows the same + procedure as creation of an ISAKMP SA. There is no relationship + between the two SAs and the initiator and responder cookie pairs + SHOULD be different, as outlined in section 2.5.3. + + Modification of a Protocol SA (phase 2 negotiation) follows the same + procedure as creation of a Protocol SA. The creation of a new SA is + protected by the existing ISAKMP SA. There is no relationship between + the two Protocol SAs. A protocol implementation SHOULD begin using + the newly created SA for outbound traffic and SHOULD continue to + support incoming traffic on the old SA until it is deleted or until + traffic is received under the protection of the newly created SA. As + stated previously in this section, deletion of an old SA is then + dependent on local security policy. + +4.4 Base Exchange + + The Base Exchange is designed to allow the Key Exchange and + Authentication related information to be transmitted together. + Combining the Key Exchange and Authentication-related information + into one message reduces the number of round-trips at the expense of + not providing identity protection. Identity protection is not + provided because identities are exchanged before a common shared + secret has been established and, therefore, encryption of the + identities is not possible. The following diagram shows the messages + with the possible payloads sent in each message and notes for an + example of the Base Exchange. + + BASE EXCHANGE + + # Initiator Direction Responder NOTE +(1) HDR; SA; NONCE => Begin ISAKMP-SA or Proxy negotiation + +(2) <= HDR; SA; NONCE + Basic SA agreed upon +(3) HDR; KE; => + IDii; AUTH Key Generated (by responder) + Initiator Identity Verified by + Responder +(4) <= HDR; KE; + IDir; AUTH + Responder Identity Verified by + Initiator Key Generated (by + initiator) SA established + + + + + + + +Maughan, et. al. Standards Track [Page 51] + +RFC 2408 ISAKMP November 1998 + + + In the first message (1), the initiator generates a proposal it + considers adequate to protect traffic for the given situation. The + Security Association, Proposal, and Transform payloads are included + in the Security Association payload (for notation purposes). Random + information which is used to guarantee liveness and protect against + replay attacks is also transmitted. Random information provided by + both parties SHOULD be used by the authentication mechanism to + provide shared proof of participation in the exchange. + + In the second message (2), the responder indicates the protection + suite it has accepted with the Security Association, Proposal, and + Transform payloads. Again, random information which is used to + guarantee liveness and protect against replay attacks is also + transmitted. Random information provided by both parties SHOULD be + used by the authentication mechanism to provide shared proof of + participation in the exchange. Local security policy dictates the + action of the responder if no proposed protection suite is accepted. + One possible action is the transmission of a Notify payload as part + of an Informational Exchange. + + In the third (3) and fourth (4) messages, the initiator and + responder, respectively, exchange keying material used to arrive at a + common shared secret and identification information. This + information is transmitted under the protection of the agreed upon + authentication function. Local security policy dictates the action + if an error occurs during these messages. One possible action is the + transmission of a Notify payload as part of an Informational + Exchange. + +4.5 Identity Protection Exchange + + The Identity Protection Exchange is designed to separate the Key + Exchange information from the Identity and Authentication related + information. Separating the Key Exchange from the Identity and + Authentication related information provides protection of the + communicating identities at the expense of two additional messages. + Identities are exchanged under the protection of a previously + established common shared secret. The following diagram shows the + messages with the possible payloads sent in each message and notes + for an example of the Identity Protection Exchange. + + + + + + + + + + + +Maughan, et. al. Standards Track [Page 52] + +RFC 2408 ISAKMP November 1998 + + + IDENTITY PROTECTION EXCHANGE + + # Initiator Direction Responder NOTE +(1) HDR; SA => Begin ISAKMP-SA or + Proxy negotiation +(2) <= HDR; SA + Basic SA agreed upon +(3) HDR; KE; NONCE => +(4) <= HDR; KE; NONCE + Key Generated (by + Initiator and + Responder) +(5) HDR*; IDii; AUTH => + Initiator Identity + Verified by + Responder +(6) <= HDR*; IDir; AUTH + Responder Identity + Verified by + Initiator + SA established + + In the first message (1), the initiator generates a proposal it + considers adequate to protect traffic for the given situation. The + Security Association, Proposal, and Transform payloads are included + in the Security Association payload (for notation purposes). + + In the second message (2), the responder indicates the protection + suite it has accepted with the Security Association, Proposal, and + Transform payloads. Local security policy dictates the action of the + responder if no proposed protection suite is accepted. One possible + action is the transmission of a Notify payload as part of an + Informational Exchange. + + In the third (3) and fourth (4) messages, the initiator and + responder, respectively, exchange keying material used to arrive at a + common shared secret and random information which is used to + guarantee liveness and protect against replay attacks. Random + information provided by both parties SHOULD be used by the + authentication mechanism to provide shared proof of participation in + the exchange. Local security policy dictates the action if an error + occurs during these messages. One possible action is the + transmission of a Notify payload as part of an Informational + Exchange. + + In the fifth (5) and sixth (6) messages, the initiator and responder, + respectively, exchange identification information and the results of + the agreed upon authentication function. This information is + + + +Maughan, et. al. Standards Track [Page 53] + +RFC 2408 ISAKMP November 1998 + + + transmitted under the protection of the common shared secret. Local + security policy dictates the action if an error occurs during these + messages. One possible action is the transmission of a Notify + payload as part of an Informational Exchange. + +4.6 Authentication Only Exchange + + The Authentication Only Exchange is designed to allow only + Authentication related information to be transmitted. The benefit of + this exchange is the ability to perform only authentication without + the computational expense of computing keys. Using this exchange + during negotiation, none of the transmitted information will be + encrypted. However, the information may be encrypted in other + places. For example, if encryption is negotiated during the first + phase of a negotiation and the authentication only exchange is used + in the second phase of a negotiation, then the authentication only + exchange will be encrypted by the ISAKMP SAs negotiated in the first + phase. The following diagram shows the messages with possible + payloads sent in each message and notes for an example of the + Authentication Only Exchange. + + AUTHENTICATION ONLY EXCHANGE + + # Initiator Direction Responder NOTE +(1) HDR; SA; NONCE => Begin ISAKMP-SA or + Proxy negotiation +(2) <= HDR; SA; NONCE; + IDir; AUTH + Basic SA agreed upon + Responder Identity + Verified by Initiator +(3) HDR; IDii; AUTH => + Initiator Identity + Verified by Responder + SA established + + In the first message (1), the initiator generates a proposal it + considers adequate to protect traffic for the given situation. The + Security Association, Proposal, and Transform payloads are included + in the Security Association payload (for notation purposes). Random + information which is used to guarantee liveness and protect against + replay attacks is also transmitted. Random information provided by + both parties SHOULD be used by the authentication mechanism to + provide shared proof of participation in the exchange. + + In the second message (2), the responder indicates the protection + suite it has accepted with the Security Association, Proposal, and + Transform payloads. Again, random information which is used to + + + +Maughan, et. al. Standards Track [Page 54] + +RFC 2408 ISAKMP November 1998 + + + guarantee liveness and protect against replay attacks is also + transmitted. Random information provided by both parties SHOULD be + used by the authentication mechanism to provide shared proof of + participation in the exchange. Additionally, the responder transmits + identification information. All of this information is transmitted + under the protection of the agreed upon authentication function. + Local security policy dictates the action of the responder if no + proposed protection suite is accepted. One possible action is the + transmission of a Notify payload as part of an Informational + Exchange. + + In the third message (3), the initiator transmits identification + information. This information is transmitted under the protection of + the agreed upon authentication function. Local security policy + dictates the action if an error occurs during these messages. One + possible action is the transmission of a Notify payload as part of an + Informational Exchange. + +4.7 Aggressive Exchange + + The Aggressive Exchange is designed to allow the Security + Association, Key Exchange and Authentication related payloads to be + transmitted together. Combining the Security Association, Key + Exchange, and Authentication-related information into one message + reduces the number of round-trips at the expense of not providing + identity protection. Identity protection is not provided because + identities are exchanged before a common shared secret has been + established and, therefore, encryption of the identities is not + possible. Additionally, the Aggressive Exchange is attempting to + establish all security relevant information in a single exchange. + The following diagram shows the messages with possible payloads sent + in each message and notes for an example of the Aggressive Exchange. + + + + + + + + + + + + + + + + + + + +Maughan, et. al. Standards Track [Page 55] + +RFC 2408 ISAKMP November 1998 + + + AGGRESSIVE EXCHANGE + + # Initiator Direction Responder NOTE +(1) HDR; SA; KE; => Begin ISAKMP-SA or + Proxy negotiation + NONCE; IDii and Key Exchange + +(2) <= HDR; SA; KE; + NONCE; IDir; AUTH + Initiator Identity + Verified by Responder + Key Generated + Basic SA agreed upon +(3) HDR*; AUTH => + Responder Identity + Verified by Initiator + SA established + + In the first message (1), the initiator generates a proposal it + considers adequate to protect traffic for the given situation. The + Security Association, Proposal, and Transform payloads are included + in the Security Association payload (for notation purposes). There + can be only one Proposal and one Transform offered (i.e. no choices) + in order for the aggressive exchange to work. Keying material used + to arrive at a common shared secret and random information which is + used to guarantee liveness and protect against replay attacks are + also transmitted. Random information provided by both parties SHOULD + be used by the authentication mechanism to provide shared proof of + participation in the exchange. Additionally, the initiator transmits + identification information. + + In the second message (2), the responder indicates the protection + suite it has accepted with the Security Association, Proposal, and + Transform payloads. Keying material used to arrive at a common + shared secret and random information which is used to guarantee + liveness and protect against replay attacks is also transmitted. + Random information provided by both parties SHOULD be used by the + authentication mechanism to provide shared proof of participation in + the exchange. Additionally, the responder transmits identification + information. All of this information is transmitted under the + protection of the agreed upon authentication function. Local + security policy dictates the action of the responder if no proposed + protection suite is accepted. One possible action is the + transmission of a Notify payload as part of an Informational + Exchange. + + + + + + +Maughan, et. al. Standards Track [Page 56] + +RFC 2408 ISAKMP November 1998 + + + In the third (3) message, the initiator transmits the results of the + agreed upon authentication function. This information is transmitted + under the protection of the common shared secret. Local security + policy dictates the action if an error occurs during these messages. + One possible action is the transmission of a Notify payload as part + of an Informational Exchange. + +4.8 Informational Exchange + + The Informational Exchange is designed as a one-way transmittal of + information that can be used for security association management. + The following diagram shows the messages with possible payloads sent + in each message and notes for an example of the Informational + Exchange. + + INFORMATIONAL EXCHANGE + + # Initiator Direction Responder NOTE + (1) HDR*; N/D => Error Notification or Deletion + + In the first message (1), the initiator or responder transmits an + ISAKMP Notify or Delete payload. + + If the Informational Exchange occurs prior to the exchange of keying + meterial during an ISAKMP Phase 1 negotiation, there will be no + protection provided for the Informational Exchange. Once keying + material has been exchanged or an ISAKMP SA has been established, the + Informational Exchange MUST be transmitted under the protection + provided by the keying material or the ISAKMP SA. + + All exchanges are similar in that with the beginning of any exchange, + cryptographic synchronization MUST occur. The Informational Exchange + is an exchange and not an ISAKMP message. Thus, the generation of an + Message ID (MID) for an Informational Exchange SHOULD be independent + of IVs of other on-going communication. This will ensure + cryptographic synchronization is maintained for existing + communications and the Informational Exchange will be processed + correctly. The only exception to this is when the Commit Bit of the + ISAKMP Header is set. When the Commit Bit is set, the Message ID + field of the Informational Exchange MUST contain the Message ID of + the original ISAKMP Phase 2 SA negotiation, rather than a new Message + ID (MID). This is done to ensure that the Informational Exchange with + the CONNECTED Notify Message can be associated with the correct Phase + 2 SA. For a description of the Commit Bit, see section 3.1. + + + + + + + +Maughan, et. al. Standards Track [Page 57] + +RFC 2408 ISAKMP November 1998 + + +5 ISAKMP Payload Processing + + Section 3 describes the ISAKMP payloads. These payloads are used in + the exchanges described in section 4 and can be used in exchanges + defined for a specific DOI. This section describes the processing for + each of the payloads. This section suggests the logging of events to + a system audit file. This action is controlled by a system security + policy and is, therefore, only a suggested action. + +5.1 General Message Processing + + Every ISAKMP message has basic processing applied to insure protocol + reliability, and to minimize threats, such as denial of service and + replay attacks. All processing SHOULD include packet length checks + to insure the packet received is at least as long as the length given + in the ISAKMP Header. If the ISAKMP message length and the value in + the Payload Length field of the ISAKMP Header are not the same, then + the ISAKMP message MUST be rejected. The receiving entity (initiator + or responder) MUST do the following: + + 1. The event, UNEQUAL PAYLOAD LENGTHS, MAY be logged in the + appropriate system audit file. + + 2. An Informational Exchange with a Notification payload containing + the UNEQUAL-PAYLOAD-LENGTHS message type MAY be sent to the + transmitting entity. This action is dictated by a system + security policy. + + When transmitting an ISAKMP message, the transmitting entity + (initiator or responder) MUST do the following: + + 1. Set a timer and initialize a retry counter. + + NOTE: Implementations MUST NOT use a fixed timer. Instead, + transmission timer values should be adjusted dynamically based on + measured round trip times. In addition, successive + retransmissions of the same packet should be separated by + increasingly longer time intervals (e.g., exponential backoff). + + 2. If the timer expires, the ISAKMP message is resent and the retry + counter is decremented. + + 3. If the retry counter reaches zero (0), the event, RETRY LIMIT + REACHED, MAY be logged in the appropriate system audit file. + + 4. The ISAKMP protocol machine clears all states and returns to + IDLE. + + + + +Maughan, et. al. Standards Track [Page 58] + +RFC 2408 ISAKMP November 1998 + + +5.2 ISAKMP Header Processing + + When creating an ISAKMP message, the transmitting entity (initiator + or responder) MUST do the following: + + 1. Create the respective cookie. See section 2.5.3 for details. + + 2. Determine the relevant security characteristics of the session + (i.e. DOI and situation). + + 3. Construct an ISAKMP Header with fields as described in section + 3.1. + + 4. Construct other ISAKMP payloads, depending on the exchange type. + + 5. Transmit the message to the destination host as described in + section5.1. + + When an ISAKMP message is received, the receiving entity (initiator + or responder) MUST do the following: + + 1. Verify the Initiator and Responder "cookies". If the cookie + validation fails, the message is discarded and the following + actions are taken: + + (a) The event, INVALID COOKIE, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-COOKIE message type MAY be sent to + the transmitting entity. This action is dictated by a + system security policy. + + 2. Check the Next Payload field to confirm it is valid. If the Next + Payload field validation fails, the message is discarded and the + following actions are taken: + + (a) The event, INVALID NEXT PAYLOAD, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-PAYLOAD-TYPE message type MAY be sent + to the transmitting entity. This action is dictated by a + system security policy. + + 3. Check the Major and Minor Version fields to confirm they are + correct (see section 3.1). If the Version field validation + fails, the message is discarded and the following actions are + + + +Maughan, et. al. Standards Track [Page 59] + +RFC 2408 ISAKMP November 1998 + + + taken: + + (a) The event, INVALID ISAKMP VERSION, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-MAJOR-VERSION or INVALID-MINOR- + VERSION message type MAY be sent to the transmitting entity. + This action is dictated by a system security policy. + + 4. Check the Exchange Type field to confirm it is valid. If the + Exchange Type field validation fails, the message is discarded + and the following actions are taken: + + (a) The event, INVALID EXCHANGE TYPE, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-EXCHANGE-TYPE message type MAY be + sent to the transmitting entity. This action is dictated by + a system security policy. + + 5. Check the Flags field to ensure it contains correct values. If + the Flags field validation fails, the message is discarded and + the following actions are taken: + + (a) The event, INVALID FLAGS, MAY be logged in the appropriate + systemaudit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-FLAGS message type MAY be sent to the + transmitting entity. This action is dictated by a system + security policy. + + 6. Check the Message ID field to ensure it contains correct values. + If the Message ID validation fails, the message is discarded and + the following actions are taken: + + (a) The event, INVALID MESSAGE ID, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-MESSAGE-ID message type MAY be sent + to the transmitting entity. This action is dictated by a + system security policy. + + 7. Processing of the ISAKMP message continues using the value in the + Next Payload field. + + + +Maughan, et. al. Standards Track [Page 60] + +RFC 2408 ISAKMP November 1998 + + +5.3 Generic Payload Header Processing + + When creating any of the ISAKMP Payloads described in sections 3.4 + through 3.15 a Generic Payload Header is placed at the beginning of + these payloads. When creating the Generic Payload Header, the + transmitting entity (initiator or responder) MUST do the following: + + 1. Place the value of the Next Payload in the Next Payload field. + These values are described in section 3.1. + + 2. Place the value zero (0) in the RESERVED field. + + 3. Place the length (in octets) of the payload in the Payload Length + field. + + 4. Construct the payloads as defined in the remainder of this + section. + + When any of the ISAKMP Payloads are received, the receiving entity + (initiator or responder) MUST do the following: + + 1. Check the Next Payload field to confirm it is valid. If the Next + Payload field validation fails, the message is discarded and the + following actions are taken: + + (a) The event, INVALID NEXT PAYLOAD, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-PAYLOAD-TYPE message type MAY be sent + to the transmitting entity. This action is dictated by a + system security policy. + + 2. Verify the RESERVED field contains the value zero. If the value + in the RESERVED field is not zero, the message is discarded and + the following actions are taken: + + (a) The event, INVALID RESERVED FIELD, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the BAD-PROPOSAL-SYNTAX or PAYLOAD-MALFORMED + message type MAY be sent to the transmitting entity. This + action is dictated by a system security policy. + + 3. Process the remaining payloads as defined by the Next Payload + field. + + + + +Maughan, et. al. Standards Track [Page 61] + +RFC 2408 ISAKMP November 1998 + + +5.4 Security Association Payload Processing + + When creating a Security Association Payload, the transmitting entity + (initiator or responder) MUST do the following: + + 1. Determine the Domain of Interpretation for which this negotiation + is being performed. + + 2. Determine the situation within the determined DOI for which this + negotiation is being performed. + + 3. Determine the proposal(s) and transform(s) within the situation. + These are described, respectively, in sections 3.5 and 3.6. + + 4. Construct a Security Association payload. + + 5. Transmit the message to the receiving entity as described in + section 5.1. + + When a Security Association payload is received, the receiving entity + (initiator or responder) MUST do the following: + + 1. Determine if the Domain of Interpretation (DOI) is supported. If + the DOI determination fails, the message is discarded and the + following actions are taken: + + (a) The event, INVALID DOI, MAY be logged in the appropriate + system audit file. + + (b) An Informational Exchange with a Notification payload + containing the DOI-NOT-SUPPORTED message type MAY be sent to + the transmitting entity. This action is dictated by a + system security policy. + + 2. Determine if the given situation can be protected. If the + Situation determination fails, the message is discarded and the + following actions are taken: + + (a) The event, INVALID SITUATION, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the SITUATION-NOT-SUPPORTED message type MAY be + sent to the transmitting entity. This action is dictated by + a system security policy. + + 3. Process the remaining payloads (i.e. Proposal, Transform) of the + Security Association Payload. If the Security Association + + + +Maughan, et. al. Standards Track [Page 62] + +RFC 2408 ISAKMP November 1998 + + + Proposal (as described in sections 5.5 and 5.6) is not accepted, + then the following actions are taken: + + (a) The event, INVALID PROPOSAL, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the NO-PROPOSAL-CHOSEN message type MAY be sent + to the transmitting entity. This action is dictated by a + system security policy. + +5.5 Proposal Payload Processing + + When creating a Proposal Payload, the transmitting entity (initiator + or responder) MUST do the following: + + 1. Determine the Protocol for this proposal. + + 2. Determine the number of proposals to be offered for this protocol + and the number of transforms for each proposal. Transforms are + described in section 3.6. + + 3. Generate a unique pseudo-random SPI. + + 4. Construct a Proposal payload. + + When a Proposal payload is received, the receiving entity (initiator + or responder) MUST do the following: + + 1. Determine if the Protocol is supported. If the Protocol-ID field + is invalid, the payload is discarded and the following actions + are taken: + + (a) The event, INVALID PROTOCOL, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-PROTOCOL-ID message type MAY be sent + to the transmitting entity. This action is dictated by a + system security policy. + + 2. Determine if the SPI is valid. If the SPI is invalid, the + payload is discarded and the following actions are taken: + + (a) The event, INVALID SPI, MAY be logged in the appropriate + system audit file. + + + + + +Maughan, et. al. Standards Track [Page 63] + +RFC 2408 ISAKMP November 1998 + + + (b) An Informational Exchange with a Notification payload + containing the INVALID-SPI message type MAY be sent to the + transmitting entity. This action is dictated by a system + security policy. + + 3. Ensure the Proposals are presented according to the details given + in section 3.5 and 4.2. If the proposals are not formed + correctly, the following actions are taken: + + (a) Possible events, BAD PROPOSAL SYNTAX, INVALID PROPOSAL, are + logged in the appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the BAD-PROPOSAL-SYNTAX or PAYLOAD-MALFORMED + message type MAY be sent to the transmitting entity. This + action is dictated by a system security policy. + + 4. Process the Proposal and Transform payloads as defined by the + Next Payload field. Examples of processing these payloads are + given in section 4.2.1. + +5.6 Transform Payload Processing + + When creating a Transform Payload, the transmitting entity (initiator + or responder) MUST do the following: + + 1. Determine the Transform # for this transform. + + 2. Determine the number of transforms to be offered for this + proposal. Transforms are described in sections 3.6. + + 3. Construct a Transform payload. + + When a Transform payload is received, the receiving entity (initiator + or responder) MUST do the following: + + 1. Determine if the Transform is supported. If the Transform-ID + field contains an unknown or unsupported value, then that + Transform payload MUST be ignored and MUST NOT cause the + generation of an INVALID TRANSFORM event. If the Transform-ID + field is invalid, the payload is discarded and the following + actions are taken: + + (a) The event, INVALID TRANSFORM, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-TRANSFORM-ID message type MAY be sent + + + +Maughan, et. al. Standards Track [Page 64] + +RFC 2408 ISAKMP November 1998 + + + to the transmitting entity. This action is dictated by a + system security policy. + + 2. Ensure the Transforms are presented according to the details + given in section 3.6 and 4.2. If the transforms are not formed + correctly, the following actions are taken: + + (a) Possible events, BAD PROPOSAL SYNTAX, INVALID TRANSFORM, + INVALID ATTRIBUTES, are logged in the appropriate system + audit file. + + (b) An Informational Exchange with a Notification payload + containing the BAD-PROPOSAL-SYNTAX, PAYLOAD-MALFORMED or + ATTRIBUTES-NOT-SUPPORTED message type MAY be sent to the + transmitting entity. This action is dictated by a system + security policy. + + 3. Process the subsequent Transform and Proposal payloads as defined + by the Next Payload field. Examples of processing these payloads + are given in section 4.2.1. + +5.7 Key Exchange Payload Processing + + When creating a Key Exchange Payload, the transmitting entity + (initiator or responder) MUST do the following: + + 1. Determine the Key Exchange to be used as defined by the DOI. + + 2. Determine the usage of the Key Exchange Data field as defined by + the DOI. + + 3. Construct a Key Exchange payload. + + 4. Transmit the message to the receiving entity as described in + section 5.1. + + When a Key Exchange payload is received, the receiving entity + (initiator or responder) MUST do the following: + + 1. Determine if the Key Exchange is supported. If the Key Exchange + determination fails, the message is discarded and the following + actions are taken: + + (a) The event, INVALID KEY INFORMATION, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-KEY-INFORMATION message type MAY be + + + +Maughan, et. al. Standards Track [Page 65] + +RFC 2408 ISAKMP November 1998 + + + sent to the transmitting entity. This action is dictated by + a system security policy. + +5.8 Identification Payload Processing + + When creating an Identification Payload, the transmitting entity + (initiator or responder) MUST do the following: + + 1. Determine the Identification information to be used as defined by + the DOI (and possibly the situation). + + 2. Determine the usage of the Identification Data field as defined + by the DOI. + + 3. Construct an Identification payload. + + 4. Transmit the message to the receiving entity as described in + section 5.1. + + When an Identification payload is received, the receiving entity + (initiator or responder) MUST do the following: + + 1. Determine if the Identification Type is supported. This may be + based on the DOI and Situation. If the Identification + determination fails, the message is discarded and the following + actions are taken: + + (a) The event, INVALID ID INFORMATION, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-ID-INFORMATION message type MAY be + sent to the transmitting entity. This action is dictated by + a system security policy. + +5.9 Certificate Payload Processing + + When creating a Certificate Payload, the transmitting entity + (initiator or responder) MUST do the following: + + 1. Determine the Certificate Encoding to be used. This may be + specified by the DOI. + + 2. Ensure the existence of a certificate formatted as defined by the + Certificate Encoding. + + 3. Construct a Certificate payload. + + + + +Maughan, et. al. Standards Track [Page 66] + +RFC 2408 ISAKMP November 1998 + + + 4. Transmit the message to the receiving entity as described in + section 5.1. + + When a Certificate payload is received, the receiving entity + (initiator or responder) MUST do the following: + + 1. Determine if the Certificate Encoding is supported. If the + Certificate Encoding is not supported, the payload is discarded + and the following actions are taken: + + (a) The event, INVALID CERTIFICATE TYPE, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-CERT-ENCODING message type MAY be + sent to the transmitting entity. This action is dictated by + a system security policy. + + 2. Process the Certificate Data field. If the Certificate Data is + invalid or improperly formatted, the payload is discarded and the + following actions are taken: + + (a) The event, INVALID CERTIFICATE, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-CERTIFICATE message type MAY be sent + to the transmitting entity. This action is dictated by a + system security policy. + +5.10 Certificate Request Payload Processing + + When creating a Certificate Request Payload, the transmitting entity + (initiator or responder) MUST do the following: + + 1. Determine the type of Certificate Encoding to be requested. This + may be specified by the DOI. + + 2. Determine the name of an acceptable Certificate Authority which + is to be requested (if applicable). + + 3. Construct a Certificate Request payload. + + 4. Transmit the message to the receiving entity as described in + section 5.1. + + When a Certificate Request payload is received, the receiving entity + (initiator or responder) MUST do the following: + + + +Maughan, et. al. Standards Track [Page 67] + +RFC 2408 ISAKMP November 1998 + + + 1. Determine if the Certificate Encoding is supported. If the + Certificate Encoding is invalid, the payload is discarded and the + following actions are taken: + + (a) The event, INVALID CERTIFICATE TYPE, MAY be logged in + the appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-CERT-ENCODING message type MAY be + sent to the transmitting entity. This action is dictated by + a system security policy. + + If the Certificate Encoding is not supported, the payload is + discarded and the following actions are taken: + + (a) The event, CERTIFICATE TYPE UNSUPPORTED, MAY be logged in + the appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the CERT-TYPE-UNSUPPORTED message type MAY be + sent to the transmitting entity. This action is dictated by + a system security policy. + + 2. Determine if the Certificate Authority is supported for the + specified Certificate Encoding. If the Certificate Authority is + invalid or improperly formatted, the payload is discarded and the + following actions are taken: + + (a) The event, INVALID CERTIFICATE AUTHORITY, MAY be logged in + the appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-CERT-AUTHORITY message type MAY be + sent to the transmitting entity. This action is dictated by + a system security policy. + + 3. Process the Certificate Request. If a requested Certificate Type + with the specified Certificate Authority is not available, then + the payload is discarded and the following actions are taken: + + (a) The event, CERTIFICATE-UNAVAILABLE, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the CERTIFICATE-UNAVAILABLE message type MAY be + sent to the transmitting entity. This action is dictated by + a system security policy. + + + + +Maughan, et. al. Standards Track [Page 68] + +RFC 2408 ISAKMP November 1998 + + +5.11 Hash Payload Processing + + When creating a Hash Payload, the transmitting entity (initiator or + responder) MUST do the following: + + 1. Determine the Hash function to be used as defined by the SA + negotiation. + + 2. Determine the usage of the Hash Data field as defined by the DOI. + + 3. Construct a Hash payload. + + 4. Transmit the message to the receiving entity as described in + section 5.1. + + When a Hash payload is received, the receiving entity (initiator or + responder) MUST do the following: + + 1. Determine if the Hash is supported. If the Hash determination + fails, the message is discarded and the following actions are + taken: + + (a) The event, INVALID HASH INFORMATION, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-HASH-INFORMATION message type MAY be + sent to the transmitting entity. This action is dictated by + a system security policy. + + 2. Perform the Hash function as outlined in the DOI and/or Key + Exchange protocol documents. If the Hash function fails, the + message is discarded and the following actions are taken: + + (a) The event, INVALID HASH VALUE, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the AUTHENTICATION-FAILED message type MAY be + sent to the transmitting entity. This action is dictated by + a system security policy. + +5.12 Signature Payload Processing + + When creating a Signature Payload, the transmitting entity (initiator + or responder) MUST do the following: + + + + + +Maughan, et. al. Standards Track [Page 69] + +RFC 2408 ISAKMP November 1998 + + + 1. Determine the Signature function to be used as defined by the SA + negotiation. + + 2. Determine the usage of the Signature Data field as defined by the + DOI. + + 3. Construct a Signature payload. + + 4. Transmit the message to the receiving entity as described in + section 5.1. + + When a Signature payload is received, the receiving entity (initiator + or responder) MUST do the following: + + 1. Determine if the Signature is supported. If the Signature + determination fails, the message is discarded and the following + actions are taken: + + (a) The event, INVALID SIGNATURE INFORMATION, MAY be logged in + the appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the INVALID-SIGNATURE message type MAY be sent to + the transmitting entity. This action is dictated by a + system security policy. + + 2. Perform the Signature function as outlined in the DOI and/or Key + Exchange protocol documents. If the Signature function fails, + the message is discarded and the following actions are taken: + + (a) The event, INVALID SIGNATURE VALUE, MAY be logged in the + appropriate system audit file. + + (b) An Informational Exchange with a Notification payload + containing the AUTHENTICATION-FAILED message type MAY be + sent to the transmitting entity. This action is dictated by + a system security policy. + +5.13 Nonce Payload Processing + + When creating a Nonce Payload, the transmitting entity (initiator or + responder) MUST do the following: + + 1. Create a unique random value to be used as a nonce. + + 2. Construct a Nonce payload. + + + + + +Maughan, et. al. Standards Track [Page 70] + +RFC 2408 ISAKMP November 1998 + + + 3. Transmit the message to the receiving entity as described in + section 5.1. + + When a Nonce payload is received, the receiving entity (initiator or + responder) MUST do the following: + + 1. There are no specific procedures for handling Nonce payloads. + The procedures are defined by the exchange types (and possibly + the DOI and Key Exchange descriptions). + +5.14 Notification Payload Processing + + During communications it is possible that errors may occur. The + Informational Exchange with a Notify Payload provides a controlled + method of informing a peer entity that errors have occurred during + protocol processing. It is RECOMMENDED that Notify Payloads be sent + in a separate Informational Exchange rather than appending a Notify + Payload to an existing exchange. + + When creating a Notification Payload, the transmitting entity + (initiator or responder) MUST do the following: + + 1. Determine the DOI for this Notification. + + 2. Determine the Protocol-ID for this Notification. + + 3. Determine the SPI size based on the Protocol-ID field. This + field is necessary because different security protocols have + different SPI sizes. For example, ISAKMP combines the Initiator + and Responder cookie pair (16 octets) as a SPI, while ESP and AH + have 4 octet SPIs. + + 4. Determine the Notify Message Type based on the error or status + message desired. + + 5. Determine the SPI which is associated with this notification. + + 6. Determine if additional Notification Data is to be included. + This is additional information specified by the DOI. + + 7. Construct a Notification payload. + + 8. Transmit the message to the receiving entity as described in + section 5.1. + + Because the Informational Exchange with a Notification payload is a + unidirectional message a retransmission will not be performed. The + local security policy will dictate the procedures for continuing. + + + +Maughan, et. al. Standards Track [Page 71] + +RFC 2408 ISAKMP November 1998 + + + However, we RECOMMEND that a NOTIFICATION PAYLOAD ERROR event be + logged in the appropriate system audit file by the receiving entity. + + If the Informational Exchange occurs prior to the exchange of keying + material during an ISAKMP Phase 1 negotiation there will be no + protection provided for the Informational Exchange. Once the keying + material has been exchanged or the ISAKMP SA has been established, + the Informational Exchange MUST be transmitted under the protection + provided by the keying material or the ISAKMP SA. + + When a Notification payload is received, the receiving entity + (initiator or responder) MUST do the following: + + 1. Determine if the Informational Exchange has any protection + applied to it by checking the Encryption Bit and the + Authentication Only Bit in the ISAKMP Header. If the Encryption + Bit is set, i.e. the Informational Exchange is encrypted, then + the message MUST be decrypted using the (in-progress or + completed) ISAKMP SA. Once the decryption is complete the + processing can continue as described below. If the + Authentication Only Bit is set, then the message MUST be + authenticated using the (in-progress or completed) ISAKMP SA. + Once the authentication is completed, the processing can continue + as described below. If the Informational Exchange is not + encrypted or authentication, the payload processing can continue + as described below. + + 2. Determine if the Domain of Interpretation (DOI) is supported. If + the DOI determination fails, the payload is discarded and the + following action is taken: + + (a) The event, INVALID DOI, MAY be logged in the appropriate + system audit file. + + 3. Determine if the Protocol-Id is supported. If the Protocol-Id + determination fails, the payload is discarded and the following + action is taken: + + (a) The event, INVALID PROTOCOL-ID, MAY be logged in the + appropriate system audit file. + + 4. Determine if the SPI is valid. If the SPI is invalid, the + payload is discarded and the following action is taken: + + (a) The event, INVALID SPI, MAY be logged in the appropriate + system audit file. + + + + + +Maughan, et. al. Standards Track [Page 72] + +RFC 2408 ISAKMP November 1998 + + + 5. Determine if the Notify Message Type is valid. If the Notify + Message Type is invalid, the payload is discarded and the + following action is taken: + + (a) The event, INVALID MESSAGE TYPE, MAY be logged in the + appropriate system audit file. + + 6. Process the Notification payload, including additional + Notification Data, and take appropriate action, according to + local security policy. + +5.15 Delete Payload Processing + + During communications it is possible that hosts may be compromised or + that information may be intercepted during transmission. Determining + whether this has occurred is not an easy task and is outside the + scope of this memo. However, if it is discovered that transmissions + are being compromised, then it is necessary to establish a new SA and + delete the current SA. + + The Informational Exchange with a Delete Payload provides a + controlled method of informing a peer entity that the transmitting + entity has deleted the SA(s). Deletion of Security Associations MUST + always be performed under the protection of an ISAKMP SA. The + receiving entity SHOULD clean up its local SA database. However, + upon receipt of a Delete message the SAs listed in the Security + Parameter Index (SPI) field of the Delete payload cannot be used with + the transmitting entity. The SA Establishment procedure must be + invoked to re-establish secure communications. + + When creating a Delete Payload, the transmitting entity (initiator or + responder) MUST do the following: + + 1. Determine the DOI for this Deletion. + + 2. Determine the Protocol-ID for this Deletion. + + 3. Determine the SPI size based on the Protocol-ID field. This + field is necessary because different security protocols have + different SPI sizes. For example, ISAKMP combines the Initiator + and Responder cookie pair (16 octets) as a SPI, while ESP and AH + have 4 octet SPIs. + + 4. Determine the # of SPIs to be deleted for this protocol. + + 5. Determine the SPI(s) which is (are) associated with this + deletion. + + + + +Maughan, et. al. Standards Track [Page 73] + +RFC 2408 ISAKMP November 1998 + + + 6. Construct a Delete payload. + + 7. Transmit the message to the receiving entity as described in + section 5.1. + + Because the Informational Exchange with a Delete payload is a + unidirectional message a retransmission will not be performed. The + local security policy will dictate the procedures for continuing. + However, we RECOMMEND that a DELETE PAYLOAD ERROR event be logged in + the appropriate system audit file by the receiving entity. + + As described above, the Informational Exchange with a Delete payload + MUST be transmitted under the protection provided by an ISAKMP SA. + + When a Delete payload is received, the receiving entity (initiator or + responder) MUST do the following: + + 1. Because the Informational Exchange is protected by some security + service (e.g. authentication for an Auth-Only SA, encryption for + other exchanges), the message MUST have these security services + applied using the ISAKMP SA. Once the security service processing + is complete the processing can continue as described below. Any + errors that occur during the security service processing will be + evident when checking information in the Delete payload. The + local security policy SHOULD dictate any action to be taken as a + result of security service processing errors. + + 2. Determine if the Domain of Interpretation (DOI) is supported. If + the DOI determination fails, the payload is discarded and the + following action is taken: + + (a) The event, INVALID DOI, MAY be logged in the appropriate + system audit file. + + 3. Determine if the Protocol-Id is supported. If the Protocol-Id + determination fails, the payload is discarded and the following + action is taken: + + (a) The event, INVALID PROTOCOL-ID, MAY be logged in the + appropriate system audit file. + + 4. Determine if the SPI is valid for each SPI included in the Delete + payload. For each SPI that is invalid, the following action is + taken: + + (a) The event, INVALID SPI, MAY be logged in the appropriate + system audit file. + + + + +Maughan, et. al. Standards Track [Page 74] + +RFC 2408 ISAKMP November 1998 + + + 5. Process the Delete payload and take appropriate action, according + to local security policy. As described above, one appropriate + action SHOULD include cleaning up the local SA database. + +6 Conclusions + + The Internet Security Association and Key Management Protocol + (ISAKMP) is a well designed protocol aimed at the Internet of the + future. The massive growth of the Internet will lead to great + diversity in network utilization, communications, security + requirements, and security mechanisms. ISAKMP contains all the + features that will be needed for this dynamic and expanding + communications environment. + + ISAKMP's Security Association (SA) feature coupled with + authentication and key establishment provides the security and + flexibility that will be needed for future growth and diversity. + This security diversity of multiple key exchange techniques, + encryption algorithms, authentication mechanisms, security services, + and security attributes will allow users to select the appropriate + security for their network, communications, and security needs. The + SA feature allows users to specify and negotiate security + requirements with other users. An additional benefit of supporting + multiple techniques in a single protocol is that as new techniques + are developed they can easily be added to the protocol. This + provides a path for the growth of Internet security services. ISAKMP + supports both publicly or privately defined SAs, making it ideal for + government, commercial, and private communications. + + ISAKMP provides the ability to establish SAs for multiple security + protocols and applications. These protocols and applications may be + session-oriented or sessionless. Having one SA establishment + protocol that supports multiple security protocols eliminates the + need for multiple, nearly identical authentication, key exchange and + SA establishment protocols when more than one security protocol is in + use or desired. Just as IP has provided the common networking layer + for the Internet, a common security establishment protocol is needed + if security is to become a reality on the Internet. ISAKMP provides + the common base that allows all other security protocols to + interoperate. + + ISAKMP follows good security design principles. It is not coupled to + other insecure transport protocols, therefore it is not vulnerable or + weakened by attacks on other protocols. Also, when more secure + transport protocols are developed, ISAKMP can be easily migrated to + them. ISAKMP also provides protection against protocol related + attacks. This protection provides the assurance that the SAs and + keys established are with the desired party and not with an attacker. + + + +Maughan, et. al. Standards Track [Page 75] + +RFC 2408 ISAKMP November 1998 + + + ISAKMP also follows good protocol design principles. Protocol + specific information only is in the protocol header, following the + design principles of IPv6. The data transported by the protocol is + separated into functional payloads. As the Internet grows and + evolves, new payloads to support new security functionality can be + added without modifying the entire protocol. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Maughan, et. al. Standards Track [Page 76] + +RFC 2408 ISAKMP November 1998 + + +A ISAKMP Security Association Attributes + +A.1 Background/Rationale + + As detailed in previous sections, ISAKMP is designed to provide a + flexible and extensible framework for establishing and managing + Security Associations and cryptographic keys. The framework provided + by ISAKMP consists of header and payload definitions, exchange types + for guiding message and payload exchanges, and general processing + guidelines. ISAKMP does not define the mechanisms that will be used + to establish and manage Security Associations and cryptographic keys + in an authenticated and confidential manner. The definition of + mechanisms and their application is the purview of individual Domains + of Interpretation (DOIs). + + This section describes the ISAKMP values for the Internet IP Security + DOI, supported security protocols, and identification values for + ISAKMP Phase 1 negotiations. The Internet IP Security DOI is + MANDATORY to implement for IP Security. [Oakley] and [IKE] describe, + in detail, the mechanisms and their application for establishing and + managing Security Associations and cryptographic keys for IP + Security. + +A.2 Internet IP Security DOI Assigned Value + + As described in [IPDOI], the Internet IP Security DOI Assigned Number + is one (1). + +A.3 Supported Security Protocols + + Values for supported security protocols are specified in the most + recent "Assigned Numbers" RFC [STD-2]. Presented in the following + table are the values for the security protocols supported by ISAKMP + for the Internet IP Security DOI. + + + Protocol Assigned Value + RESERVED 0 + ISAKMP 1 + + All DOIs MUST reserve ISAKMP with a Protocol-ID of 1. All other + security protocols within that DOI will be numbered accordingly. + + Security protocol values 2-15359 are reserved to IANA for future use. + Values 15360-16383 are permanently reserved for private use amongst + mutually consenting implementations. Such private use values are + unlikely to be interoperable across different implementations. + + + + +Maughan, et. al. Standards Track [Page 77] + +RFC 2408 ISAKMP November 1998 + + +A.4 ISAKMP Identification Type Values + + The following table lists the assigned values for the Identification + Type field found in the Identification payload during a generic Phase + 1 exchange, which is not for a specific protocol. + + + ID Type Value + ID_IPV4_ADDR 0 + ID_IPV4_ADDR_SUBNET 1 + ID_IPV6_ADDR 2 + ID_IPV6_ADDR_SUBNET 3 + +A.4.1 ID_IPV4_ADDR + + The ID_IPV4_ADDR type specifies a single four (4) octet IPv4 address. + +A.4.2 ID_IPV4_ADDR_SUBNET + + The ID_IPV4_ADDR_SUBNET type specifies a range of IPv4 addresses, + represented by two four (4) octet values. The first value is an IPv4 + address. The second is an IPv4 network mask. Note that ones (1s) in + the network mask indicate that the corresponding bit in the address + is fixed, while zeros (0s) indicate a "wildcard" bit. + +A.4.3 ID_IPV6_ADDR + + The ID_IPV6_ADDR type specifies a single sixteen (16) octet IPv6 + address. + +A.4.4 ID_IPV6_ADDR_SUBNET + + The ID_IPV6_ADDR_SUBNET type specifies a range of IPv6 addresses, + represented by two sixteen (16) octet values. The first value is an + IPv6 address. The second is an IPv6 network mask. Note that ones + (1s) in the network mask indicate that the corresponding bit in the + address is fixed, while zeros (0s) indicate a "wildcard" bit. + + + + + + + + + + + + + + +Maughan, et. al. Standards Track [Page 78] + +RFC 2408 ISAKMP November 1998 + + +B Defining a new Domain of Interpretation + + The Internet DOI may be sufficient to meet the security requirements + of a large portion of the internet community. However, some groups + may have a need to customize some aspect of a DOI, perhaps to add a + different set of cryptographic algorithms, or perhaps because they + want to make their security-relevant decisions based on something + other than a host id or user id. Also, a particular group may have a + need for a new exchange type, for example to support key management + for multicast groups. + + This section discusses guidelines for defining a new DOI. The full + specification for the Internet DOI can be found in [IPDOI]. + + Defining a new DOI is likely to be a time-consuming process. If at + all possible, it is recommended that the designer begin with an + existing DOI and customize only the parts that are unacceptable. + + If a designer chooses to start from scratch, the following MUST be + defined: + + o A "situation": the set of information that will be used to + determine the required security services. + + o The set of security policies that must be supported. + + o A scheme for naming security-relevant information, including + encryption algorithms, key exchange algorithms, etc. + + o A syntax for the specification of proposed security services, + attributes, and certificate authorities. + + o The specific formats of the various payload contents. + + o Additional exchange types, if required. + +B.1 Situation + + The situation is the basis for deciding how to protect a + communications channel. It must contain all of the data that will be + used to determine the types and strengths of protections applied in + an SA. For example, a US Department of Defense DOI would probably use + unpublished algorithms and have additional special attributes to + negotiate. These additional security attributes would be included in + the situation. + + + + + + +Maughan, et. al. Standards Track [Page 79] + +RFC 2408 ISAKMP November 1998 + + +B.2 Security Policies + + Security policies define how various types of information must be + categorized and protected. The DOI must define the set of security + policies supported, because both parties in a negotiation must trust + that the other party understands a situation, and will protect + information appropriately, both in transit and in storage. In a + corporate setting, for example, both parties in a negotiation must + agree to the meaning of the term "proprietary information" before + they can negotiate how to protect it. + + Note that including the required security policies in the DOI only + specifies that the participating hosts understand and implement those + policies in a full system context. + +B.3 Naming Schemes + + Any DOI must define a consistent way to name cryptographic + algorithms, certificate authorities, etc. This can usually be done + by using IANA naming conventions, perhaps with some private + extensions. + +B.4 Syntax for Specifying Security Services + + In addition to simply specifying how to name entities, the DOI must + also specify the format for complete proposals of how to protect + traffic under a given situation. + +B.5 Payload Specification + + The DOI must specify the format of each of the payload types. For + several of the payload types, ISAKMP has included fields that would + have to be present across all DOI (such as a certificate authority in + the certificate payload, or a key exchange identifier in the key + exchange payload). + +B.6 Defining new Exchange Types + + If the basic exchange types are inadequate to meet the requirements + within a DOI, a designer can define up to thirteen extra exchange + types per DOI. The designer creates a new exchange type by choosing + an unused exchange type value, and defining a sequence of messages + composed of strings of the ISAKMP payload types. + + Note that any new exchange types must be rigorously analyzed for + vulnerabilities. Since this is an expensive and imprecise + undertaking, a new exchange type should only be created when + absolutely necessary. + + + +Maughan, et. al. Standards Track [Page 80] + +RFC 2408 ISAKMP November 1998 + + +Security Considerations + + Cryptographic analysis techniques are improving at a steady pace. + The continuing improvement in processing power makes once + computationally prohibitive cryptographic attacks more realistic. + New cryptographic algorithms and public key generation techniques are + also being developed at a steady pace. New security services and + mechanisms are being developed at an accelerated pace. A consistent + method of choosing from a variety of security services and mechanisms + and to exchange attributes required by the mechanisms is important to + security in the complex structure of the Internet. However, a system + that locks itself into a single cryptographic algorithm, key exchange + technique, or security mechanism will become increasingly vulnerable + as time passes. + + UDP is an unreliable datagram protocol and therefore its use in + ISAKMP introduces a number of security considerations. Since UDP is + unreliable, but a key management protocol must be reliable, the + reliability is built into ISAKMP. While ISAKMP utilizes UDP as its + transport mechanism, it doesn't rely on any UDP information (e.g. + checksum, length) for its processing. + + Another issue that must be considered in the development of ISAKMP is + the effect of firewalls on the protocol. Many firewalls filter out + all UDP packets, making reliance on UDP questionable in certain + environments. + + A number of very important security considerations are presented in + [SEC-ARCH]. One bears repeating. Once a private session key is + created, it must be safely stored. Failure to properly protect the + private key from access both internal and external to the system + completely nullifies any protection provided by the IP Security + services. + +IANA Considerations + + This document contains many "magic" numbers to be maintained by the + IANA. This section explains the criteria to be used by the IANA to + assign additional numbers in each of these lists. + +Domain of Interpretation + + The Domain of Interpretation (DOI) is a 32-bit field which identifies + the domain under which the security association negotiation is taking + place. Requests for assignments of new DOIs must be accompanied by a + standards-track RFC which describes the specific domain. + + + + + +Maughan, et. al. Standards Track [Page 81] + +RFC 2408 ISAKMP November 1998 + + +Supported Security Protocols + + ISAKMP is designed to provide security association negotiation and + key management for many security protocols. Requests for identifiers + for additional security protocols must be accompanied by a + standards-track RFC which describes the security protocol and its + relationship to ISAKMP. + +Acknowledgements + + Dan Harkins, Dave Carrel, and Derrell Piper of Cisco Systems provided + design assistance with the protocol and coordination for the [IKE] + and [IPDOI] documents. + + Hilarie Orman, via the Oakley key exchange protocol, has + significantly influenced the design of ISAKMP. + + Marsha Gross, Bill Kutz, Mike Oehler, Pete Sell, and Ruth Taylor + provided significant input and review to this document. + + Scott Carlson ported the TIS DNSSEC prototype to FreeBSD for use with + the ISAKMP prototype. + + Jeff Turner and Steve Smalley contributed to the prototype + development and integration with ESP and AH. + + Mike Oehler and Pete Sell performed interoperability testing with + other ISAKMP implementors. + + Thanks to Carl Muckenhirn of SPARTA, Inc. for his assistance with + LaTeX. + +References + + [ANSI] ANSI, X9.42: Public Key Cryptography for the Financial + Services Industry -- Establishment of Symmetric Algorithm + Keys Using Diffie-Hellman, Working Draft, April 19, 1996. + + [BC] Ballardie, A., and J. Crowcroft, Multicast-specific + Security Threats and Countermeasures, Proceedings of 1995 + ISOC Symposium on Networks & Distributed Systems Security, + pp. 17-30, Internet Society, San Diego, CA, February 1995. + + [Berge] Berge, N., "UNINETT PCA Policy Statements", RFC 1875, + December 1995. + + + + + + +Maughan, et. al. Standards Track [Page 82] + +RFC 2408 ISAKMP November 1998 + + + [CW87] Clark, D.D. and D.R. Wilson, A Comparison of Commercial + and Military Computer Security Policies, Proceedings of + the IEEE Symposium on Security & Privacy, Oakland, CA, + 1987, pp. 184-193. + + [DNSSEC] D. Eastlake III, Domain Name System Protocol Security + Extensions, Work in Progress. + + [DOW92] Diffie, W., M.Wiener, P. Van Oorschot, Authentication and + Authenticated Key Exchanges, Designs, Codes, and + Cryptography, 2, 107-125, Kluwer Academic Publishers, + 1992. + + [IAB] Bellovin, S., "Report of the IAB Security Architecture + Workshop", RFC 2316, April 1998. + + [IKE] Harkins, D., and D. Carrel, "The Internet Key Exchange + (IKE)", RFC 2409, November 1998. + + [IPDOI] Piper, D., "The Internet IP Security Domain of + Interpretation for ISAKMP", RFC 2407, November 1998. + + [Karn] Karn, P., and B. Simpson, Photuris: Session Key + Management Protocol, Work in Progress. + + [Kent94] Steve Kent, IPSEC SMIB, e-mail to ipsec@ans.net, August + 10, 1994. + + [Oakley] Orman, H., "The Oakley Key Determination Protocol", RFC + 2412, November 1998. + + [RFC-1422] Kent, S., "Privacy Enhancement for Internet Electronic + Mail: Part II: Certificate-Based Key Management", RFC + 1422, February 1993. + + [RFC-1949] Ballardie, A., "Scalable Multicast Key Distribution", RFC + 1949, May 1996. + + [RFC-2093] Harney, H., and C. Muckenhirn, "Group Key Management + Protocol (GKMP) Specification", RFC 2093, July 1997. + + [RFC-2094] Harney, H., and C. Muckenhirn, "Group Key Management + Protocol (GKMP) Architecture", RFC 2094, July 1997. + + [RFC-2119] Bradner, S., "Key Words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + + + + +Maughan, et. al. Standards Track [Page 83] + +RFC 2408 ISAKMP November 1998 + + + [Schneier] Bruce Schneier, Applied Cryptography - Protocols, + Algorithms, and Source Code in C (Second Edition), John + Wiley & Sons, Inc., 1996. + + [SEC-ARCH] Atkinson, R., and S. Kent, "Security Architecture for the + Internet Protocol", RFC 2401, November 1998. + + [STD-2] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC + 1700, October 1994. See also: + http://www.iana.org/numbers.html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Maughan, et. al. Standards Track [Page 84] + +RFC 2408 ISAKMP November 1998 + + +Authors' Addresses + + Douglas Maughan + National Security Agency + ATTN: R23 + 9800 Savage Road + Ft. Meade, MD. 20755-6000 + + Phone: 301-688-0847 + EMail:wdm@tycho.ncsc.mil + + + Mark Schneider + National Security Agency + ATTN: R23 + 9800 Savage Road + Ft. Meade, MD. 20755-6000 + + Phone: 301-688-0851 + EMail:mss@tycho.ncsc.mil + + + Mark Schertler + Securify, Inc. + 2415-B Charleston Road + Mountain View, CA 94043 + + Phone: 650-934-9303 + EMail:mjs@securify.com + + + Jeff Turner + RABA Technologies, Inc. + 10500 Little Patuxent Parkway + Columbia, MD. 21044 + + Phone: 410-715-9399 + EMail:jeff.turner@raba.com + + + + + + + + + + + + + +Maughan, et. al. Standards Track [Page 85] + +RFC 2408 ISAKMP November 1998 + + +Full Copyright Statement + + Copyright (C) The Internet Society (1998). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + + + + + + + + + + + + + + + + + + + + + + + +Maughan, et. al. Standards Track [Page 86] + diff --git a/crypto/dist/ipsec-tools/src/racoon/rfc/rfc3706.txt b/crypto/dist/ipsec-tools/src/racoon/rfc/rfc3706.txt new file mode 100644 index 0000000000000..3198e5e9e56f3 --- /dev/null +++ b/crypto/dist/ipsec-tools/src/racoon/rfc/rfc3706.txt @@ -0,0 +1,731 @@ + + + + + + +Network Working Group G. Huang +Request for Comments: 3706 S. Beaulieu +Category: Informational D. Rochefort + Cisco Systems, Inc. + February 2004 + + + A Traffic-Based Method of Detecting Dead Internet + Key Exchange (IKE) Peers + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2004). All Rights Reserved. + +Abstract + + This document describes the method detecting a dead Internet Key + Exchange (IKE) peer that is presently in use by a number of vendors. + The method, called Dead Peer Detection (DPD) uses IPSec traffic + patterns to minimize the number of IKE messages that are needed to + confirm liveness. DPD, like other keepalive mechanisms, is needed to + determine when to perform IKE peer failover, and to reclaim lost + resources. + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. Document Roadmap . . . . . . . . . . . . . . . . . . . . . . . 3 + 3. Rationale for Periodic Message Exchange for Proof of + Liveliness . . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 4. Keepalives vs. Heartbeats . . . . . . . . . . . . . . . . . . 3 + 4.1. Keepalives . . . . . . . . . . . . . . . . . . . . . . . 3 + 4.2. Heartbeats . . . . . . . . . . . . . . . . . . . . . . . 5 + 5. DPD Protocol . . . . . . . . . . . . . . . . . . . . . . . . . 6 + 5.1. DPD Vendor ID. . . . . . . . . . . . . . . . . . . . . . 7 + 5.2. Message Exchanges. . . . . . . . . . . . . . . . . . . . 7 + 5.3. NOTIFY(R-U-THERE/R-U-THERE-ACK) Message Format . . . . . 8 + 5.4. Impetus for DPD Exchange . . . . . . . . . . . . . . . . 9 + 5.5. Implementation Suggestion. . . . . . . . . . . . . . . . 9 + 5.6. Comparisons. . . . . . . . . . . . . . . . . . . . . . . 10 + 6. Resistance to Replay Attack and False Proof of Liveliness. . . 10 + 6.1. Sequence Number in DPD Messages. . . . . . . . . . . . . 10 + + + +Huang, et al. Informational [Page 1] + +RFC 3706 Detecting Dead IKE Peers February 2004 + + + 6.2. Selection and Maintenance of Sequence Numbers. . . . . . 11 + 7. Security Considerations. . . . . . . . . . . . . . . . . . . . 11 + 8. IANA Considerations. . . . . . . . . . . . . . . . . . . . . . 12 + 9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 12 + 9.1. Normative Reference. . . . . . . . . . . . . . . . . . . 12 + 9.2. Informative References . . . . . . . . . . . . . . . . . 12 + 10. Editors' Addresses . . . . . . . . . . . . . . . . . . . . . . 12 + 11. Full Copyright Statement . . . . . . . . . . . . . . . . . . . 13 + +1. Introduction + + When two peers communicate with IKE [2] and IPSec [3], the situation + may arise in which connectivity between the two goes down + unexpectedly. This situation can arise because of routing problems, + one host rebooting, etc., and in such cases, there is often no way + for IKE and IPSec to identify the loss of peer connectivity. As + such, the SAs can remain until their lifetimes naturally expire, + resulting in a "black hole" situation where packets are tunneled to + oblivion. It is often desirable to recognize black holes as soon as + possible so that an entity can failover to a different peer quickly. + Likewise, it is sometimes necessary to detect black holes to recover + lost resources. + + This problem of detecting a dead IKE peer has been addressed by + proposals that require sending periodic HELLO/ACK messages to prove + liveliness. These schemes tend to be unidirectional (a HELLO only) + or bidirectional (a HELLO/ACK pair). For the purpose of this + document, the term "heartbeat" will refer to a unidirectional message + to prove liveliness. Likewise, the term "keepalive" will refer to a + bidirectional message. + + The problem with current heartbeat and keepalive proposals is their + reliance upon their messages to be sent at regular intervals. In the + implementation, this translates into managing some timer to service + these message intervals. Similarly, because rapid detection of the + dead peer is often desired, these messages must be sent with some + frequency, again translating into considerable overhead for message + processing. In implementations and installations where managing + large numbers of simultaneous IKE sessions is of concern, these + regular heartbeats/keepalives prove to be infeasible. + + To this end, a number of vendors have implemented their own approach + to detect peer liveliness without needing to send messages at regular + intervals. This informational document describes the current + practice of those implementations. This scheme, called Dead Peer + Detection (DPD), relies on IKE Notify messages to query the + liveliness of an IKE peer. + + + + +Huang, et al. Informational [Page 2] + +RFC 3706 Detecting Dead IKE Peers February 2004 + + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in RFC-2119 [1]. + +2. Document Roadmap + + As mentioned above, there are already proposed solutions to the + problem of detecting dead peers. Section 3 elaborates the rationale + for using an IKE message exchange to query a peer's liveliness. + Section 4 examines a keepalives-based approach as well as a + heartbeats-based approach. Section 5 presents the DPD proposal + fully, highlighting differences between DPD and the schemes presented + in Section 4 and emphasizing scalability issues. Section 6 examines + security issues surrounding replayed messages and false liveliness. + +3. Rationale for Periodic Message Exchange for Proof of Liveliness + + As the introduction mentioned, it is often necessary to detect that a + peer is unreachable as soon as possible. IKE provides no way for + this to occur -- aside from waiting until the rekey period, then + attempting (and failing the rekey). This would result in a period of + loss connectivity lasting the remainder of the lifetime of the + security association (SA), and in most deployments, this is + unacceptable. As such, a method is needed for checking up on a + peer's state at will. Different methods have arisen, usually using + an IKE Notify to query the peer's liveliness. These methods rely on + either a bidirectional "keepalive" message exchange (a HELLO followed + by an ACK), or a unidirectional "heartbeat" message exchange (a HELLO + only). The next section considers both of these schemes. + +4. Keepalives vs. Heartbeats + +4.1. Keepalives: + + Consider a keepalives scheme in which peer A and peer B require + regular acknowledgements of each other's liveliness. The messages + are exchanged by means of an authenticated notify payload. The two + peers must agree upon the interval at which keepalives are sent, + meaning that some negotiation is required during Phase 1. For any + prompt failover to be possible, the keepalives must also be sent at + rather frequent intervals -- around 10 seconds or so. In this + hypothetical keepalives scenario, peers A and B agree to exchange + keepalives every 10 seconds. Essentially, every 10 seconds, one peer + must send a HELLO to the other. This HELLO serves as proof of + liveliness for the sending entity. In turn, the other peer must + acknowledge each keepalive HELLO. If the 10 seconds elapse, and one + side has not received a HELLO, it will send the HELLO message itself, + using the peer's ACK as proof of liveliness. Receipt of either a + + + +Huang, et al. Informational [Page 3] + +RFC 3706 Detecting Dead IKE Peers February 2004 + + + HELLO or ACK causes an entity's keepalive timer to reset. Failure to + receive an ACK in a certain period of time signals an error. A + clarification is presented below: + + Scenario 1: + Peer A's 10-second timer elapses first, and it sends a HELLO to B. + B responds with an ACK. + + Peer A: Peer B: + 10 second timer fires; ------> + wants to know that B is alive; + sends HELLO. + Receives HELLO; acknowledges + A's liveliness; + <------ resets keepalive timer, sends + ACK. + Receives ACK as proof of + B's liveliness; resets timer. + + Scenario 2: + Peer A's 10-second timer elapses first, and it sends a HELLO to B. + B fails to respond. A can retransmit, in case its initial HELLO is + lost. This situation describes how peer A detects its peer is dead. + + Peer A: Peer B (dead): + + 10 second timer fires; ------X + wants to know that B is + alive; sends HELLO. + + Retransmission timer ------X + expires; initial message + could have been lost in + transit; A increments + error counter and + sends another HELLO. + + --- + + After some number of errors, A assumes B is dead; deletes SAs and + possibly initiates failover. + + An advantage of this scheme is that the party interested in the other + peer's liveliness begins the message exchange. In Scenario 1, peer A + is interested in peer B's liveliness, and peer A consequently sends + + + + + + +Huang, et al. Informational [Page 4] + +RFC 3706 Detecting Dead IKE Peers February 2004 + + + the HELLO. It is conceivable in such a scheme that peer B would + never be interested in peer A's liveliness. In such a case, the onus + would always lie on peer A to initiate the exchange. + +4.2. Heartbeats: + + By contrast, consider a proof-of-liveliness scheme involving + unidirectional (unacknowledged) messages. An entity interested in + its peer's liveliness would rely on the peer itself to send periodic + messages demonstrating liveliness. In such a scheme, the message + exchange might look like this: + + Scenario 3: Peer A and Peer B are interested in each other's + liveliness. Each peer depends on the other to send periodic HELLOs. + + + Peer A: Peer B: + 10 second timer fires; ------> + sends HELLO. Timer also + signals expectation of + B's HELLO. + Receives HELLO as proof of A's + liveliness. + + <------ 10 second timer fires; sends + HELLO. + Receives HELLO as proof + of B's liveliness. + + Scenario 4: + Peer A fails to receive HELLO from B and marks the peer dead. This + is how an entity detects its peer is dead. + + Peer A: Peer B (dead): + 10 second timer fires; ------X + sends HELLO. Timer also + signals expectation of + B's HELLO. + + --- + + Some time passes and A assumes B is dead. + + The disadvantage of this scheme is the reliance upon the peer to + demonstrate liveliness. To this end, peer B might never be + interested in peer A's liveliness. Nonetheless, if A is interested + B's liveliness, B must be aware of this, and maintain the necessary + state information to send periodic HELLOs to A. The disadvantage of + + + +Huang, et al. Informational [Page 5] + +RFC 3706 Detecting Dead IKE Peers February 2004 + + + such a scheme becomes clear in the remote-access scenario. Consider + a VPN aggregator that terminates a large number of sessions (on the + order of 50,000 peers or so). Each peer requires fairly rapid + failover, therefore requiring the aggregator to send HELLO packets + every 10 seconds or so. Such a scheme simply lacks scalability, as + the aggregator must send 50,000 messages every few seconds. + + In both of these schemes (keepalives and heartbeats), some + negotiation of message interval must occur, so that each entity can + know how often its peer expects a HELLO. This immediately adds a + degree of complexity. Similarly, the need to send periodic messages + (regardless of other IPSec/IKE activity), also increases + computational overhead to the system. + +5. DPD Protocol + + DPD addresses the shortcomings of IKE keepalives- and heartbeats- + schemes by introducing a more reasonable logic governing message + exchange. Essentially, keepalives and heartbeats mandate exchange of + HELLOs at regular intervals. By contrast, with DPD, each peer's DPD + state is largely independent of the other's. A peer is free to + request proof of liveliness when it needs it -- not at mandated + intervals. This asynchronous property of DPD exchanges allows fewer + messages to be sent, and this is how DPD achieves greater + scalability. + + As an elaboration, consider two DPD peers A and B. If there is + ongoing valid IPSec traffic between the two, there is little need for + proof of liveliness. The IPSec traffic itself serves as the proof of + liveliness. If, on the other hand, a period of time lapses during + which no packet exchange occurs, the liveliness of each peer is + questionable. Knowledge of the peer's liveliness, however, is only + urgently necessary if there is traffic to be sent. For example, if + peer A has some IPSec packets to send after the period of idleness, + it will need to know if peer B is still alive. At this point, peer A + can initiate the DPD exchange. + + To this end, each peer may have different requirements for detecting + proof of liveliness. Peer A, for example, may require rapid + failover, whereas peer B's requirements for resource cleanup are less + urgent. In DPD, each peer can define its own "worry metric" - an + interval that defines the urgency of the DPD exchange. Continuing the + example, peer A might define its DPD interval to be 10 seconds. + Then, if peer A sends outbound IPSec traffic, but fails to receive + any inbound traffic for 10 seconds, it can initiate a DPD exchange. + + + + + + +Huang, et al. Informational [Page 6] + +RFC 3706 Detecting Dead IKE Peers February 2004 + + + Peer B, on the other hand, defines its less urgent DPD interval to be + 5 minutes. If the IPSec session is idle for 5 minutes, peer B can + initiate a DPD exchange the next time it sends IPSec packets to A. + + It is important to note that the decision about when to initiate a + DPD exchange is implementation specific. An implementation might + even define the DPD messages to be at regular intervals following + idle periods. See section 5.5 for more implementation suggestions. + +5.1. DPD Vendor ID + + To demonstrate DPD capability, an entity must send the DPD vendor ID. + Both peers of an IKE session MUST send the DPD vendor ID before DPD + exchanges can begin. The format of the DPD Vendor ID is: + + 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! !M!M! + ! HASHED_VENDOR_ID !J!N! + ! !R!R! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + where HASHED_VENDOR_ID = {0xAF, 0xCA, 0xD7, 0x13, 0x68, 0xA1, 0xF1, + 0xC9, 0x6B, 0x86, 0x96, 0xFC, 0x77, 0x57}, and MJR and MNR correspond + to the current major and minor version of this protocol (1 and 0 + respectively). An IKE peer MUST send the Vendor ID if it wishes to + take part in DPD exchanges. + +5.2. Message Exchanges + + The DPD exchange is a bidirectional (HELLO/ACK) Notify message. The + exchange is defined as: + + Sender Responder + -------- ----------- + HDR*, NOTIFY(R-U-THERE), HASH ------> + + <------ HDR*, NOTIFY(R-U-THERE- + ACK), HASH + + + + + + + + + + + +Huang, et al. Informational [Page 7] + +RFC 3706 Detecting Dead IKE Peers February 2004 + + + The R-U-THERE message corresponds to a "HELLO" and the R-U-THERE-ACK + corresponds to an "ACK." Both messages are simply ISAKMP Notify + payloads, and as such, this document defines these two new ISAKMP + Notify message types: + + Notify Message Value + R-U-THERE 36136 + R-U-THERE-ACK 36137 + + An entity that has sent the DPD Vendor ID MUST respond to an R-U- + THERE query. Furthermore, an entity MUST reject unencrypted R-U- + THERE and R-U-THERE-ACK messages. + +5.3. NOTIFY(R-U-THERE/R-U-THERE-ACK) Message Format + + When sent, the R-U-THERE message MUST take the following form: + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Domain of Interpretation (DOI) ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Protocol-ID ! SPI Size ! Notify Message Type ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Security Parameter Index (SPI) ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Notification Data ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + As this message is an ISAKMP NOTIFY, the Next Payload, RESERVED, and + Payload Length fields should be set accordingly. The remaining + fields are set as: + + - Domain of Interpretation (4 octets) - SHOULD be set to IPSEC-DOI. + + - Protocol ID (1 octet) - MUST be set to the protocol ID for ISAKMP. + + - SPI Size (1 octet) - SHOULD be set to sixteen (16), the length of + two octet-sized ISAKMP cookies. + + - Notify Message Type (2 octets) - MUST be set to R-U-THERE + + + + + + +Huang, et al. Informational [Page 8] + +RFC 3706 Detecting Dead IKE Peers February 2004 + + + - Security Parameter Index (16 octets) - SHOULD be set to the + cookies of the Initiator and Responder of the IKE SA (in that + order) + + - Notification Data (4 octets) - MUST be set to the sequence number + corresponding to this message + + The format of the R-U-THERE-ACK message is the same, with the + exception that the Notify Message Type MUST be set to R-U-THERE-ACK. + Again, the Notification Data MUST be sent to the sequence number + corresponding to the received R-U-THERE message. + +5.4. Impetus for DPD Exchange + + Again, rather than relying on some negotiated time interval to force + the exchange of messages, DPD does not mandate the exchange of R-U- + THERE messages at any time. Instead, an IKE peer SHOULD send an R- + U-THERE query to its peer only if it is interested in the liveliness + of this peer. To this end, if traffic is regularly exchanged between + two peers, either peer SHOULD use this traffic as proof of + liveliness, and both peers SHOULD NOT initiate a DPD exchange. + + A peer MUST keep track of the state of a given DPD exchange. That + is, once it has sent an R-U-THERE query, it expects an ACK in + response within some implementation-defined period of time. An + implementation SHOULD retransmit R-U-THERE queries when it fails to + receive an ACK. After some number of retransmitted messages, an + implementation SHOULD assume its peer to be unreachable and delete + IPSec and IKE SAs to the peer. + +5.5. Implementation Suggestion + + Since the liveliness of a peer is only questionable when no traffic + is exchanged, a viable implementation might begin by monitoring + idleness. Along these lines, a peer's liveliness is only important + when there is outbound traffic to be sent. To this end, an + implementation can initiate a DPD exchange (i.e., send an R-U-THERE + message) when there has been some period of idleness, followed by the + desire to send outbound traffic. Likewise, an entity can initiate a + DPD exchange if it has sent outbound IPSec traffic, but not received + any inbound IPSec packets in response. A complete DPD exchange + (i.e., transmission of R-U-THERE and receipt of corresponding R-U- + THERE-ACK) will serve as proof of liveliness until the next idle + period. + + Again, since DPD does not mandate any interval, this "idle period" + (or "worry metric") is left as an implementation decision. It is not + a negotiated value. + + + +Huang, et al. Informational [Page 9] + +RFC 3706 Detecting Dead IKE Peers February 2004 + + +5.6. Comparisons + + The performance benefit that DPD offers over traditional keepalives- + and heartbeats-schemes comes from the fact that regular messages do + not need to be sent. Returning to the examples presented in section + 4.1, a keepalive implementation such as the one presented would + require one timer to signal when to send a HELLO message and another + timer to "timeout" the ACK from the peer (this could also be the + retransmit timer). Similarly, a heartbeats scheme such as the one + presented in section 4.2 would need to keep one timer to signal when + to send a HELLO, as well as another timer to signal the expectation + of a HELLO from the peer. By contrast a DPD scheme needs to keep a + timestamp to keep track of the last received traffic from the peer + (thus marking beginning of the "idle period"). Once a DPD R-U-THERE + message has been sent, an implementation need only maintain a timer + to signal retransmission. Thus, the need to maintain active timer + state is reduced, resulting in a scalability improvement (assuming + maintaining a timestamp is less costly than an active timer). + Furthermore, since a DPD exchange only occurs if an entity has not + received traffic recently from its peer, the number of IKE messages + to be sent and processed is also reduced. As a consequence, the + scalability of DPD is much better than keepalives and heartbeats. + + DPD maintains the HELLO/ACK model presented by keepalives, as it + follows that an exchange is initiated only by an entity interested in + the liveliness of its peer. + +6. Resistance to Replay Attack and False Proof of Liveliness + +6.1. Sequence Number in DPD Messages + + To guard against message replay attacks and false proof of + liveliness, a 32-bit sequence number MUST be presented with each R- + U-THERE message. A responder to an R-U-THERE message MUST send an + R-U-THERE-ACK with the same sequence number. Upon receipt of the R- + U-THERE-ACK message, the initial sender SHOULD check the validity of + the sequence number. The initial sender SHOULD reject the R-U- + THERE-ACK if the sequence number fails to match the one sent with the + R-U-THERE message. + + Additionally, both the receiver of the R-U-THERE and the R-U-THERE- + ACK message SHOULD check the validity of the Initiator and Responder + cookies presented in the SPI field of the payload. + + + + + + + + +Huang, et al. Informational [Page 10] + +RFC 3706 Detecting Dead IKE Peers February 2004 + + +6.2. Selection and Maintenance of Sequence Numbers + + As both DPD peers can initiate a DPD exchange (i.e., both peers can + send R-U-THERE messages), each peer MUST maintain its own sequence + number for R-U-THERE messages. The first R-U-THERE message sent in a + session MUST be a randomly chosen number. To prevent rolling past + overflowing the 32-bit boundary, the high-bit of the sequence number + initially SHOULD be set to zero. Subsequent R-U-THERE messages MUST + increment the sequence number by one. Sequence numbers MAY reset at + the expiry of the IKE SA, moving to a newly chosen random number. + Each entity SHOULD also maintain its peer's R-U-THERE sequence + number, and an entity SHOULD reject the R-U-THERE message if it fails + to match the expected sequence number. + + Implementations MAY maintain a window of acceptable sequence numbers, + but this specification makes no assumptions about how this is done. + Again, it is an implementation specific detail. + +7. Security Considerations + + As the previous section highlighted, DPD uses sequence numbers to + ensure liveliness. This section describes the advantages of using + sequence numbers over random nonces to ensure liveliness. + + While sequence numbers do require entities to keep per-peer state, + they also provide an added method of protection in certain replay + attacks. Consider a case where peer A sends peer B a valid DPD R-U- + THERE message. An attacker C can intercept this message and flood B + with multiple copies of the messages. B will have to decrypt and + process each packet (regardless of whether sequence numbers or nonces + are in use). With sequence numbers B can detect that the packets are + replayed: the sequence numbers in these replayed packets will not + match the incremented sequence number that B expects to receive from + A. This prevents B from needing to build, encrypt, and send ACKs. + By contrast, if the DPD protocol used nonces, it would provide no way + for B to detect that the messages are replayed (unless B maintained a + list of recently received nonces). + + Another benefit of sequence numbers is that it adds an extra + assurance of the peer's liveliness. As long as a receiver verifies + the validity of a DPD R-U-THERE message (by verifying its incremented + sequence number), then the receiver can be assured of the peer's + liveliness by the very fact that the sender initiated the query. + Nonces, by contrast, cannot provide this assurance. + + + + + + + +Huang, et al. Informational [Page 11] + +RFC 3706 Detecting Dead IKE Peers February 2004 + + +8. IANA Considerations + + There is no IANA action required for this document. DPD uses notify + numbers from the private range. + +9. References + +9.1. Normative Reference + + [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement + Levels", BCP 14, RFC 2119, March 1997. + +9.2. Informative References + + [2] Harkins, D. and D. Carrel, "The Internet Key Exchange (IKE)", + RFC 2409, November 1998. + + [3] Kent, S. and R. Atkinson, "Security Architecture for the + Internet Protocol", RFC 2401, November 1998. + +10. Editors' Addresses + + Geoffrey Huang + Cisco Systems, Inc. + 170 West Tasman Drive + San Jose, CA 95134 + + Phone: (408) 525-5354 + EMail: ghuang@cisco.com + + + Stephane Beaulieu + Cisco Systems, Inc. + 2000 Innovation Drive + Kanata, ON + Canada, K2K 3E8 + + Phone: (613) 254-3678 + EMail: stephane@cisco.com + + + Dany Rochefort + Cisco Systems, Inc. + 124 Grove Street, Suite 205 + Franklin, MA 02038 + + Phone: (508) 553-8644 + EMail: danyr@cisco.com + + + +Huang, et al. Informational [Page 12] + +RFC 3706 Detecting Dead IKE Peers February 2004 + + +11. Full Copyright Statement + + Copyright (C) The Internet Society (2004). This document is subject + to the rights, licenses and restrictions contained in BCP 78 and + except as set forth therein, the authors retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE + REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE + INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF + THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed + to pertain to the implementation or use of the technology + described in this document or the extent to which any license + under such rights might or might not be available; nor does it + represent that it has made any independent effort to identify any + such rights. Information on the procedures with respect to + rights in RFC documents can be found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use + of such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository + at http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention + any copyrights, patents or patent applications, or other + proprietary rights that may cover technology that may be required + to implement this standard. Please address the information to the + IETF at ietf-ipr@ietf.org. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + + + +Huang, et al. Informational [Page 13] + diff --git a/crypto/dist/ipsec-tools/src/racoon/rfc/rfc3715.txt b/crypto/dist/ipsec-tools/src/racoon/rfc/rfc3715.txt new file mode 100644 index 0000000000000..827f5b3732cbe --- /dev/null +++ b/crypto/dist/ipsec-tools/src/racoon/rfc/rfc3715.txt @@ -0,0 +1,1011 @@ + + + + + + +Network Working Group B. Aboba +Request for Comments: 3715 W. Dixon +Category: Informational Microsoft + March 2004 + + + IPsec-Network Address Translation (NAT) Compatibility Requirements + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2004). All Rights Reserved. + +Abstract + + This document describes known incompatibilities between Network + Address Translation (NAT) and IPsec, and describes the requirements + for addressing them. Perhaps the most common use of IPsec is in + providing virtual private networking capabilities. One very popular + use of Virtual Private Networks (VPNs) is to provide telecommuter + access to the corporate Intranet. Today, NATs are widely deployed in + home gateways, as well as in other locations likely to be used by + telecommuters, such as hotels. The result is that IPsec-NAT + incompatibilities have become a major barrier in the deployment of + IPsec in one of its principal uses. + + + + + + + + + + + + + + + + + + + + + +Aboba & Dixon Informational [Page 1] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2 + 1.1. Requirements Language. . . . . . . . . . . . . . . . . . 2 + 2. Known Incompatibilities between NA(P)T and IPsec . . . . . . . 3 + 2.1. Intrinsic NA(P)T Issues. . . . . . . . . . . . . . . . . 3 + 2.2. NA(P)T Implementation Weaknesses . . . . . . . . . . . . 7 + 2.3. Helper Incompatibilities . . . . . . . . . . . . . . . . 8 + 3. Requirements for IPsec-NAT Compatibility . . . . . . . . . . . 8 + 4. Existing Solutions . . . . . . . . . . . . . . . . . . . . . . 12 + 4.1. IPsec Tunnel Mode. . . . . . . . . . . . . . . . . . . . 12 + 4.2. RSIP . . . . . . . . . . . . . . . . . . . . . . . . . . 13 + 4.3. 6to4 . . . . . . . . . . . . . . . . . . . . . . . . . . 13 + 5. Security Considerations. . . . . . . . . . . . . . . . . . . . 14 + 6. References . . . . . . . . . . . . . . . . . . . . . . . . . . 15 + 6.1. Normative References . . . . . . . . . . . . . . . . . . 15 + 6.2. Informative References . . . . . . . . . . . . . . . . . 16 + 7. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 17 + 8. Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 17 + 9 . Full Copyright Statement . . . . . . . . . . . . . . . . . . . 18 + +1. Introduction + + Perhaps the most common use of IPsec [RFC2401] is in providing + virtual private networking (VPN) capabilities. One very popular use + of VPNs is to provide telecommuter access to the corporate Intranet. + Today, Network Address Translations (NATs) as described in [RFC3022] + and [RFC2663], are widely deployed in home gateways, as well as in + other locations likely to be used by telecommuters, such as hotels. + The result is that IPsec-NAT incompatibilities have become a major + barrier in the deployment of IPsec in one of its principal uses. + This document describes known incompatibilities between NAT and + IPsec, and describes the requirements for addressing them. + +1.1. Requirements Language + + In this document, the key words "MAY", "MUST, "MUST NOT", "optional", + "recommended", "SHOULD", and "SHOULD NOT", are to be interpreted as + described in [RFC2119]. + + Please note that the requirements specified in this document are to + be used in evaluating protocol submissions. As such, the + requirements language refers to capabilities of these protocols; the + protocol documents will specify whether these features are required, + recommended, or optional. For example, requiring that a protocol + support confidentiality is not the same thing as requiring that all + protocol traffic be encrypted. + + + + +Aboba & Dixon Informational [Page 2] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + + A protocol submission is not compliant if it fails to satisfy one or + more of the MUST or MUST NOT requirements for the capabilities that + it implements. A protocol submission that satisfies all the MUST, + MUST NOT, SHOULD, and SHOULD NOT requirements for its capabilities is + said to be "unconditionally compliant"; one that satisfies all the + MUST and MUST NOT requirements, but not all the SHOULD or SHOULD NOT + requirements for its protocols is said to be "conditionally + compliant." + +2. Known Incompatibilities between NA(P)T and IPsec + + The incompatibilities between NA(P)T and IPsec can be divided into + three categories: + + 1) Intrinsic NA(P)T issues. These incompatibilities derive directly + from the NA(P)T functionality described in [RFC3022]. These + incompatibilities will therefore be present in any NA(P)T device. + + 2) NA(P)T implementation weaknesses. These incompatibilities are not + intrinsic to NA(P)T, but are present in many NA(P)T + implementations. Included in this category are problems in + handling inbound or outbound fragments. Since these issues are + not intrinsic to NA(P)T, they can, in principle, be addressed in + future NA(P)T implementations. However, since the implementation + problems appear to be wide spread, they need to be taken into + account in a NA(P)T traversal solution. + + 3) Helper issues. These incompatibilities are present in NA(P)T + devices which attempt to provide for IPsec NA(P)T traversal. + Ironically, this "helper" functionality creates further + incompatibilities, making an already difficult problem harder to + solve. While IPsec traversal "helper" functionality is not + present in all NA(P)Ts, these features are becoming sufficiently + popular that they also need to be taken into account in a NA(P)T + traversal solution. + +2.1. Intrinsic NA(P)T Issues + + Incompatibilities that are intrinsic to NA(P)T include: + + a) Incompatibility between IPsec AH [RFC2402] and NAT. Since the AH + header incorporates the IP source and destination addresses in the + keyed message integrity check, NAT or reverse NAT devices making + changes to address fields will invalidate the message integrity + check. Since IPsec ESP [RFC2406] does not incorporate the IP + source and destination addresses in its keyed message integrity + check, this issue does not arise for ESP. + + + + +Aboba & Dixon Informational [Page 3] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + + b) Incompatibility between checksums and NAT. TCP and UDP checksums + have a dependency on the IP source and destination addresses + through inclusion of the "pseudo-header" in the calculation. As a + result, where checksums are calculated and checked upon receipt, + they will be invalidated by passage through a NAT or reverse NAT + device. + + As a result, IPsec Encapsulating Security Payload (ESP) will only + pass through a NAT unimpeded if TCP/UDP protocols are not involved + (as in IPsec tunnel mode or IPsec protected GRE), or checksums are + not calculated (as is possible with IPv4 UDP). As described in + [RFC793], TCP checksum calculation and verification is required in + IPv4. UDP/TCP checksum calculation and verification is required + in IPv6. + + Stream Control Transmission Protocol (SCTP), as defined in + [RFC2960] and [RFC3309], uses a CRC32C algorithm calculated only + on the SCTP packet (common header + chunks), so that the IP header + is not covered. As a result, NATs do not invalidate the SCTP CRC, + and the problem does not arise. + + Note that since transport mode IPsec traffic is integrity + protected and authenticated using strong cryptography, + modifications to the packet can be detected prior to checking + UDP/TCP checksums. Thus, checksum verification only provides + assurance against errors made in internal processing. + + c) Incompatibility between IKE address identifiers and NAT. Where IP + addresses are used as identifiers in Internet Key Exchange + Protocol (IKE) Phase 1 [RFC2409] or Phase 2, modification of the + IP source or destination addresses by NATs or reverse NATs will + result in a mismatch between the identifiers and the addresses in + the IP header. As described in [RFC2409], IKE implementations are + required to discard such packets. + + In order to avoid use of IP addresses as IKE Phase 1 and Phase 2 + identifiers, userIDs and FQDNs can be used instead. Where user + authentication is desired, an ID type of ID_USER_FQDN can be used, + as described in [RFC2407]. Where machine authentication is + desired, an ID type of ID_FQDN can be used. In either case, it is + necessary to verify that the proposed identifier is authenticated + as a result of processing an end-entity certificate, if + certificates are exchanged in Phase 1. While use of USER_FQDN or + FQDN identity types is possible within IKE, there are usage + scenarios (e.g. Security Policy Database (SPD) entries describing + subnets) that cannot be accommodated this way. + + + + + +Aboba & Dixon Informational [Page 4] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + + Since the source address in the Phase 2 identifier is often used + to form a full 5-tuple inbound SA selector, the destination + address, protocol, source port and destination port can be used in + the selector so as not to weaken inbound SA processing. + + d) Incompatibility between fixed IKE source ports and NAPT. Where + multiple hosts behind the NAPT initiate IKE SAs to the same + responder, a mechanism is needed to allow the NAPT to demultiplex + the incoming IKE packets from the responder. This is typically + accomplished by translating the IKE UDP source port on outbound + packets from the initiator. Thus responders must be able to + accept IKE traffic from a UDP source port other than 500, and must + reply to that port. Care must be taken to avoid unpredictable + behavior during re-keys. If the floated source port is not used + as the destination port for the re-key, the NAT may not be able to + send the re-key packets to the correct destination. + + e) Incompatibilities between overlapping SPD entries and NAT. Where + initiating hosts behind a NAT use their source IP addresses in + Phase 2 identifiers, they can negotiate overlapping SPD entries + with the same responder IP address. The responder could then send + packets down the wrong IPsec SA. This occurs because to the + responder, the IPsec SAs appear to be equivalent, since they exist + between the same endpoints and can be used to pass the same + traffic. + + f) Incompatibilities between IPsec SPI selection and NAT. Since + IPsec ESP traffic is encrypted and thus opaque to the NAT, the NAT + must use elements of the IP and IPsec header to demultiplex + incoming IPsec traffic. The combination of the destination IP + address, security protocol (AH/ESP), and IPsec SPI is typically + used for this purpose. + + However, since the outgoing and incoming SPIs are chosen + independently, there is no way for the NAT to determine what + incoming SPI corresponds to what destination host merely by + inspecting outgoing traffic. Thus, were two hosts behind the NAT + to attempt to create IPsec SAs at the same destination + simultaneously, it is possible that the NAT will deliver the + incoming IPsec packets to the wrong destination. + + Note that this is not an incompatibility with IPsec per se, but + rather with the way it is typically implemented. With both AH and + ESP, the receiving host specifies the SPI to use for a given SA, a + choice which is significant only to the receiver. At present, the + combination of Destination IP, SPI, and Security Protocol (AH, + ESP) uniquely identifies a Security Association. Also, SPI values + in the range 1-255 are reserved to IANA and may be used in the + + + +Aboba & Dixon Informational [Page 5] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + + future. This means that, when negotiating with the same external + host or gateway, the internal hosts behind the same NAPT can + select the same SPI value, such that one host inbound SA is + (SPI=470, Internal Dest IP=192.168.0.4) + and a different host inbound SA is + (SPI=470, Internal Dest IP=192.168.0.5). + The receiving NAPT will not be able to determine which internal + host an inbound IPsec packet with SPI=470 should be forwarded to. + + It is also possible for the receiving host to allocate a unique + SPI to each unicast Security Association. In this case, the + Destination IP Address need only be checked to see if it is "any + valid unicast IP for this host", not checked to see if it is the + specific Destination IP address used by the sending host. Using + this technique, the NA(P)T can be assured of a low but non-zero + chance of forwarding packets to the wrong internal host, even when + two or more hosts establish SAs with the same external host. + + This approach is completely backwards compatible, and only + requires the particular receiving host to make a change to its SPI + allocation and IPsec_esp_input() code. However, NA(P)T devices + may not be able to detect this behavior without problems + associated with parsing IKE payloads. And a host may still be + required to use a SPI in the IANA reserved range for the assigned + purpose. + + g) Incompatibilities between embedded IP addresses and NAT. Since + the payload is integrity protected, any IP addresses enclosed + within IPsec packets will not be translatable by a NAT. This + renders ineffective Application Layer Gateways (ALGs) implemented + within NATs. Protocols that utilize embedded IP addresses include + FTP, IRC, SNMP, LDAP, H.323, SIP, SCTP (optionally), and many + games. To address this issue, it is necessary to install ALGs on + the host or security gateway that can operate on application + traffic prior to IPsec encapsulation and after IPsec + decapsulation. + + h) Implicit directionality of NA(P)T. NA(P)Ts often require an + initial outbound packet to flow through them in order to create an + inbound mapping state. Directionality prohibits unsolicited + establishment of IPsec SAs to hosts behind the NA(P)T. + + i) Inbound SA selector verification. Assuming IKE negotiates phase 2 + selectors, inbound SA processing will drop the decapsulated + packet, since [RFC2401] requires a packet's source address match + the SA selector value, which NA(P)T processing of an ESP packet + would change. + + + + +Aboba & Dixon Informational [Page 6] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + +2.2. NA(P)T Implementation Weaknesses + + Implementation problems present in many NA(P)Ts include: + + j) Inability to handle non-UDP/TCP traffic. Some NA(P)Ts discard + non-UDP/TCP traffic or perform address-only translation when only + one host is behind the NAT. Such NAPTs are unable to enable SCTP, + ESP (protocol 50), or AH (protocol 51) traffic. + + k) NAT mapping timeouts. NA(P)Ts vary in the time for which a UDP + mapping will be maintained in the absence of traffic. Thus, even + where IKE packets can be correctly translated, the translation + state may be removed prematurely. + + l) Inability to handle outgoing fragments. Most NA(P)Ts can properly + fragment outgoing IP packets in the case where the IP packet size + exceeds the MTU on the outgoing interface. However, proper + translation of outgoing packets that are already fragmented is + difficult and most NAPTs do not handle this correctly. As noted + in Section 6.3 of [RFC3022], where two hosts originate fragmented + packets to the same destination, the fragment identifiers can + overlap. Since the destination host relies on the fragmentation + identifier and fragment offset for reassembly, the result will be + data corruption. Few NA(P)Ts protect against identifier + collisions by supporting identifier translation. Identifier + collisions are not an issue when NATs perform the fragmentation, + since the fragment identifier need only be unique within a + source/destination IP address pair. + + Since a fragment can be as small as 68 octets [RFC791], there is + no guarantee that the first fragment will contain a complete TCP + header. Thus, a NA(P)T looking to recalculate the TCP checksum + may need to modify a subsequent fragment. Since fragments can be + reordered, and IP addresses can be embedded and possibly even + split between fragments, the NA(P)T will need to perform + reassembly prior to completing the translation. Few NA(P)Ts + support this. + + m) Inability to handle incoming fragments. Since only the first + fragment will typically contain a complete IP/UDP/SCTP/TCP header, + NAPTs need to be able to perform the translation based on the + source/dest IP address and fragment identifier alone. Since + fragments can be reordered, the headers to a given fragment + identifier may not be known if a subsequent fragment arrives prior + to the initial one, and the headers may be split between + fragments. As a result, the NAPT may need to perform reassembly + prior to completing the translation. Few NAPTs support this. + Note that with NAT, the source/dest IP address is enough to + + + +Aboba & Dixon Informational [Page 7] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + + determine the translation so that this does not arise. However, + it is possible for the IPsec or IKE headers to be split between + fragments, so that reassembly may still be required. + +2.3. Helper Incompatibilities + + Incompatibilities between IPsec and NAT "helper" functionality + include: + + n) Internet Security Association and Key Management Protocol (ISAKMP) + header inspection. Today some NAT implementations attempt to use + IKE cookies to de-multiplex incoming IKE traffic. As with + source-port de-multiplexing, IKE cookie de-multiplexing results in + problems with re-keying, since Phase 1 re-keys typically will not + use the same cookies as the earlier traffic. + + o) Special treatment of port 500. Since some IKE implementations are + unable to handle non-500 UDP source ports, some NATs do not + translate packets with a UDP source port of 500. This means that + these NATs are limited to one IPsec client per destination + gateway, unless they inspect details of the ISAKMP header to + examine cookies which creates the problem noted above. + + p) ISAKMP payload inspection. NA(P)T implementations that attempt to + parse ISAKMP payloads may not handle all payload ordering + combinations, or support vendor_id payloads for IKE option + negotiation. + +3. Requirements for IPsec-NAT Compatibility + + The goal of an IPsec-NAT compatibility solution is to expand the + range of usable IPsec functionality beyond that available in the + NAT-compatible IPsec tunnel mode solution described in Section 2.3. + + In evaluating a solution to IPsec-NAT incompatibility, the following + criteria should be kept in mind: + + Deployment + + Since IPv6 will address the address scarcity issues that + frequently lead to use of NA(P)Ts with IPv4, the IPsec-NAT + compatibility issue is a transitional problem that needs to be + solved in the time frame prior to widespread deployment of IPv6. + Therefore, to be useful, an IPsec-NAT compatibility solution MUST + be deployable on a shorter time scale than IPv6. + + + + + + +Aboba & Dixon Informational [Page 8] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + + Since IPv6 deployment requires changes to routers as well as + hosts, a potential IPsec-NAT compatibility solution, which + requires changes to both routers and hosts, will be deployable on + approximately the same time scale as IPv6. Thus, an IPsec-NAT + compatibility solution SHOULD require changes only to hosts, and + not to routers. + + Among other things, this implies that communication between the + host and the NA(P)T SHOULD NOT be required by an IPsec-NAT + compatibility solution, since that would require changes to the + NA(P)Ts, and interoperability testing between the host and NA(P)T + implementations. In order to enable deployment in the short term, + it is necessary for the solution to work with existing router and + NA(P)T products within the deployed infrastructure. + + Protocol Compatibility + + An IPsec NAT traversal solution is not expected to resolve issues + with protocols that cannot traverse NA(P)T when unsecured with + IPsec. Therefore, ALGs may still be needed for some protocols, + even when an IPsec NAT traversal solution is available. + + Security + + Since NA(P)T directionality serves a security function, IPsec + NA(P)T traversal solutions should not allow arbitrary incoming + IPsec or IKE traffic from any IP address to be received by a host + behind the NA(P)T, although mapping state should be maintained + once bidirectional IKE and IPsec communication is established. + + Telecommuter Scenario + + Since one of the primary uses of IPsec is remote access to + corporate Intranets, a NA(P)T traversal solution MUST support + NA(P)T traversal, via either IPsec tunnel mode or L2TP over IPsec + transport mode [RFC3193]. This includes support for traversal of + more than one NA(P)T between the remote client and the VPN + gateway. + + The client may have a routable address and the VPN gateway may be + behind at least one NA(P)T, or alternatively, both the client and + the VPN gateway may be behind one or more NA(P)Ts. Telecommuters + may use the same private IP address, each behind their own NA(P)T, + or many telecommuters may reside on a private network behind the + same NA(P)T, each with their own unique private address, + connecting to the same VPN gateway. Since IKE uses UDP port 500 + as the destination, it is not necessary to enable multiple VPN + gateways operating behind the same external IP address. + + + +Aboba & Dixon Informational [Page 9] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + + Gateway-to-Gateway Scenario + + In a gateway-gateway scenario, a privately addressed network (DMZ) + may be inserted between the corporate network and the Internet. + In this design, IPsec security gateways connecting portions of the + corporate network may be resident in the DMZ and have private + addresses on their external (DMZ) interfaces. A NA(P)T connects + the DMZ network to the Internet. + + End-to-End Scenario + + A NAT-IPsec solution MUST enable secure host-host TCP/IP + communication via IPsec, as well as host-gateway communications. + A host on a private network MUST be able to bring up one or + multiple IPsec-protected TCP connections or UDP sessions to + another host with one or more NA(P)Ts between them. For example, + NA(P)Ts may be deployed within branch offices connecting to the + corporate network, with an additional NA(P)T connecting the + corporate network to the Internet. Likewise, NA(P)Ts may be + deployed within a corporate network LAN or WAN to connect wireless + or remote location clients to the corporate network. This may + require special processing of TCP and UDP traffic on the host. + + Bringing up SCTP connections to another host with one or more NA(P)Ts + between them may present special challenges. SCTP supports multi- + homing. If more than one IP address is used, these addresses are + transported as part of the SCTP packet during the association setup + (in the INIT and INIT-ACK chunks). If only single homed SCTP end- + points are used, [RFC2960] section 3.3.2.1 states: + + Note that not using any IP address parameters in the INIT and + INIT-ACK is an alternative to make an association more likely + to work across a NAT box. + + This implies that IP addresses should not be put into the SCTP packet + unless necessary. If NATs are present and IP addresses are included, + then association setup will fail. Recently [AddIP] has been proposed + which allows the modification of the IP address once an association + is established. The modification messages have also IP addresses in + the SCTP packet, and so will be adversely affected by NATs. + + Firewall Compatibility + + Since firewalls are widely deployed, a NAT-IPsec compatibility + solution MUST enable a firewall administrator to create simple, + static access rule(s) to permit or deny IKE and IPsec NA(P)T + traversal traffic. This implies, for example, that dynamic + allocation of IKE or IPsec destination ports is to be avoided. + + + +Aboba & Dixon Informational [Page 10] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + + Scaling + + An IPsec-NAT compatibility solution should be capable of being + deployed within an installation consisting of thousands of + telecommuters. In this situation, it is not possible to assume + that only a single host is communicating with a given destination + at a time. Thus, an IPsec-NAT compatibility solution MUST address + the issue of overlapping SPD entries and de-multiplexing of + incoming packets. + + Mode Support + + At a minimum, an IPsec-NAT compatibility solution MUST support + traversal of the IKE and IPsec modes required for support within + [RFC2409] and [RFC2401]. For example, an IPsec gateway MUST + support ESP tunnel mode NA(P)T traversal, and an IPsec host MUST + support IPsec transport mode NA(P)T traversal. The purpose of AH + is to protect immutable fields within the IP header (including + addresses), and NA(P)T translates addresses, invalidating the AH + integrity check. As a result, NA(P)T and AH are fundamentally + incompatible and there is no requirement that an IPsec-NAT + compatibility solution support AH transport or tunnel mode. + + Backward Compatibility and Interoperability + + An IPsec-NAT compatibility solution MUST be interoperable with + existing IKE/IPsec implementations, so that they can communicate + where no NA(P)T is present. This implies that an IPsec-NAT + compatibility solution MUST be backwards-compatible with IPsec as + defined in [RFC2401] and IKE as defined in [RFC2409]. In + addition, it SHOULD be able to detect the presence of a NA(P)T, so + that NA(P)T traversal support is only used when necessary. This + implies that it MUST be possible to determine that an existing IKE + implementation does not support NA(P)T traversal, so that a + standard IKE conversation can occur, as described in [RFC2407], + [RFC2408], and [RFC2409]. Note that while this implies initiation + of IKE to port 500, there is no requirement for a specific source + port, so that UDP source port 500 may or may not be used. + + Security + + An IPsec-NAT compatibility solution MUST NOT introduce additional + IKE or IPsec security vulnerabilities. For example, an acceptable + solution must demonstrate that it introduces no new denial of + service or spoofing vulnerabilities. IKE MUST be allowed to re- + key in a bi-directional manner as described in [RFC2408]. + + + + + +Aboba & Dixon Informational [Page 11] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + +4. Existing Solutions + +4.1. IPsec Tunnel Mode + + In a limited set of circumstances, it is possible for an IPsec tunnel + mode implementation, such as that described in [DHCP], to traverse + NA(P)T successfully. However, the requirements for successful + traversal are sufficiently limited so that a more general solution is + needed: + + 1) IPsec ESP. IPsec ESP tunnels do not cover the outer IP header + within the message integrity check, and so will not suffer + Authentication Data invalidation due to address translation. + IPsec tunnels also need not be concerned about checksum + invalidation. + + 2) No address validation. Most current IPsec tunnel mode + implementations do not perform source address validation so that + incompatibilities between IKE identifiers and source addresses + will not be detected. This introduces security vulnerabilities as + described in Section 5. + + 3) "Any to Any" SPD entries. IPsec tunnel mode clients can negotiate + "any to any" SPDs, which are not invalidated by address + translation. This effectively precludes use of SPDs for the + filtering of allowed tunnel traffic. + + 4) Single client operation. With only a single client behind a NAT, + there is no risk of overlapping SPDs. Since the NAT will not need + to arbitrate between competing clients, there is also no risk of + re-key mis-translation, or improper incoming SPI or cookie + de-multiplexing. + + 5) No fragmentation. When certificate authentication is used, IKE + fragmentation can be encountered. This can occur when certificate + chains are used, or even when exchanging a single certificate if + the key size, or the size of other certificate fields (such as the + distinguished name and other extensions), is large enough. + However, when pre-shared keys are used for authentication, + fragmentation is less likely. + + 6) Active sessions. Most VPN sessions typically maintain ongoing + traffic flow during their lifetime so that UDP port mappings are + less likely be removed due to inactivity. + + + + + + + +Aboba & Dixon Informational [Page 12] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + +4.2. RSIP + + RSIP, described in [RSIP] and [RSIPFrame], includes mechanisms for + IPsec traversal, as described in [RSIPsec]. By enabling host-NA(P)T + communication, RSIP addresses issues of IPsec SPI de-multiplexing, as + well as SPD overlap. It is thus suitable for use in enterprises, as + well as home networking scenarios. By enabling hosts behind a NAT to + share the external IP address of the NA(P)T (the RSIP gateway), this + approach is compatible with protocols including embedded IP + addresses. + + By tunneling IKE and IPsec packets, RSIP avoids changes to the IKE + and IPsec protocols, although major changes are required to host IKE + and IPsec implementations to retrofit them for RSIP-compatibility. + It is thus compatible with all existing protocols (AH/ESP) and modes + (transport and tunnel). + + In order to handle de-multiplexing of IKE re-keys, RSIP requires + floating of the IKE source port, as well as re-keying to the floated + port. As a result, interoperability with existing IPsec + implementations is not assured. + + RSIP does not satisfy the deployment requirements for an IPsec-NAT + compatibility solution because an RSIP-enabled host requires a + corresponding RSIP-enabled gateway in order to establish an IPsec SA + with another host. Since RSIP requires changes only to clients and + routers and not to servers, it is less difficult to deploy than IPv6. + However, for vendors, implementation of RSIP requires a substantial + fraction of the resources required for IPv6 support. Thus, RSIP + solves a "transitional" problem on a long-term time scale, which is + not useful. + +4.3. 6to4 + + 6to4, as described in [RFC3056] can form the basis for an IPsec-NAT + traversal solution. In this approach, the NAT provides IPv6 hosts + with an IPv6 prefix derived from the NAT external IPv4 address, and + encapsulates IPv6 packets in IPv4 for transmission to other 6to4 + hosts or 6to4 relays. This enables an IPv6 host using IPsec to + communicate freely to other hosts within the IPv6 or 6to4 clouds. + + While 6to4 is an elegant and robust solution where a single NA(P)T + separates a client and VPN gateway, it is not universally applicable. + Since 6to4 requires the assignment of a routable IPv4 address to the + NA(P)T in order to allow formation of an IPv6 prefix, it is not + usable where multiple NA(P)Ts exist between the client and VPN + + + + + +Aboba & Dixon Informational [Page 13] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + + gateway. For example, an NA(P)T with a private address on its + external interface cannot be used by clients behind it to obtain an + IPv6 prefix via 6to4. + + While 6to4 requires little additional support from hosts that already + support IPv6, it does require changes to NATs, which need to be + upgraded to support 6to4. As a result, 6to4 may not be suitable for + deployment in the short term. + +5. Security Considerations + + By definition, IPsec-NAT compatibility requires that hosts and + routers implementing IPsec be capable of securely processing packets + whose IP headers are not cryptographically protected. A number of + issues arise from this that are worth discussing. + + Since IPsec AH cannot pass through a NAT, one of the side effects of + providing an IPsec-NAT compatibility solution may be for IPsec ESP + with null encryption to be used in place of AH where a NAT exists + between the source and destination. However, it should be noted that + ESP with null encryption does not provide the same security + properties as AH. For example, there are security risks relating to + IPv6 source routing that are precluded by AH, but not by ESP with + null encryption. + + In addition, since ESP with any transform does not protect against + source address spoofing, some sort of source IP address sanity + checking needs to be performed. The importance of the anti-spoofing + check is not widely understood. There is normally an anti-spoofing + check on the Source IP Address as part of IPsec_{esp,ah}_input(). + This ensures that the packet originates from the same address as that + claimed within the original IKE Phase 1 and Phase 2 security + associations. When a receiving host is behind a NAT, this check + might not strictly be meaningful for unicast sessions, whereas in the + Global Internet this check is important for tunnel-mode unicast + sessions to prevent a spoofing attack described in [AuthSource], + which can occur when access controls on the receiver depend upon the + source IP address of verified ESP packets after decapsulation. + IPsec-NAT compatibility schemes should provide anti-spoofing + protection if it uses source addresses for access controls. + + Let us consider two hosts, A and C, both behind (different) NATs, who + negotiate IPsec tunnel mode SAs to router B. Hosts A and C may have + different privileges; for example, host A might belong to an employee + trusted to access much of the corporate Intranet, while C might be a + contractor only authorized to access a specific web site. + + + + + +Aboba & Dixon Informational [Page 14] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + + If host C sends a tunnel mode packet spoofing A's IP address as the + source, it is important that this packet not be accorded the + privileges corresponding to A. If authentication and integrity + checking is performed, but no anti-spoofing check (verifying that the + originating IP address corresponds to the SPI) then host C may be + allowed to reach parts of the network that are off limits. As a + result, an IPsec-NAT compatibility scheme MUST provide some degree of + anti-spoofing protection. + +6. References + +6.1. Normative References + + [RFC791] Postel, J., "Internet Protocol", STD 5, RFC 791, + September 1981. + + [RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC + 793, September 1981. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC2401] Atkinson, R. and S. Kent, "Security Architecture for the + Internet Protocol", RFC 2401, November 1998. + + [RFC2402] Kent, S. and R. Atkinson, "IP Authentication Header", + RFC 2402, November 1998. + + [RFC2406] Kent,S. and R. Atkinson, "IP Encapsulating Security + Payload (ESP)", RFC 2406, November 1998. + + [RFC2407] Piper, D., "The Internet IP Security Domain of + Interpretation for ISAKMP", RFC 2407, November 1998. + + [RFC2409] Harkins, D. and D. Carrel, "The Internet Key Exchange + (IKE)", RFC 2409, November 1998. + + [RFC2663] Srisuresh, P. and M. Holdredge, "IP Network Address + Translator (NAT) Terminology and Considerations", RFC + 2663, August 1999. + + [RFC3022] Srisuresh, P. and K. Egevang, "Traditional IP Network + Address Translator (Traditional NAT)", RFC 3022, January + 2001. + + + + + + + +Aboba & Dixon Informational [Page 15] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + +6.2. Informative References + + [RFC2408] Maughan, D., Schertler, M., Schneider, M. and J. Turner, + "Internet Security Association and Key Management + Protocol (ISAKMP)", RFC 2408, November 1998. + + [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C., + Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M., + Zhang, M. and V. Paxson, "Stream Control Transmission + Protocol", RFC 2960, October 2000. + + [RFC3056] Carpenter, B. and K. Moore, "Connection of IPv6 Domains + via IPv4 Clouds", RFC 3056, February 2001. + + [RFC3193] Patel, B., Aboba, B., Dixon, W., Zorn, G. and S. Booth, + "Securing L2TP using IPsec", RFC 3193, November 2001. + + [RFC3309] Stone, J., Stewart, R. and D. Otis, "Stream Control + Transmission Protocol (SCTP) Checksum Change", RFC 3309, + September 2002. + + [RSIPFrame] Borella, M., Lo, J., Grabelsky, D. and G. Montenegro, + "Realm Specific IP: Framework", RFC 3102, October 2001. + + [RSIP] Borella, M., Grabelsky, D., Lo, J. and K. Taniguchi, + "Realm Specific IP: Protocol Specification", RFC 3103, + October 2001. + + [RSIPsec] Montenegro, G. and M. Borella, "RSIP Support for End- + to-End IPsec", RFC 3104, October 2001. + + [DHCP] Patel, B., Aboba, B., Kelly, S. and V. Gupta, "Dynamic + Host Configuration Protocol (DHCPv4) Configuration of + IPsec Tunnel Mode", RFC 3456, January 2003. + + [AuthSource] Kent, S., "Authenticated Source Addresses", IPsec WG + Archive (ftp://ftp.ans.net/pub/archive/IPsec), Message- + Id: , January 5, + 1996. + + [AddIP] Stewart, R., et al., "Stream Control Transmission + Protocol (SCTP) Dynamic Address Reconfiguration", Work + in Progress. + + + + + + + + +Aboba & Dixon Informational [Page 16] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + +7. Acknowledgments + + Thanks to Steve Bellovin of AT&T Research, Michael Tuexen of Siemens, + Peter Ford of Microsoft, Ran Atkinson of Extreme Networks, and Daniel + Senie for useful discussions of this problem space. + +8. Authors' Addresses + + Bernard Aboba + Microsoft Corporation + One Microsoft Way + Redmond, WA 98052 + + Phone: +1 425 706 6605 + Fax: +1 425 936 7329 + EMail: bernarda@microsoft.com + + + William Dixon + V6 Security, Inc. + 601 Union Square, Suite #4200-300 + Seattle, WA 98101 + + EMail: ietf-wd@v6security.com + + + + + + + + + + + + + + + + + + + + + + + + + + + +Aboba & Dixon Informational [Page 17] + +RFC 3715 IPsec-NAT Compatibility Requirements March 2004 + + +9. Full Copyright Statement + + Copyright (C) The Internet Society (2004). This document is subject + to the rights, licenses and restrictions contained in BCP 78 and + except as set forth therein, the authors retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE + INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at ietf- + ipr@ietf.org. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + + + +Aboba & Dixon Informational [Page 18] + diff --git a/crypto/dist/ipsec-tools/src/racoon/rfc/rfc4109.txt b/crypto/dist/ipsec-tools/src/racoon/rfc/rfc4109.txt new file mode 100644 index 0000000000000..9f0f9b5f9a3a4 --- /dev/null +++ b/crypto/dist/ipsec-tools/src/racoon/rfc/rfc4109.txt @@ -0,0 +1,282 @@ + + + + + +Network Working Group P. Hoffman +Request for Comments: 4109 VPN Consortium +Updates: 2409 May 2005 +Category: Standards Track + + + Algorithms for Internet Key Exchange version 1 (IKEv1) + +Status of This Memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2005). + +Abstract + + The required and suggested algorithms in the original Internet Key + Exchange version 1 (IKEv1) specification do not reflect the current + reality of the IPsec market requirements. The original specification + allows weak security and suggests algorithms that are thinly + implemented. This document updates RFC 2409, the original + specification, and is intended for all IKEv1 implementations deployed + today. + + + + + + + + + + + + + + + + + + + + + + +Hoffman Standards Track [Page 1] + +RFC 4109 Algorithms for IKEv1 May 2005 + + +1. Introduction + + The original IKEv1 definition, [RFC2409], has a set of MUST-level and + SHOULD-level requirements that do not match the needs of IPsec users. + This document updates RFC 2409 by changing the algorithm requirements + defined there. + + The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, + SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, when they appear in this + document, are to be interpreted as described in [RFC2119]. + +2. Old Algorithm Requirements + + RFC 2409 has the following MUST-level and SHOULD-level requirements: + + o DES for encryption MUST be supported. + o MD5 and SHA-1 for hashing and HMAC functions MUST be supported. + o Pre-shared secrets for authentication MUST be supported. + o Diffie-Hellman MODP group 1 (discrete log 768 bits) MUST be + supported. + o TripleDES for encryption SHOULD be supported. + o Tiger for hashing SHOULD be supported. + o DSA and RSA for authentication with signatures SHOULD be + supported. + o RSA for authentication with encryption SHOULD be supported. + o Diffie-Hellman MODP group 2 (discrete log 1024 bits) SHOULD be + supported. + + RFC 2409 gives two conflicting requirement levels for Diffie-Hellman + MODP groups with elliptic curves. Section 4 of that specification + says that "IKE implementations ... MAY support ECP and EC2N groups", + but Sections 6.3 and 6.4 say that MODP groups 3 and 4 for EC2N groups + SHOULD be supported. + +3. New Algorithm Requirements + + The new requirements for IKEv1 are listed here. Note that some of + the requirements are the same as those in RFC 2409, whereas others + are changed. + + o TripleDES for encryption MUST be supported. + o AES-128 in CBC mode [RFC3602] for encryption SHOULD be supported. + o SHA-1 for hashing and HMAC functions MUST be supported. + o Pre-shared secrets for authentication MUST be supported. + o AES-128 in XCBC mode for PRF functions ([RFC3566] and [RFC3664]) + SHOULD be supported. + o Diffie-Hellman MODP group 2 (discrete log 1024 bits) MUST be + supported. + + + +Hoffman Standards Track [Page 2] + +RFC 4109 Algorithms for IKEv1 May 2005 + + + o Diffie-Hellman MODP group 14 (discrete log 2048 bits) [RFC3526] + SHOULD be supported. + o RSA for authentication with signatures SHOULD be supported. + + If additional updates are made to IKEv1 in the future, then it is + very likely that implementation of AES-128 in CBC mode for encryption + will become mandatory. + + The other algorithms that were listed at MUST-level and SHOULD-level + in RFC 2409 are now MAY-level. This includes DES for encryption, MD5 + and Tiger for hashing, Diffie-Hellman MODP group 1, Diffie-Hellman + MODP groups with elliptic curves, DSA for authentication with + signatures, and RSA for authentication with encryption. + + DES for encryption, MD5 for hashing, and Diffie-Hellman MODP group 1 + are dropped to MAY due to cryptographic weakness. + + Tiger for hashing, Diffie-Hellman MODP groups with elliptic curves, + DSA for authentication with signatures, and RSA for authentication + with encryption are dropped due to lack of any significant deployment + and interoperability. + +4. Summary + + Algorithm RFC 2409 This document + ------------------------------------------------------------------ + DES for encryption MUST MAY (crypto weakness) + TripleDES for encryption SHOULD MUST + AES-128 for encryption N/A SHOULD + MD5 for hashing and HMAC MUST MAY (crypto weakness) + SHA1 for hashing and HMAC MUST MUST + Tiger for hashing SHOULD MAY (lack of deployment) + AES-XCBC-MAC-96 for PRF N/A SHOULD + Pre-shared secrets MUST MUST + RSA with signatures SHOULD SHOULD + DSA with signatures SHOULD MAY (lack of deployment) + RSA with encryption SHOULD MAY (lack of deployment) + D-H Group 1 (768) MUST MAY (crypto weakness) + D-H Group 2 (1024) SHOULD MUST + D-H Group 14 (2048) N/A SHOULD + D-H elliptic curves SHOULD MAY (lack of deployment) + +5. Security Considerations + + This document is all about security. All the algorithms that are + either MUST-level or SHOULD-level in the "new algorithm requirements" + section of this document are believed to be robust and secure at the + time of this writing. + + + +Hoffman Standards Track [Page 3] + +RFC 4109 Algorithms for IKEv1 May 2005 + + +6. Normative References + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC2409] Harkins, D. and D. Carrel, "The Internet Key Exchange + (IKE)", RFC 2409, November 1998. + + [RFC3526] Kivinen, T. and M. Kojo, "More Modular Exponential (MODP) + Diffie-Hellman groups for Internet Key Exchange (IKE)", + RFC 3526, May 2003. + + [RFC3566] Frankel, S. and H. Herbert, "The AES-XCBC-MAC-96 Algorithm + and Its Use With IPsec", RFC 3566, September 2003. + + [RFC3602] Frankel, S., Glenn, R., and S. Kelly, "The AES-CBC Cipher + Algorithm and Its Use with IPsec", RFC 3602, September + 2003. + + [RFC3664] Hoffman, P., "The AES-XCBC-PRF-128 Algorithm for the + Internet Key Exchange Protocol (IKE)", RFC 3664, January + 2004. + +Author's Address + + Paul Hoffman + VPN Consortium + 127 Segre Place + Santa Cruz, CA 95060 + US + + EMail: paul.hoffman@vpnc.org + + + + + + + + + + + + + + + + + + + +Hoffman Standards Track [Page 4] + +RFC 4109 Algorithms for IKEv1 May 2005 + + +Full Copyright Statement + + Copyright (C) The Internet Society (2005). + + This document is subject to the rights, licenses and restrictions + contained in BCP 78, and except as set forth therein, the authors + retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE + INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at ietf- + ipr@ietf.org. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + +Hoffman Standards Track [Page 5] + diff --git a/crypto/dist/ipsec-tools/src/racoon/sainfo.c b/crypto/dist/ipsec-tools/src/racoon/sainfo.c index c756d6b2dd326..19e07ae16d722 100644 --- a/crypto/dist/ipsec-tools/src/racoon/sainfo.c +++ b/crypto/dist/ipsec-tools/src/racoon/sainfo.c @@ -1,4 +1,4 @@ -/* $NetBSD: sainfo.c,v 1.1.1.2 2005/02/23 14:54:27 manu Exp $ */ +/* $NetBSD: sainfo.c,v 1.1.1.3 2006/09/09 16:12:20 manu Exp $ */ /* $KAME: sainfo.c,v 1.16 2003/06/27 07:32:39 sakane Exp $ */ @@ -68,7 +68,7 @@ #include "sainfo.h" #include "gcmalloc.h" -static LIST_HEAD(_sitree, sainfo) sitree; +static LIST_HEAD(_sitree, sainfo) sitree, sitree_save, sitree_tmp; /* %%% * modules for ipsec sa info @@ -90,8 +90,45 @@ getsainfo(src, dst, peer) if (peer == NULL) pass = 2; + + /* debug level output */ + if(loglevel >= LLV_DEBUG) { + char *dsrc, *ddst, *dpeer, *dclient; + + if (src == NULL) + dsrc = strdup("ANONYMOUS"); + else + dsrc = ipsecdoi_id2str(src); + + if (dst == NULL) + ddst = strdup("ANONYMOUS"); + else + ddst = ipsecdoi_id2str(dst); + + if (peer == NULL) + dpeer = strdup("NULL"); + else + dpeer = ipsecdoi_id2str(peer); + + plog(LLV_DEBUG, LOCATION, NULL, + "getsainfo params: src=\'%s\', dst=\'%s\', peer=\'%s\'\n", + dsrc, ddst, dpeer ); + + racoon_free(dsrc); + racoon_free(ddst); + racoon_free(dpeer); + } + again: + plog(LLV_DEBUG, LOCATION, NULL, + "getsainfo pass #%i\n", pass); + LIST_FOREACH(s, &sitree, chain) { + + const char *sainfostr = sainfo2str(s); + plog(LLV_DEBUG, LOCATION, NULL, + "evaluating sainfo: %s\n", sainfostr); + if (s->id_i != NULL) { if (pass == 2) continue; @@ -99,7 +136,7 @@ getsainfo(src, dst, peer) continue; } else if (pass == 1) continue; - if (s->idsrc == NULL) { + if (s->idsrc == NULL && s->iddst == NULL) { anonymous = s; continue; } @@ -111,9 +148,12 @@ getsainfo(src, dst, peer) continue; } - if (memcmp(src->v, s->idsrc->v, s->idsrc->l) == 0 - && memcmp(dst->v, s->iddst->v, s->iddst->l) == 0) + if ((s->idsrc == NULL || src == NULL || + memcmp(src->v, s->idsrc->v, s->idsrc->l) == 0) && + (s->iddst == NULL || dst == NULL || + memcmp(dst->v, s->iddst->v, s->iddst->l) == 0)){ return s; + } } if (anonymous) { @@ -156,6 +196,11 @@ delsainfo(si) if (si->iddst) vfree(si->iddst); +#ifdef ENABLE_HYBRID + if (si->group) + vfree(si->group); +#endif + racoon_free(si); } @@ -234,19 +279,47 @@ const char * sainfo2str(si) const struct sainfo *si; { - static char buf[256]; - - if (si->idsrc == NULL) - snprintf(buf, sizeof(buf), "anonymous"); - else { - snprintf(buf, sizeof(buf), "%s", ipsecdoi_id2str(si->idsrc)); - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - " %s", ipsecdoi_id2str(si->iddst)); - } + static char buf[256]; + + char *idsrc = NULL, *iddst = NULL, *id_i; + + if (si->idsrc == NULL) + idsrc = strdup("ANONYMOUS"); + else + idsrc = ipsecdoi_id2str(si->idsrc); + + if (si->iddst == NULL) + iddst = strdup("ANONYMOUS"); + else + iddst = ipsecdoi_id2str(si->iddst); + + if (si->id_i == NULL) + id_i = strdup("ANY"); + else + id_i = ipsecdoi_id2str(si->id_i); + + snprintf(buf, 255, "src=\'%s\', dst=\'%s\', peer=\'%s\'", idsrc, iddst, id_i); + + racoon_free(idsrc); + racoon_free(iddst); + racoon_free(id_i); + + return buf; +} - if (si->id_i != NULL) - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - " from %s", ipsecdoi_id2str(si->id_i)); +void save_sainfotree(void){ + sitree_save=sitree; + initsainfo(); +} + +void save_sainfotree_flush(void){ + sitree_tmp=sitree; + sitree=sitree_save; + flushsainfo(); + sitree=sitree_tmp; +} - return buf; +void save_sainfotree_restore(void){ + flushsainfo(); + sitree=sitree_save; } diff --git a/crypto/dist/ipsec-tools/src/racoon/sainfo.h b/crypto/dist/ipsec-tools/src/racoon/sainfo.h index ceea15455544e..5975e677d60a0 100644 --- a/crypto/dist/ipsec-tools/src/racoon/sainfo.h +++ b/crypto/dist/ipsec-tools/src/racoon/sainfo.h @@ -1,6 +1,6 @@ -/* $NetBSD: sainfo.h,v 1.1.1.2 2005/02/23 14:54:27 manu Exp $ */ +/* $NetBSD: sainfo.h,v 1.1.1.3 2006/09/09 16:12:20 manu Exp $ */ -/* Id: sainfo.h,v 1.3 2004/06/11 16:00:17 ludvigm Exp */ +/* Id: sainfo.h,v 1.5 2006/07/09 17:19:38 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -46,6 +46,10 @@ struct sainfo { * If idsrc == NULL, that is anonymous entry. */ +#ifdef ENABLE_HYBRID + vchar_t *group; +#endif + time_t lifetime; int lifebyte; int pfs_group; /* only use when pfs is required. */ @@ -75,4 +79,8 @@ extern void delsainfoalg __P((struct sainfoalg *)); extern void inssainfoalg __P((struct sainfoalg **, struct sainfoalg *)); extern const char * sainfo2str __P((const struct sainfo *)); +extern void save_sainfotree __P((void)); +extern void save_sainfotree_flush __P((void)); +extern void save_sainfotree_restore __P((void)); + #endif /* _SAINFO_H */ diff --git a/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.in b/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.in index 11f05eeb5948f..29b7951694272 100644 --- a/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.in +++ b/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.in @@ -61,7 +61,7 @@ remote anonymous nonce_size 16; initial_contact on; - proposal_check obey; # obey, strict, or claim + proposal_check strict; # obey, strict, or claim proposal { encryption_algorithm 3des; diff --git a/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample b/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample index 2f4303cae2f57..631910f28300d 100644 --- a/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample +++ b/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample @@ -39,10 +39,12 @@ remote anonymous dh_group 2 ; } - # the configuration makes racoon (as a responder) to obey the - # initiator's lifetime and PFS group proposal. - # this makes testing so much easier. - proposal_check obey; + # 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). diff --git a/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample-inherit b/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample-inherit index a71dc74996af7..9e1185f1021e4 100644 --- a/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample-inherit +++ b/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample-inherit @@ -1,4 +1,4 @@ -# Id: racoon.conf.sample-inherit,v 1.1.12.1 2005/04/18 11:10:55 manubsd Exp +# 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. @@ -17,7 +17,7 @@ remote anonymous nonce_size 16; initial_contact on; - proposal_check obey; # obey, strict or claim + proposal_check strict; # obey, strict or claim proposal { encryption_algorithm 3des; diff --git a/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample-natt b/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample-natt index 4baf10ef31d7e..645b4de77e63f 100644 --- a/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample-natt +++ b/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample-natt @@ -1,4 +1,4 @@ -# Id: racoon.conf.sample-natt,v 1.3.10.1 2005/04/18 11:10:55 manubsd Exp +# 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. @@ -83,7 +83,7 @@ remote anonymous dh_group 2; } - proposal_check obey; + proposal_check strict; } # Phase 2 proposal (for IPsec SA) diff --git a/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample-plainrsa b/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample-plainrsa index de0c457e5d42e..8447eb30c32c9 100644 --- a/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample-plainrsa +++ b/crypto/dist/ipsec-tools/src/racoon/samples/racoon.conf.sample-plainrsa @@ -1,4 +1,4 @@ -# Id: racoon.conf.sample-plainrsa,v 1.2.10.1 2005/04/18 11:10:55 manubsd Exp +# 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 @@ -26,7 +26,7 @@ remote anonymous peers_certfile plain_rsa "pubkey2.rsa"; # Standard setup follows... - proposal_check obey; + proposal_check strict; proposal { encryption_algorithm 3des; diff --git a/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/client/phase1-up.sh b/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/client/phase1-up.sh index 991d69321ba79..a2e70b43c7200 100755 --- a/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/client/phase1-up.sh +++ b/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/client/phase1-up.sh @@ -33,7 +33,7 @@ echo "nameserver ${INTERNAL_DNS4}" >> /etc/resolv.conf case `uname -s` in NetBSD) if=`netstat -rn|awk '($1 == "default"){print $7}'` - ifconfig ${if} alias ${INTERNAL_ADDR4} + ifconfig ${if} alias ${INTERNAL_ADDR4} netmask ${INTERNAL_NETMASK4} route delete default route add default ${DEFAULT_GW} -ifa ${INTERNAL_ADDR4} ;; diff --git a/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/client/racoon.conf b/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/client/racoon.conf index 7aa0f7cbbffec..669be36202dce 100644 --- a/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/client/racoon.conf +++ b/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/client/racoon.conf @@ -8,7 +8,7 @@ listen { remote 192.0.2.50 { exchange_mode aggressive; ca_type x509 "root-ca.crt"; - proposal_check obey; + proposal_check strict; nat_traversal on; ike_frag on; mode_cfg on; diff --git a/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf b/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf index f5f4a173bd249..ae7d603a43b2f 100644 --- a/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf +++ b/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf @@ -8,7 +8,7 @@ remote anonymous { exchange_mode aggressive; certificate_type x509 "server.crt" "server.key"; my_identifier asn1dn; - proposal_check claim; + proposal_check strict; generate_policy on; nat_traversal on; dpd_delay 20; diff --git a/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf-radius b/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf-radius index 1470530c8ef70..24e8d4e8e9845 100644 --- a/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf-radius +++ b/crypto/dist/ipsec-tools/src/racoon/samples/roadwarrior/server/racoon.conf-radius @@ -8,7 +8,7 @@ remote anonymous { exchange_mode aggressive; certificate_type x509 "server.crt" "server.key"; my_identifier asn1dn; - proposal_check claim; + proposal_check strict; generate_policy on; nat_traversal on; dpd_delay 20; diff --git a/crypto/dist/ipsec-tools/src/racoon/schedule.c b/crypto/dist/ipsec-tools/src/racoon/schedule.c index 5483d1ceffe64..bdeea8a51361b 100644 --- a/crypto/dist/ipsec-tools/src/racoon/schedule.c +++ b/crypto/dist/ipsec-tools/src/racoon/schedule.c @@ -1,4 +1,4 @@ -/* $NetBSD: schedule.c,v 1.1.1.2 2005/02/23 14:54:27 manu Exp $ */ +/* $NetBSD: schedule.c,v 1.1.1.3 2006/09/09 16:12:20 manu Exp $ */ /* $KAME: schedule.c,v 1.19 2001/11/05 10:53:19 sakane Exp $ */ @@ -310,7 +310,7 @@ getstdin() struct scheddump *scbuf, *p; int len; sched_dump((caddr_t *)&scbuf, &len); - if (buf == NULL) + if (scbuf == NULL) return; for (p = scbuf; len; p++) { printf("xtime=%ld\n", p->xtime); diff --git a/crypto/dist/ipsec-tools/src/racoon/schedule.h b/crypto/dist/ipsec-tools/src/racoon/schedule.h index 2cc7585ecc4b2..4c35065a882e5 100644 --- a/crypto/dist/ipsec-tools/src/racoon/schedule.h +++ b/crypto/dist/ipsec-tools/src/racoon/schedule.h @@ -1,6 +1,6 @@ -/* $NetBSD: schedule.h,v 1.1.1.2 2005/02/23 14:54:27 manu Exp $ */ +/* $NetBSD: schedule.h,v 1.1.1.3 2006/09/09 16:12:20 manu Exp $ */ -/* Id: schedule.h,v 1.4 2004/11/18 15:14:44 ludvigm Exp */ +/* Id: schedule.h,v 1.5 2006/05/03 21:53:42 vanhu Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -35,7 +35,7 @@ #define _SCHEDULE_H #include -#include +#include "gnuc.h" /* scheduling table */ /* the head is the nearest event. */ diff --git a/crypto/dist/ipsec-tools/src/racoon/session.c b/crypto/dist/ipsec-tools/src/racoon/session.c index 181b62e88c092..c9885c9836c02 100644 --- a/crypto/dist/ipsec-tools/src/racoon/session.c +++ b/crypto/dist/ipsec-tools/src/racoon/session.c @@ -1,4 +1,4 @@ -/* $NetBSD: session.c,v 1.1.1.4 2005/11/21 14:12:11 manu Exp $ */ +/* $NetBSD: session.c,v 1.1.1.5 2006/09/09 16:12:20 manu Exp $ */ /* $KAME: session.c,v 1.32 2003/09/24 02:01:17 jinmei Exp $ */ @@ -64,6 +64,9 @@ #include #include +#include +#include + #include "libpfkey.h" #include "var.h" @@ -78,6 +81,8 @@ #include "evt.h" #include "cfparse_proto.h" #include "isakmp_var.h" +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" #include "admin_var.h" #include "admin.h" #include "privsep.h" @@ -91,6 +96,11 @@ #include "nattraversal.h" #endif + +#include "algorithm.h" /* XXX ??? */ + +#include "sainfo.h" + static void close_session __P((void)); static void check_rtsock __P((void *)); static void initfds __P((void)); @@ -104,7 +114,7 @@ static int close_sockets __P((void)); static fd_set mask0; static fd_set maskdying; static int nfds = 0; -static int sigreq = 0; +static volatile sig_atomic_t sigreq[NSIG + 1]; static int dying = 0; int @@ -117,6 +127,7 @@ session(void) char pid_file[MAXPATHLEN]; FILE *fp; pid_t racoon_pid = 0; + int i; /* initialize schedular */ sched_init(); @@ -142,7 +153,8 @@ session(void) if (privsep_init() != 0) exit(1); - sigreq = 0; + for (i = 0; i <= NSIG; i++) + sigreq[i] = 0; /* write .pid file */ racoon_pid = getpid(); @@ -226,6 +238,9 @@ session(void) static void close_session() { +#ifdef ENABLE_FASTQUIT + flushph2(); +#endif flushph1(); close_sockets(); backupsa_clean(); @@ -319,57 +334,153 @@ RETSIGTYPE signal_handler(sig) int sig; { - switch (sig) { - case SIGCHLD: - { - pid_t pid; - int s; + /* Do not just set it to 1, because we may miss some signals by just setting + * values to 0/1 + */ + sigreq[sig]++; +} - pid = wait(&s); - } - break; -#ifdef DEBUG_RECORD_MALLOCATION - case SIGUSR2: - DRM_dump(); - break; +/* 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 - default: - /* XXX should be blocked any signal ? */ - sigreq = sig; - break; + + save_sainfotree(); + + /* TODO: save / restore / flush old lcconf (?) / rmtree + */ +/* initlcconf();*/ /* racoon_conf ? ! */ + + save_rmconf(); + initrmconf(); + + /* Do a part of pfkey_init() ? + * SPD reload ? + */ + + save_params(); + 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 + + /* + * init_myaddr() ? + * If running in privilege separation, do not reinitialize + * the IKE listener, as we will not have the right to + * setsockopt(IP_IPSEC_POLICY). + */ + if (geteuid() == 0) { + struct myaddrs *p; + + for (p = lcconf->myaddrs; p; p = p->next) { + if (!p->addr) { + continue; + } + close(p->sock); + p->sock=-1; + } + + isakmp_open(); + } + + /* Revalidate ph1 / ph2tree !!! + * update ctdtree if removing some ph1 ! + */ + revalidate_ph12(); + /* Update ctdtree ? + */ + + save_sainfotree_flush(); + save_rmconf_flush(); } static void check_sigreq() { - switch (sigreq) { - case 0: - return; + int sig; - case SIGHUP: - isakmp_close(); - close(lcconf->rtsock); - if (cfreparse()) { - plog(LLV_ERROR, LOCATION, NULL, - "configuration read failed\n"); - exit(1); - } - initmyaddr(); - isakmp_init(); - initfds(); - sigreq = 0; - break; + /* + * XXX We are not able to tell if we got + * several time the same signal. This is + * not a problem for the current code, + * but we shall remember this limitation. + */ + for (sig = 0; sig <= NSIG; sig++) { + if (sigreq[sig] == 0) + continue; - default: - plog(LLV_INFO, LOCATION, NULL, "caught signal %d\n", sigreq); - EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL); - pfkey_send_flush(lcconf->sock_pfkey, SADB_SATYPE_UNSPEC); - sched_new(1, check_flushsa_stub, NULL); - sigreq = 0; - dying = 1; + sigreq[sig]--; + switch(sig) { + case 0: + return; + + /* Catch up childs, mainly scripts. + */ + case SIGCHLD: + { + pid_t pid; + int s; + + pid = wait(&s); + } 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); + EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL); + pfkey_send_flush(lcconf->sock_pfkey, + SADB_SATYPE_UNSPEC); +#ifdef ENABLE_FASTQUIT + close_session(); +#else + sched_new(1, check_flushsa_stub, NULL); +#endif + dying = 1; + break; + + default: + plog(LLV_INFO, LOCATION, NULL, + "caught signal %d\n", sig); + break; + } } } diff --git a/crypto/dist/ipsec-tools/src/racoon/sockmisc.c b/crypto/dist/ipsec-tools/src/racoon/sockmisc.c index 5a906d93cc316..2e03b87ca1eea 100644 --- a/crypto/dist/ipsec-tools/src/racoon/sockmisc.c +++ b/crypto/dist/ipsec-tools/src/racoon/sockmisc.c @@ -1,6 +1,6 @@ -/* $NetBSD: sockmisc.c,v 1.1.1.4 2005/10/14 13:21:50 manu Exp $ */ +/* $NetBSD: sockmisc.c,v 1.1.1.5 2006/09/09 16:12:21 manu Exp $ */ -/* Id: sockmisc.c,v 1.17.4.4 2005/10/04 09:54:27 manubsd Exp */ +/* Id: sockmisc.c,v 1.24 2006/05/07 21:32:59 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -63,6 +63,7 @@ #include "sockmisc.h" #include "debug.h" #include "gcmalloc.h" +#include "debugrm.h" #include "libpfkey.h" #ifndef IP_IPSEC_POLICY @@ -652,7 +653,8 @@ sendfromto(s, buf, buflen, src, dst, cnt) #endif (void *)&yes, sizeof(yes)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt (%s)\n", strerror(errno)); + "setsockopt SO_REUSEPORT (%s)\n", + strerror(errno)); close(sendsock); return -1; } @@ -661,7 +663,8 @@ sendfromto(s, buf, buflen, src, dst, cnt) setsockopt(sendsock, IPPROTO_IPV6, IPV6_USE_MIN_MTU, (void *)&yes, sizeof(yes)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt (%s)\n", strerror(errno)); + "setsockopt IPV6_USE_MIN_MTU (%s)\n", + strerror(errno)); close(sendsock); return -1; } @@ -740,7 +743,7 @@ setsockopt_bypass(so, family) IP_IPSEC_POLICY : IPV6_IPSEC_POLICY), buf, ipsec_get_policylen(buf)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt (%s)\n", + "setsockopt IP_IPSEC_POLICY (%s)\n", strerror(errno)); return -1; } @@ -759,7 +762,7 @@ setsockopt_bypass(so, family) IP_IPSEC_POLICY : IPV6_IPSEC_POLICY), buf, ipsec_get_policylen(buf)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt (%s)\n", + "setsockopt IP_IPSEC_POLICY (%s)\n", strerror(errno)); return -1; } @@ -871,8 +874,10 @@ naddrwop2str_fromto(const char *format, const struct netaddr *saddr, static char buf[2*(NI_MAXHOST + NI_MAXSERV + 10) + 100]; char *src, *dst; - src = strdup(naddrwop2str(saddr)); - dst = strdup(naddrwop2str(daddr)); + 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); @@ -891,8 +896,10 @@ saddr2str_fromto(format, saddr, daddr) static char buf[2*(NI_MAXHOST + NI_MAXSERV + 10) + 100]; char *src, *dst; - src = strdup(saddr2str(saddr)); - dst = strdup(saddr2str(daddr)); + 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); @@ -997,7 +1004,7 @@ naddr_score(const struct netaddr *naddr, const struct sockaddr *saddr) { static const struct netaddr naddr_any; /* initialized to all-zeros */ struct sockaddr sa; - uint16_t naddr_port, saddr_port; + u_int16_t naddr_port, saddr_port; int port_score; if (!naddr || !saddr) { @@ -1029,9 +1036,12 @@ naddr_score(const struct netaddr *naddr, const struct sockaddr *saddr) mask_sockaddr(&sa, saddr, naddr->prefix); if (loglevel >= LLV_DEBUG) { /* debug only */ char *a1, *a2, *a3; - a1 = strdup(naddrwop2str(naddr)); - a2 = strdup(saddrwop2str(saddr)); - a3 = strdup(saddrwop2str(&sa)); + 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); diff --git a/crypto/dist/ipsec-tools/src/racoon/sockmisc.h b/crypto/dist/ipsec-tools/src/racoon/sockmisc.h index f034fe33172a3..ff0aa0c981b51 100644 --- a/crypto/dist/ipsec-tools/src/racoon/sockmisc.h +++ b/crypto/dist/ipsec-tools/src/racoon/sockmisc.h @@ -1,6 +1,6 @@ -/* $NetBSD: sockmisc.h,v 1.1.1.4 2005/10/14 13:21:50 manu Exp $ */ +/* $NetBSD: sockmisc.h,v 1.1.1.5 2006/09/09 16:12:21 manu Exp $ */ -/* Id: sockmisc.h,v 1.5.10.4 2005/10/04 09:54:27 manubsd Exp */ +/* Id: sockmisc.h,v 1.9 2005/10/05 16:55:41 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. diff --git a/crypto/dist/ipsec-tools/src/racoon/strnames.c b/crypto/dist/ipsec-tools/src/racoon/strnames.c index 94edcfcfa4746..052dd0961198a 100644 --- a/crypto/dist/ipsec-tools/src/racoon/strnames.c +++ b/crypto/dist/ipsec-tools/src/racoon/strnames.c @@ -1,4 +1,4 @@ -/* $NetBSD: strnames.c,v 1.1.1.3 2005/08/07 08:48:14 manu Exp $ */ +/* $NetBSD: strnames.c,v 1.1.1.4 2006/09/09 16:12:22 manu Exp $ */ /* $KAME: strnames.c,v 1.25 2003/11/13 10:53:26 itojun Exp $ */ @@ -47,6 +47,9 @@ #include #include +#ifdef ENABLE_HYBRID +#include +#endif #include "var.h" #include "misc.h" @@ -55,6 +58,11 @@ #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" @@ -220,6 +228,7 @@ static struct ksmap name_isakmp_etype[] = { { 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 }, @@ -271,6 +280,9 @@ static struct ksmap name_isakmp_notify_msg[] = { { ISAKMP_NTYPE_RESPONDER_LIFETIME, "RESPONDER-LIFETIME", NULL }, { ISAKMP_NTYPE_REPLAY_STATUS, "REPLAY-STATUS", NULL }, { ISAKMP_NTYPE_INITIAL_CONTACT, "INITIAL-CONTACT", NULL }, +#ifdef ENABLE_HYBRID +{ ISAKMP_NTYPE_UNITY_HEARTBEAT, "HEARTBEAT (Unity)", NULL }, +#endif { ISAKMP_LOG_RETRY_LIMIT_REACHED, "RETRY-LIMIT-REACHED", NULL }, }; @@ -287,25 +299,27 @@ s_isakmp_notify_msg(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_GSS, "gss id", NULL }, +{ 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 * @@ -319,6 +333,79 @@ s_isakmp_nptype(k) 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 }, @@ -587,6 +674,7 @@ static struct ksmap name_attr_isakmp_enc[] = { { 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 * @@ -621,19 +709,25 @@ s_attr_isakmp_hash(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 }, -{ OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, "GSS-API on Kerberos 5", NULL }, +{ 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_I, "Hybrid DSS server", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I, "Hybrid RSA server", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, "Hybrid DSS client", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, "Hybrid RSA client", NULL }, +{ 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 }; @@ -780,7 +874,7 @@ static struct ksmap name_pfkey_type[] = { { SADB_EXPIRE, "EXPIRE", NULL }, { SADB_FLUSH, "FLUSH", NULL }, { SADB_DUMP, "DUMP", NULL }, -{ SADB_X_PROMISC, "X_PRIMISC", 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 }, @@ -792,9 +886,12 @@ static struct ksmap name_pfkey_type[] = { { SADB_X_SPDSETIDX, "X_SPDSETIDX", NULL }, { SADB_X_SPDEXPIRE, "X_SPDEXPIRE", NULL }, { SADB_X_SPDDELETE2, "X_SPDDELETE2", NULL }, -#ifdef ENABLE_NATT +#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 * diff --git a/crypto/dist/ipsec-tools/src/racoon/strnames.h b/crypto/dist/ipsec-tools/src/racoon/strnames.h index 374df8e947b12..254863480df72 100644 --- a/crypto/dist/ipsec-tools/src/racoon/strnames.h +++ b/crypto/dist/ipsec-tools/src/racoon/strnames.h @@ -1,6 +1,6 @@ -/* $NetBSD: strnames.h,v 1.1.1.2 2005/02/23 14:54:28 manu Exp $ */ +/* $NetBSD: strnames.h,v 1.1.1.3 2006/09/09 16:12:23 manu Exp $ */ -/* Id: strnames.h,v 1.5 2004/07/12 20:37:13 ludvigm Exp */ +/* Id: strnames.h,v 1.7 2005/04/18 10:04:26 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -72,5 +72,9 @@ 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/crypto/dist/ipsec-tools/src/racoon/throttle.c b/crypto/dist/ipsec-tools/src/racoon/throttle.c index f5132191e390a..ecb75d1af1c00 100644 --- a/crypto/dist/ipsec-tools/src/racoon/throttle.c +++ b/crypto/dist/ipsec-tools/src/racoon/throttle.c @@ -1,6 +1,6 @@ -/* $NetBSD: throttle.c,v 1.1.1.2 2005/02/23 14:54:28 manu Exp $ */ +/* $NetBSD: throttle.c,v 1.1.1.3 2006/09/09 16:12:23 manu Exp $ */ -/* Id: throttle.c,v 1.2 2004/11/30 07:40:13 manubsd Exp */ +/* Id: throttle.c,v 1.5 2006/04/05 20:54:50 manubsd Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -51,6 +51,7 @@ #include #include +#include #include "vmbuf.h" #include "misc.h" @@ -102,14 +103,15 @@ throttle_host(addr, authfail) now = time(NULL); - TAILQ_FOREACH_REVERSE(te, &throttle_list, throttle_list, next) { - /* - * Remove outdated entries - */ +restart: + RACOON_TAILQ_FOREACH_REVERSE(te, &throttle_list, throttle_list, next) { + /* + * Remove outdated entries + */ if (te->penalty < now) { TAILQ_REMOVE(&throttle_list, te, next); racoon_free(te); - continue; + goto restart; } if (cmpsaddrwop(addr, (struct sockaddr *)&te->host) == 0) { diff --git a/crypto/dist/ipsec-tools/src/racoon/vendorid.c b/crypto/dist/ipsec-tools/src/racoon/vendorid.c index ce31d1984b863..db5494656dcc3 100644 --- a/crypto/dist/ipsec-tools/src/racoon/vendorid.c +++ b/crypto/dist/ipsec-tools/src/racoon/vendorid.c @@ -1,6 +1,6 @@ -/* $NetBSD: vendorid.c,v 1.1.1.2 2005/02/23 14:54:28 manu Exp $ */ +/* $NetBSD: vendorid.c,v 1.1.1.3 2006/09/09 16:12:23 manu Exp $ */ -/* Id: vendorid.c,v 1.7 2005/01/29 16:34:25 vanhu Exp */ +/* Id: vendorid.c,v 1.10 2006/02/22 16:10:21 vanhu Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -55,7 +55,7 @@ #include "crypto_openssl.h" static struct vendor_id all_vendor_ids[] = { -{ VENDORID_KAME , "KAME/racoon" }, +{ VENDORID_IPSEC_TOOLS, "IPSec-Tools" }, { VENDORID_GSSAPI_LONG, "A GSS-API Authentication Method for IKE" }, { VENDORID_GSSAPI , "GSSAPI" }, { VENDORID_MS_NT5 , "MS NT5 ISAKMPOAKLEY" }, @@ -75,6 +75,8 @@ static struct vendor_id all_vendor_ids[] = { { 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])) @@ -139,7 +141,7 @@ compute_vendorids (void) for (i = 0; i < NUMVENDORIDS; i++) { /* VENDORID_DPD is not a MD5 sum... */ - if(i == VENDORID_DPD){ + 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, @@ -181,7 +183,7 @@ set_vendorid(int vendorid) * The default unknown ID gets translated to * KAME/racoon. */ - vendorid = VENDORID_KAME; + vendorid = VENDORID_DEFAULT; } current = lookup_vendor_id_by_id(vendorid); @@ -232,6 +234,7 @@ check_vendorid(struct isakmp_gen *gen) unknown: plog(LLV_DEBUG, LOCATION, NULL, "received unknown Vendor ID\n"); + plogdump(LLV_DEBUG, (char *)(gen + 1), vidlen); return (VENDORID_UNKNOWN); } diff --git a/crypto/dist/ipsec-tools/src/racoon/vendorid.h b/crypto/dist/ipsec-tools/src/racoon/vendorid.h index 2a5dd85b4f8ce..14585beebec38 100644 --- a/crypto/dist/ipsec-tools/src/racoon/vendorid.h +++ b/crypto/dist/ipsec-tools/src/racoon/vendorid.h @@ -1,6 +1,6 @@ -/* $NetBSD: vendorid.h,v 1.1.1.2 2005/02/23 14:54:28 manu Exp $ */ +/* $NetBSD: vendorid.h,v 1.1.1.3 2006/09/09 16:12:23 manu Exp $ */ -/* Id: vendorid.h,v 1.10 2005/01/29 16:34:25 vanhu Exp */ +/* Id: vendorid.h,v 1.11 2006/02/17 14:09:10 vanhu Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -37,8 +37,11 @@ /* The unknown vendor ID. */ #define VENDORID_UNKNOWN -1 + /* Our default vendor ID. */ -#define VENDORID_KAME 0 +#define VENDORID_DEFAULT VENDORID_IPSEC_TOOLS + +#define VENDORID_IPSEC_TOOLS 0 /* * Refer to draft-ietf-ipsec-isakmp-gss-auth-06.txt. @@ -80,6 +83,14 @@ /* 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; diff --git a/crypto/dist/ipsec-tools/src/racoon/vmbuf.c b/crypto/dist/ipsec-tools/src/racoon/vmbuf.c index 244325073e4d9..6f95a065ab286 100644 --- a/crypto/dist/ipsec-tools/src/racoon/vmbuf.c +++ b/crypto/dist/ipsec-tools/src/racoon/vmbuf.c @@ -1,4 +1,4 @@ -/* $NetBSD: vmbuf.c,v 1.1.1.2 2005/02/23 14:54:28 manu Exp $ */ +/* $NetBSD: vmbuf.c,v 1.1.1.3 2006/09/09 16:12:23 manu Exp $ */ /* $KAME: vmbuf.c,v 1.11 2001/11/26 16:54:29 sakane Exp $ */ @@ -46,6 +46,7 @@ #include "misc.h" #include "vmbuf.h" #include "debug.h" +#include "plog.h" #include "gcmalloc.h" vchar_t * @@ -122,6 +123,11 @@ vdup(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; diff --git a/crypto/dist/ipsec-tools/src/racoon/vmbuf.h b/crypto/dist/ipsec-tools/src/racoon/vmbuf.h index f8a75445bd1b4..030909659ccd5 100644 --- a/crypto/dist/ipsec-tools/src/racoon/vmbuf.h +++ b/crypto/dist/ipsec-tools/src/racoon/vmbuf.h @@ -1,6 +1,6 @@ -/* $NetBSD: vmbuf.h,v 1.1.1.2 2005/02/23 14:54:28 manu Exp $ */ +/* $NetBSD: vmbuf.h,v 1.1.1.3 2006/09/09 16:12:23 manu Exp $ */ -/* Id: vmbuf.h,v 1.3 2004/06/11 16:00:17 ludvigm Exp */ +/* Id: vmbuf.h,v 1.4 2005/10/30 10:28:44 vanhu Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -60,6 +60,11 @@ do { \ } \ } 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 *)); diff --git a/crypto/dist/ipsec-tools/src/setkey/parse.y b/crypto/dist/ipsec-tools/src/setkey/parse.y index 5cb229a4af42b..79d2e7f390f56 100644 --- a/crypto/dist/ipsec-tools/src/setkey/parse.y +++ b/crypto/dist/ipsec-tools/src/setkey/parse.y @@ -1,4 +1,4 @@ -/* $NetBSD: parse.y,v 1.1.1.3 2005/08/07 08:49:28 manu Exp $ */ +/* $NetBSD: parse.y,v 1.1.1.4 2006/09/09 16:13:02 manu Exp $ */ /* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun Exp $ */ @@ -61,6 +61,10 @@ #include "vchar.h" #include "extern.h" +#ifndef IPPROTO_MH +#define IPPROTO_MH 135 +#endif + #define DEFAULT_NATT_PORT 4500 #ifndef UDP_ENCAP_ESPINUDP @@ -80,6 +84,15 @@ 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; @@ -126,6 +139,7 @@ static int setkeymsg_add __P((unsigned int, unsigned int, %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 @@ -180,7 +194,7 @@ add_command /* delete */ delete_command - : DELETE ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT + : DELETE ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT { int status; @@ -211,7 +225,7 @@ deleteall_command /* get command */ get_command - : GET ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT + : GET ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT { int status; @@ -535,12 +549,18 @@ extension | 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 - : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT + : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT { int status; struct addrinfo *src, *dst; @@ -551,7 +571,8 @@ spdadd_command /* fixed port fields if ulp is icmpv6 */ if ($10.buf != NULL) { - if ($9 != IPPROTO_ICMPV6) + if ( ($9 != IPPROTO_ICMPV6) && + ($9 != IPPROTO_MH)) return -1; free($5.buf); free($8.buf); @@ -572,7 +593,7 @@ spdadd_command return -1; } - status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11, + status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$12, src, $4, dst, $7); freeaddrinfo(src); freeaddrinfo(dst); @@ -591,14 +612,15 @@ spdadd_command ; spddelete_command - : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT + : 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 icmpv6 */ if ($10.buf != NULL) { - if ($9 != IPPROTO_ICMPV6) + if (($9 != IPPROTO_ICMPV6) && + ($9 != IPPROTO_MH)) return -1; free($5.buf); free($8.buf); @@ -619,7 +641,7 @@ spddelete_command return -1; } - status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11, + status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$12, src, $4, dst, $7); freeaddrinfo(src); freeaddrinfo(dst); @@ -709,7 +731,6 @@ ipandport } ; - prefix : /*NOTHING*/ { $$ = -1; } | SLASH DECSTRING { $$ = $2; } @@ -795,6 +816,16 @@ upper_misc_spec } ; +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 { @@ -942,7 +973,27 @@ setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) 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); @@ -1271,6 +1322,25 @@ setkeymsg_add(type, satype, srcs, dsts) 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; @@ -1516,6 +1586,8 @@ parse_init() 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; diff --git a/crypto/dist/ipsec-tools/src/setkey/setkey.8 b/crypto/dist/ipsec-tools/src/setkey/setkey.8 index 993272d1bf64f..b8618db5fd26b 100644 --- a/crypto/dist/ipsec-tools/src/setkey/setkey.8 +++ b/crypto/dist/ipsec-tools/src/setkey/setkey.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: setkey.8,v 1.1.1.4 2005/10/14 13:21:55 manu Exp $ +.\" $NetBSD: setkey.8,v 1.1.1.5 2006/09/09 16:13:04 manu Exp $ .\" .\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. .\" All rights reserved. @@ -97,9 +97,7 @@ If is also specified, the SPD entries are dumped. If .Fl p -is specified with -.FL P , -the ports that can be used for ESP over UDP are displayed. +is specified, the ports are displayed. .It Fl F Flush the SAD entries. If @@ -220,7 +218,7 @@ on the command line achieves the same functionality. .It Xo .Li spdadd .Op Fl 46n -.Ar src_range Ar dst_range Ar upperspec Ar policy +.Ar src_range Ar dst_range Ar upperspec Ar label Ar policy .Li ; .Xc Add an SPD entry. @@ -266,7 +264,8 @@ Meta-arguments are as follows: .It Ar src .It Ar dst Source/destination of the secure communication is specified as -an IPv4/v6 address. +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, @@ -369,6 +368,20 @@ 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 @@ -489,6 +502,27 @@ 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. It's 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: @@ -797,6 +831,14 @@ 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 diff --git a/crypto/dist/ipsec-tools/src/setkey/setkey.c b/crypto/dist/ipsec-tools/src/setkey/setkey.c index 36222e656e6f0..ab867d01e2204 100644 --- a/crypto/dist/ipsec-tools/src/setkey/setkey.c +++ b/crypto/dist/ipsec-tools/src/setkey/setkey.c @@ -1,4 +1,4 @@ -/* $NetBSD: setkey.c,v 1.1.1.3 2005/08/07 08:49:31 manu Exp $ */ +/* $NetBSD: setkey.c,v 1.1.1.4 2006/09/09 16:13:02 manu Exp $ */ /* $KAME: setkey.c,v 1.36 2003/09/24 23:52:51 itojun Exp $ */ @@ -135,7 +135,7 @@ usage(int 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 [-Palv" RK_OPTS "] -D\n"); + printf(" setkey [-Palpv" RK_OPTS "] -D\n"); printf(" setkey [-Pv] -F\n"); printf(" setkey [-H] -x\n"); printf(" setkey [-V] [-h]\n"); @@ -570,7 +570,10 @@ postproc(msg, len) switch (msg->sadb_msg_type) { case SADB_GET: - pfkey_sadump(msg); + if (f_withports) + pfkey_sadump_withports(msg); + else + pfkey_sadump(msg); break; case SADB_DUMP: @@ -585,10 +588,15 @@ postproc(msg, len) break; } } - if (f_forever) + if (f_forever) { + /* TODO: f_withports */ shortdump(msg); - else - pfkey_sadump(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) { diff --git a/crypto/dist/ipsec-tools/src/setkey/token.l b/crypto/dist/ipsec-tools/src/setkey/token.l index 4e01a5c6de1da..d623e84baf882 100644 --- a/crypto/dist/ipsec-tools/src/setkey/token.l +++ b/crypto/dist/ipsec-tools/src/setkey/token.l @@ -1,4 +1,4 @@ -/* $NetBSD: token.l,v 1.1.1.3 2005/08/07 08:49:36 manu Exp $ */ +/* $NetBSD: token.l,v 1.1.1.4 2006/09/09 16:13:03 manu Exp $ */ /* $KAME: token.l,v 1.44 2003/10/21 07:20:58 itojun Exp $ */ @@ -56,7 +56,8 @@ #include #include "vchar.h" -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || \ +(defined(__APPLE__) && defined(__MACH__)) #include "parse.h" #else #include "y.tab.h" @@ -238,6 +239,7 @@ nocyclic-seq { return(NOCYCLICSEQ); } {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); }