summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES13
-rw-r--r--Makefile4
-rw-r--r--Makefile.inc9
-rw-r--r--Makefile.ver2
-rw-r--r--README52
-rw-r--r--doc/2.6.known-issues112
-rw-r--r--doc/README39
-rw-r--r--doc/draft-richardson-ipsec-opportunistic.txt2688
-rw-r--r--doc/draft-richardson-ipsec-rr.txt840
-rw-r--r--doc/draft-spencer-ipsec-ike-implementation.nr1203
-rw-r--r--doc/draft-spencer-ipsec-ike-implementation.txt1232
-rw-r--r--doc/examples182
-rw-r--r--doc/impl.notes127
-rw-r--r--doc/ipsec.conf.2_to_122
-rw-r--r--doc/kernel.notes173
-rw-r--r--doc/src/draft-richardson-ipsec-opportunistic.html2456
-rw-r--r--doc/src/draft-richardson-ipsec-opportunistic.xml2519
-rw-r--r--doc/src/draft-richardson-ipsec-rr.html659
-rw-r--r--doc/src/draft-richardson-ipsec-rr.xml560
-rw-r--r--doc/utils/cleanhtml.sed1
-rwxr-xr-xdoc/utils/cleanhtml.sh12
-rw-r--r--doc/utils/contents.awk109
-rw-r--r--doc/utils/four2perm.120
-rw-r--r--doc/utils/four2perm.c140
-rw-r--r--doc/utils/html2four.126
-rw-r--r--doc/utils/html2four.c298
-rw-r--r--doc/utils/html2txt.sed86
-rw-r--r--doc/utils/killtoodeepcontents.pl59
-rwxr-xr-xdoc/utils/man2html.script48
-rw-r--r--doc/utils/man_xref.c125
-rwxr-xr-xdoc/utils/mkhtmlman44
-rw-r--r--doc/utils/perm1.awk1
-rw-r--r--doc/utils/perm2.awk46
-rw-r--r--doc/utils/rfc_pg.c76
-rw-r--r--doc/utils/xref.sed56
-rw-r--r--programs/pluto/Makefile18
-rw-r--r--programs/pluto/connections.c41
-rw-r--r--programs/pluto/constants.c91
-rw-r--r--programs/pluto/constants.h90
-rw-r--r--programs/pluto/defs.h4
-rw-r--r--programs/pluto/demux.c168
-rw-r--r--programs/pluto/demux.h4
-rw-r--r--programs/pluto/ike_alg.c33
-rw-r--r--programs/pluto/ipsec_doi.c137
-rw-r--r--programs/pluto/keys.c162
-rw-r--r--programs/pluto/keys.h10
-rw-r--r--programs/pluto/modecfg.c509
-rw-r--r--programs/pluto/modecfg.h31
-rw-r--r--programs/pluto/plutomain.c5
-rw-r--r--programs/pluto/spdb.c299
-rw-r--r--programs/pluto/spdb.h13
-rw-r--r--programs/pluto/state.h10
-rw-r--r--programs/pluto/vendor.c18
-rw-r--r--programs/pluto/vendor.h78
-rw-r--r--programs/pluto/xauth.c77
-rw-r--r--programs/pluto/xauth.h41
-rw-r--r--programs/starter/args.c3
-rw-r--r--programs/starter/confread.c13
-rw-r--r--programs/starter/keywords.c14
-rw-r--r--programs/starter/keywords.h5
-rw-r--r--programs/starter/keywords.txt3
-rw-r--r--programs/starter/lex.yy.c6
-rw-r--r--programs/starter/parser.tab.c836
-rw-r--r--programs/starter/parser.tab.h36
-rw-r--r--testing/INSTALL6
-rwxr-xr-xtesting/scripts/kstart-umls18
-rwxr-xr-xtesting/scripts/start-umls7
-rwxr-xr-xtesting/scripts/xstart-umls18
-rwxr-xr-xtesting/testing.conf6
-rw-r--r--testing/tests/crl-ldap/pretest.dat2
-rw-r--r--testing/tests/xauth-psk-mode-config/description.txt11
-rw-r--r--testing/tests/xauth-psk-mode-config/evaltest.dat18
-rw-r--r--testing/tests/xauth-psk-mode-config/hosts/carol/etc/ipsec.conf24
-rw-r--r--testing/tests/xauth-psk-mode-config/hosts/carol/etc/ipsec.secrets5
-rw-r--r--testing/tests/xauth-psk-mode-config/hosts/dave/etc/ipsec.conf24
-rw-r--r--testing/tests/xauth-psk-mode-config/hosts/dave/etc/ipsec.secrets5
-rw-r--r--testing/tests/xauth-psk-mode-config/hosts/moon/etc/ipsec.conf29
-rw-r--r--testing/tests/xauth-psk-mode-config/hosts/moon/etc/ipsec.secrets7
-rw-r--r--testing/tests/xauth-psk-mode-config/posttest.dat9
-rw-r--r--testing/tests/xauth-psk-mode-config/pretest.dat12
-rw-r--r--testing/tests/xauth-psk-mode-config/test.conf21
-rw-r--r--testing/tests/xauth-psk/description.txt9
-rw-r--r--testing/tests/xauth-psk/evaltest.dat12
-rw-r--r--testing/tests/xauth-psk/hosts/carol/etc/ipsec.conf21
-rw-r--r--testing/tests/xauth-psk/hosts/carol/etc/ipsec.secrets5
-rw-r--r--testing/tests/xauth-psk/hosts/dave/etc/ipsec.conf21
-rw-r--r--testing/tests/xauth-psk/hosts/dave/etc/ipsec.secrets5
-rw-r--r--testing/tests/xauth-psk/hosts/moon/etc/ipsec.conf22
-rw-r--r--testing/tests/xauth-psk/hosts/moon/etc/ipsec.secrets7
-rw-r--r--testing/tests/xauth-psk/posttest.dat9
-rw-r--r--testing/tests/xauth-psk/pretest.dat12
-rw-r--r--testing/tests/xauth-psk/test.conf21
-rw-r--r--testing/tests/xauth-rsa-fail/description.txt5
-rw-r--r--testing/tests/xauth-rsa-fail/evaltest.dat4
-rwxr-xr-xtesting/tests/xauth-rsa-fail/hosts/carol/etc/ipsec.conf24
-rw-r--r--testing/tests/xauth-rsa-fail/hosts/carol/etc/ipsec.secrets5
-rwxr-xr-xtesting/tests/xauth-rsa-fail/hosts/moon/etc/ipsec.conf24
-rw-r--r--testing/tests/xauth-rsa-fail/hosts/moon/etc/ipsec.secrets5
-rw-r--r--testing/tests/xauth-rsa-fail/posttest.dat2
-rw-r--r--testing/tests/xauth-rsa-fail/pretest.dat4
-rw-r--r--testing/tests/xauth-rsa-fail/test.conf21
-rw-r--r--testing/tests/xauth-rsa-mode-config/description.txt11
-rw-r--r--testing/tests/xauth-rsa-mode-config/evaltest.dat18
-rw-r--r--testing/tests/xauth-rsa-mode-config/hosts/carol/etc/ipsec.conf25
-rw-r--r--testing/tests/xauth-rsa-mode-config/hosts/carol/etc/ipsec.secrets5
-rw-r--r--testing/tests/xauth-rsa-mode-config/hosts/dave/etc/ipsec.conf25
-rw-r--r--testing/tests/xauth-rsa-mode-config/hosts/dave/etc/ipsec.secrets5
-rw-r--r--testing/tests/xauth-rsa-mode-config/hosts/moon/etc/ipsec.conf30
-rw-r--r--testing/tests/xauth-rsa-mode-config/hosts/moon/etc/ipsec.secrets7
-rw-r--r--testing/tests/xauth-rsa-mode-config/posttest.dat9
-rw-r--r--testing/tests/xauth-rsa-mode-config/pretest.dat9
-rw-r--r--testing/tests/xauth-rsa-mode-config/test.conf21
-rw-r--r--testing/tests/xauth-rsa-nosecret/description.txt6
-rw-r--r--testing/tests/xauth-rsa-nosecret/evaltest.dat4
-rwxr-xr-xtesting/tests/xauth-rsa-nosecret/hosts/carol/etc/ipsec.conf24
-rw-r--r--testing/tests/xauth-rsa-nosecret/hosts/carol/etc/ipsec.secrets3
-rwxr-xr-xtesting/tests/xauth-rsa-nosecret/hosts/moon/etc/ipsec.conf24
-rw-r--r--testing/tests/xauth-rsa-nosecret/hosts/moon/etc/ipsec.secrets5
-rw-r--r--testing/tests/xauth-rsa-nosecret/posttest.dat2
-rw-r--r--testing/tests/xauth-rsa-nosecret/pretest.dat4
-rw-r--r--testing/tests/xauth-rsa-nosecret/test.conf21
-rw-r--r--testing/tests/xauth-rsa/description.txt9
-rw-r--r--testing/tests/xauth-rsa/evaltest.dat12
-rw-r--r--testing/tests/xauth-rsa/hosts/carol/etc/ipsec.conf24
-rw-r--r--testing/tests/xauth-rsa/hosts/carol/etc/ipsec.secrets5
-rw-r--r--testing/tests/xauth-rsa/hosts/dave/etc/ipsec.conf24
-rw-r--r--testing/tests/xauth-rsa/hosts/dave/etc/ipsec.secrets5
-rw-r--r--testing/tests/xauth-rsa/hosts/moon/etc/ipsec.conf24
-rw-r--r--testing/tests/xauth-rsa/hosts/moon/etc/ipsec.secrets7
-rw-r--r--testing/tests/xauth-rsa/posttest.dat9
-rw-r--r--testing/tests/xauth-rsa/pretest.dat9
-rw-r--r--testing/tests/xauth-rsa/test.conf21
132 files changed, 14975 insertions, 2686 deletions
diff --git a/CHANGES b/CHANGES
index 38ed3f184..5398c0959 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,16 @@
+strongswan-2.8.1
+----------------
+
+- Support for extended authentication (XAUTH) in combination
+ with ISAKMP Main Mode RSA or PSK authentication. Both client and
+ server side were implemented. Handling of user credentials can
+ be done by a run-time loadable XAUTH module. By default user
+ credentials are stored in ipsec.secrets.
+
+- Mixed PSK/RSA authentication is now possible between two hosts
+ with static IP addresses.
+
+
strongswan-2.8.0
----------------
diff --git a/Makefile b/Makefile
index d77302267..9027df9fe 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
-# RCSID $Id: Makefile,v 1.5 2006/08/28 11:12:36 as Exp $
+# RCSID $Id: Makefile,v 1.6 2006/11/22 05:47:11 as Exp $
FREESWANSRCDIR=$(shell pwd)
@@ -42,7 +42,7 @@ KVSHORTUTIL=${MAKEUTILS}/kernelversion-short
KERNELREL=$(shell ${KVSHORTUTIL} ${KERNELSRC}/Makefile)
# directories visited by all recursion
-SUBDIRS=doc lib programs linux
+SUBDIRS=lib programs linux
# declaration for make's benefit
.PHONY: def insert kpatch klink klibcryptolink patches _patches _patches2.2 _patches2.4 \
diff --git a/Makefile.inc b/Makefile.inc
index f5ec6741d..8abbbf55c 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -11,7 +11,7 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
-# RCSID $Id: Makefile.inc,v 1.12 2006/01/25 17:23:15 as Exp $
+# RCSID $Id: Makefile.inc,v 1.13 2007/01/11 21:42:11 as Exp $
# Variables in this file with names starting with INC_ are not for use
@@ -261,8 +261,8 @@ USE_KERNEL26?=true
# whether or not pluto sends its strongSwan Vendor ID
USE_VENDORID?=true
-# whether or not pluto sends an XAUTH VID (Cisco Mode Config Interoperability)
-USE_XAUTH_VID?=false
+# whether to tolerate some non-conformities (interoperability with Cisco VPN client)
+USE_CISCO_QUIRKS?=false
# whether to support NAT Traversal (aka NAT-T)
USE_NAT_TRAVERSAL?=true
@@ -292,6 +292,9 @@ PKCS11_DEFAULT_LIB=\"/usr/lib/pkcs11/opensc-pkcs11.so\"
# Uncomment and complete this line if using another default library
#PKCS11_DEFAULT_LIB=\"/usr/lib/...\"
+# Uncomment if you want to specify a path to an XAUTH library module
+#XAUTH_DEFAULT_LIB=
+
# Enable the leak detective to find memory leaks
USE_LEAK_DETECTIVE?=false
diff --git a/Makefile.ver b/Makefile.ver
index c13d3a0da..07b052019 100644
--- a/Makefile.ver
+++ b/Makefile.ver
@@ -1 +1 @@
-IPSECVERSION=2.8.0
+IPSECVERSION=2.8.1
diff --git a/README b/README
index c0480b069..9750e63c5 100644
--- a/README
+++ b/README
@@ -57,7 +57,7 @@ Contents
10. Monitoring functions
11. Firewall support functions
11.1 Environment variables in the updown script
- 11.2 Automatic insertion and deletion of iptables firewall rules (NEW)
+ 11.2 Automatic insertion and deletion of iptables firewall rules
11.3 Sample Linux 2.6 _updown_espmark script for iptables < 1.3.5
12. Authentication with raw RSA public keys
13. Authentication with OpenPGP certificates
@@ -71,6 +71,7 @@ Contents
14.3 Dead peer detection
14.4 IKE Mode Config Pull Mode
14.5 IKE Mode Config Push Mode
+ 14.6 XAUTH - Extended Authentication (NEW)
15. Copyright statement and acknowledgements
@@ -105,7 +106,10 @@ and currently supports the following features:
* NAT-Traversal (RFC 3947)
- * Support of Virtual IPs via static configuratin and IKE Mode Config
+ * Support of Virtual IPs via static configuration and IKE Mode Config
+
+ * XAUTH client and server functionality in conjunction with either PSK
+ or RSA IKE Main Mode authentication.
* Support of Delete SA and informational Notification messages.
@@ -3026,6 +3030,44 @@ as part of the connection definition in ipsec.conf. The default value is
modeconfig=pull.
+14.6 XAUTH - Extended Authentication
+ -------------------------------
+
+The XAUTH protocol <draft-beaulieu-ike-xauth-02.txt> allows an extended
+client authentication using e.g. a username/password paradigm in addition
+to the IKE Main Mode authentication. Thus XAUTH can be used in conjunction
+with Pre-Shared Keys (PSK) by defining
+
+ authby=xauthpsk
+
+or with RSA signatures
+
+ authby=xauthrsasig
+
+in the connection definition, correspondingly. strongSwan can act either as
+an XAUTH client with
+
+ xauth=client
+
+or as an XAUTH server with
+
+ xauth=server
+
+with xauth=client being the default value. strongSwan integrates a default
+implementation where the XAUTH user credentials are stored on both the
+server and the client in the /etc/ipsec.secrets file, using the syntax
+
+ : XAUTH john "rT6q!V2p"
+
+The client must not have more than one XAUTH entry whereas the server can
+contain an unlimited number of user credentials in ipsec.secrets.
+
+Either the prompting on the client side or the verification of the user
+credentials on the server side can be implemented as a customized XAUTH
+dynamic library module. The corresponding library interface is defined
+by the pluto/xauth.h header file.
+
+
15. Copyright statement and acknowledgements
----------------------------------------
@@ -3059,7 +3101,7 @@ modeconfig=pull.
Copyright (c) 2002, Stephane Laroche
- IKE Mode Config protocol:
+ IKE Mode Config and XAUTH protocol:
Copyright (c) 2001-2002, Colubris Networks
@@ -3090,7 +3132,7 @@ modeconfig=pull.
scepclient:
Copyright (c) 2005, Jan Hutter, Martin Willi
- Copyright (c) 2005-2006, Andreas Steffen
+ Copyright (c) 2005-2007, Andreas Steffen
University of Applied Sciences in Rapperswil, Switzerland
@@ -3105,5 +3147,5 @@ modeconfig=pull.
for more details.
-----------------------------------------------------------------------------
-This file is RCSID $Id: README,v 1.36 2006/10/20 15:43:51 as Exp $
+This file is RCSID $Id: README,v 1.38 2007/01/14 18:16:51 as Exp $
diff --git a/doc/2.6.known-issues b/doc/2.6.known-issues
deleted file mode 100644
index 397c4f957..000000000
--- a/doc/2.6.known-issues
+++ /dev/null
@@ -1,112 +0,0 @@
-Known issues with FreeS/WAN on a 2.6 kernel Claudia Schmeing
--------------------------------------------
-
-
-This is an overview of known issues with FreeS/WAN on the 2.6 kernel codebase
-(also 2.5.x), which includes native Linux IPsec code.
-
-More information on the native IPsec code is available here:
-
- http://lartc.org/howto/lartc.ipsec.html
-
-Tools for use with that code are here:
-
- http://ipsec-tools.sourceforge.net/
-
-
-* As of FreeS/WAN 2.03, FreeS/WAN ships with some support for the 2.6 kernel
- IPsec code. In 2.03, this support is preliminary, but we expect to develop
- it fully. Many thanks to Herbert Xu for the initial code patches.
-
-* Use the most recent Linux FreeS/WAN 2.x release from ftp.xs4all.nl
- to try our 2.6 kernel support.
-
-* The installation procedure for use with 2.6 kernel IPsec is a little
- different from a traditional FreeS/WAN installation. Please see
- the latest doc/install.html.
-
-* Please see the design and users' mailing lists
- (http://www.freeswan.org/mail.html) for more detail and the latest reports.
-
-
-
-DESIGN-RELATED ISSUES
-
-
-* In 2.6, IPsec policies are detached from routing decisions. Because of this
- design, Opportunistic Encryption on the local LAN will be possible with 2.6.
-
- One side effect: When contacting a node on the local LAN which is protected
- by gateway OE, you will get asymmetrical routing (one way through the gateway,
- one way direct), and IPsec will drop the return packets.
-
-
-
-CURRENT ISSUES
-
-
-* For the moment, users wishing to test FreeS/WAN with 2.6 will require
- ipsec-tools' "setkey" program. Though FreeS/WAN's keying daemon, Pluto,
- directly sets IPsec policy, setkey is currently required to reset kernel SPD
- (Security Policy Database) states when Pluto restarts. We will likely add
- this basic functionality to an upcoming FreeS/WAN release.
-
-* State information is not available to the user, eg. ipsec
- eroute/ipsec spi/ipsec look do not work. The exception: ipsec auto --status
- This will be fixed in a future release.
-
-* If you're running Opportunistic Encryption, connectivity to new hosts will
- immediately fail. You may receive a message similar to this:
-
- connect: Resource temporarily unavailable
-
- The reason for this lies in the kernel code. Fairly complex discussion:
-
- http://lists.freeswan.org/archives/design/2003-September/msg00073.html
-
- As of 2.6.0-test6, this has not been fixed.
-
-* This initial connectivity failure has an unintended side effect on DNS queries.
- This will result in a rekey failure for OE connections; a %pass will be
- installed for your destination IP before a %pass is re-instituted to your
- DNS server. As a workaround, please add your DNS servers to
- /etc/ipsec.d/policies/clear.
-
-* Packets on all interfaces are considered for OE, including loopback. If you're
- running a local nameserver, you'll still need to exempt localhost DNS traffic
- as per the previous point. Since this traffic has a source of 127.0.0.1/32,
- the "clear" policy group will not suffice; you'll need to add the following
- %passthrough conn to ipsec.conf:
-
- conn exclude-lo
- authby=never
- left=127.0.0.1
- leftsubnet=127.0.0.0/8
- right=127.0.0.2
- rightsubnet=127.0.0.0/8
- type=passthrough
- auto=route
-
-
-
-OLD ISSUES
-
-
-None, yet.
-
-
-
-RELATED DOCUMENTS
-
-
-FreeS/WAN Install web page doc/install.html
-
-FreeS/WAN Install guide INSTALL
-
-FreeS/WAN mailing list posts, including:
-
- http://lists.freeswan.org/archives/design/2003-September/msg00057.html
-
-To sign up for our mailing lists, see http://www.freeswan.org/mail.html
-
-
diff --git a/doc/README b/doc/README
deleted file mode 100644
index ff5564e4e..000000000
--- a/doc/README
+++ /dev/null
@@ -1,39 +0,0 @@
-This directory has the HTML FreeS/WAN documentation.
-
-Start from either of:
-
- toc.html table of contents for HTML docs
- index.html pointers to everything, including
- text files not in HTML docs
-
-The Makefile in this directory can generate various
-things from the HTML source:
-
- ./*.html individual HTML files
- with previous/contents/next links
- toc.html table of contents
- HowTo.html one big HTML file
- HowTo.ps Postscript
- HowTo.pdf PDF
- HowTo.txt ASCII text
-
-Not all of the above are in the shipped version. All but
-text are on our website, www.freeswan.org. To get PDF or
-Postscript, either grab them from the web or install
-htmldoc from www.easysw.com, then use the Makefile.
-
-Subdirectories are:
- src/*.html HTML source files
- manpage.d/*.html HTML versions of man pages
-
-You should not need to look at these, except for following
-links to HTML man pages.
-
-The Internet Drafts are natively in XML format. They have been
-converted with Marshall Rose's xml2rfc.
-
-xml2rfc is available at xml.resource.org.
-You may have to install the TclXML package by symlinking it into
-/usr/lib/tcl8.3 or some such.
-
-
diff --git a/doc/draft-richardson-ipsec-opportunistic.txt b/doc/draft-richardson-ipsec-opportunistic.txt
new file mode 100644
index 000000000..4c87d857a
--- /dev/null
+++ b/doc/draft-richardson-ipsec-opportunistic.txt
@@ -0,0 +1,2688 @@
+
+
+Independent submission M. Richardson
+Internet-Draft SSW
+Expires: November 19, 2003 D. Redelmeier
+ Mimosa
+ May 21, 2003
+
+
+ Opportunistic Encryption using The Internet Key Exchange (IKE)
+ draft-richardson-ipsec-opportunistic-11.txt
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of RFC2026.
+
+ Internet-Drafts are working documents of the Internet Engineering
+ Task Force (IETF), its areas, and its working groups. Note that
+ other groups may also distribute working documents as Internet-
+ Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress."
+
+ The list of current Internet-Drafts can be accessed at http://
+ www.ietf.org/ietf/1id-abstracts.txt.
+
+ The list of Internet-Draft Shadow Directories can be accessed at
+ http://www.ietf.org/shadow.html.
+
+ This Internet-Draft will expire on November 19, 2003.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+Abstract
+
+ This document describes opportunistic encryption (OE) using the
+ Internet Key Exchange (IKE) and IPsec. Each system administrator
+ adds new resource records to his or her Domain Name System (DNS) to
+ support opportunistic encryption. The objective is to allow
+ encryption for secure communication without any pre-arrangement
+ specific to the pair of systems involved.
+
+ DNS is used to distribute the public keys of each system involved.
+ This is resistant to passive attacks. The use of DNS Security
+ (DNSSEC) secures this system against active attackers as well.
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 1]
+
+Internet-Draft opportunistic May 2003
+
+
+ As a result, the administrative overhead is reduced from the square
+ of the number of systems to a linear dependence, and it becomes
+ possible to make secure communication the default even when the
+ partner is not known in advance.
+
+ This document is offered up as an Informational RFC.
+
+Table of Contents
+
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 2. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
+ 3. Specification . . . . . . . . . . . . . . . . . . . . . . . . 10
+ 4. Impacts on IKE . . . . . . . . . . . . . . . . . . . . . . . . 21
+ 5. DNS issues . . . . . . . . . . . . . . . . . . . . . . . . . . 24
+ 6. Network address translation interaction . . . . . . . . . . . 28
+ 7. Host implementations . . . . . . . . . . . . . . . . . . . . . 29
+ 8. Multi-homing . . . . . . . . . . . . . . . . . . . . . . . . . 30
+ 9. Failure modes . . . . . . . . . . . . . . . . . . . . . . . . 32
+ 10. Unresolved issues . . . . . . . . . . . . . . . . . . . . . . 34
+ 11. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
+ 12. Security considerations . . . . . . . . . . . . . . . . . . . 42
+ 13. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 44
+ 14. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 45
+ Normative references . . . . . . . . . . . . . . . . . . . . . 46
+ Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 47
+ Full Copyright Statement . . . . . . . . . . . . . . . . . . . 48
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 2]
+
+Internet-Draft opportunistic May 2003
+
+
+1. Introduction
+
+1.1 Motivation
+
+ The objective of opportunistic encryption is to allow encryption
+ without any pre-arrangement specific to the pair of systems involved.
+ Each system administrator adds public key information to DNS records
+ to support opportunistic encryption and then enables this feature in
+ the nodes' IPsec stack. Once this is done, any two such nodes can
+ communicate securely.
+
+ This document describes opportunistic encryption as designed and
+ mostly implemented by the Linux FreeS/WAN project. For project
+ information, see http://www.freeswan.org.
+
+ The Internet Architecture Board (IAB) and Internet Engineering
+ Steering Group (IESG) have taken a strong stand that the Internet
+ should use powerful encryption to provide security and privacy [4].
+ The Linux FreeS/WAN project attempts to provide a practical means to
+ implement this policy.
+
+ The project uses the IPsec, ISAKMP/IKE, DNS and DNSSEC protocols
+ because they are standardized, widely available and can often be
+ deployed very easily without changing hardware or software or
+ retraining users.
+
+ The extensions to support opportunistic encryption are simple. No
+ changes to any on-the-wire formats are needed. The only changes are
+ to the policy decision making system. This means that opportunistic
+ encryption can be implemented with very minimal changes to an
+ existing IPsec implementation.
+
+ Opportunistic encryption creates a "fax effect". The proliferation
+ of the fax machine was possible because it did not require that
+ everyone buy one overnight. Instead, as each person installed one,
+ the value of having one increased - as there were more people that
+ could receive faxes. Once opportunistic encryption is installed it
+ automatically recognizes other boxes using opportunistic encryption,
+ without any further configuration by the network administrator. So,
+ as opportunistic encryption software is installed on more boxes, its
+ value as a tool increases.
+
+ This document describes the infrastructure to permit deployment of
+ Opportunistic Encryption.
+
+ The term S/WAN is a trademark of RSA Data Systems, and is used with
+ permission by this project.
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 3]
+
+Internet-Draft opportunistic May 2003
+
+
+1.2 Types of network traffic
+
+ To aid in understanding the relationship between security processing
+ and IPsec we divide network traffic into four categories:
+
+ * Deny: networks to which traffic is always forbidden.
+
+ * Permit: networks to which traffic in the clear is permitted.
+
+ * Opportunistic tunnel: networks to which traffic is encrypted if
+ possible, but otherwise is in the clear or fails depending on the
+ default policy in place.
+
+ * Configured tunnel: networks to which traffic must be encrypted, and
+ traffic in the clear is never permitted.
+
+ Traditional firewall devices handle the first two categories. No
+ authentication is required. The permit policy is currently the
+ default on the Internet.
+
+ This document describes the third category - opportunistic tunnel,
+ which is proposed as the new default for the Internet.
+
+ Category four, encrypt traffic or drop it, requires authentication of
+ the end points. As the number of end points is typically bounded and
+ is typically under a single authority, arranging for distribution of
+ authentication material, while difficult, does not require any new
+ technology. The mechanism described here provides an additional way
+ to distribute the authentication materials, that of a public key
+ method that does not require deployment of an X.509 based
+ infrastructure.
+
+ Current Virtual Private Networks can often be replaced by an "OE
+ paranoid" policy as described herein.
+
+1.3 Peer authentication in opportunistic encryption
+
+ Opportunistic encryption creates tunnels between nodes that are
+ essentially strangers. This is done without any prior bilateral
+ arrangement. There is, therefore, the difficult question of how one
+ knows to whom one is talking.
+
+ One possible answer is that since no useful authentication can be
+ done, none should be tried. This mode of operation is named
+ "anonymous encryption". An active man-in-the-middle attack can be
+ used to thwart the privacy of this type of communication. Without
+ peer authentication, there is no way to prevent this kind of attack.
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 4]
+
+Internet-Draft opportunistic May 2003
+
+
+ Although a useful mode, anonymous encryption is not the goal of this
+ project. Simpler methods are available that can achieve anonymous
+ encryption only, but authentication of the peer is a desireable goal.
+ The latter is achieved through key distribution in DNS, leveraging
+ upon the authentication of the DNS in DNSSEC.
+
+ Peers are, therefore, authenticated with DNSSEC when available.
+ Local policy determines how much trust to extend when DNSSEC is not
+ available.
+
+ However, an essential premise of building private connections with
+ strangers is that datagrams received through opportunistic tunnels
+ are no more special than datagrams that arrive in the clear. Unlike
+ in a VPN, these datagrams should not be given any special exceptions
+ when it comes to auditing, further authentication or firewalling.
+
+ When initiating outbound opportunistic encryption, local
+ configuration determines what happens if tunnel setup fails. It may
+ be that the packet goes out in the clear, or it may be dropped.
+
+1.4 Use of RFC2119 terms
+
+ 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 [5]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 5]
+
+Internet-Draft opportunistic May 2003
+
+
+2. Overview
+
+2.1 Reference diagram
+
+ ---------------------------------------------------------------------
+
+ The following network diagram is used in the rest of this document as
+ the canonical diagram:
+
+ [Q] [R]
+ . . AS2
+ [A]----+----[SG-A].......+....+.......[SG-B]-------[B]
+ | ......
+ AS1 | ..PI..
+ | ......
+ [D]----+----[SG-D].......+....+.......[C] AS3
+
+
+
+ Figure 1: Reference Network Diagram
+
+ ---------------------------------------------------------------------
+
+ In this diagram, there are four end-nodes: A, B, C and D. There are
+ three gateways, SG-A, SG-B, SG-D. A, D, SG-A and SG-D are part of
+ the same administrative authority, AS1. SG-A and SG-D are on two
+ different exit paths from organization 1. SG-B/B is an independent
+ organization, AS2. Nodes Q and R are nodes on the Internet. PI is
+ the Public Internet ("The Wild").
+
+2.2 Terminology
+
+ The following terminology is used in this document:
+
+ Security gateway: a system that performs IPsec tunnel mode
+ encapsulation/decapsulation. [SG-x] in the diagram.
+
+ Alice: node [A] in the diagram. When an IP address is needed, this
+ is 192.1.0.65.
+
+ Bob: node [B] in the diagram. When an IP address is needed, this is
+ 192.2.0.66.
+
+ Carol: node [C] in the diagram. When an IP address is needed, this
+ is 192.1.1.67.
+
+ Dave: node [D] in the diagram. When an IP address is needed, this is
+ 192.3.0.68.
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 6]
+
+Internet-Draft opportunistic May 2003
+
+
+ SG-A: Alice's security gateway. Internally it is 192.1.0.1,
+ externally it is 192.1.1.4.
+
+ SG-B: Bob's security gateway. Internally it is 192.2.0.1, externally
+ it is 192.1.1.5.
+
+ SG-D: Dave's security gateway. Also Alice's backup security gateway.
+ Internally it is 192.3.0.1, externally it is 192.1.1.6.
+
+ - A single dash represents clear-text datagrams.
+
+ = An equals sign represents phase 2 (IPsec) cipher-text datagrams.
+
+ ~ A single tilde represents clear-text phase 1 datagrams.
+
+ # A hash sign represents phase 1 (IKE) cipher-text datagrams.
+
+ . A period represents an untrusted network of unknown type.
+
+ Configured tunnel: a tunnel that is directly and deliberately hand
+ configured on participating gateways. Configured tunnels are
+ typically given a higher level of trust than opportunistic
+ tunnels.
+
+ Road warrior tunnel: a configured tunnel connecting one node with a
+ fixed IP address and one node with a variable IP address. A road
+ warrior (RW) connection must be initiated by the variable node,
+ since the fixed node cannot know the current address for the road
+ warrior.
+
+ Anonymous encryption: the process of encrypting a session without any
+ knowledge of who the other parties are. No authentication of
+ identities is done.
+
+ Opportunistic encryption: the process of encrypting a session with
+ authenticated knowledge of who the other parties are.
+
+ Lifetime: the period in seconds (bytes or datagrams) for which a
+ security association will remain alive before needing to be re-
+ keyed.
+
+ Lifespan: the effective time for which a security association remains
+ useful. A security association with a lifespan shorter than its
+ lifetime would be removed when no longer needed. A security
+ association with a lifespan longer than its lifetime would need to
+ be re-keyed one or more times.
+
+ Phase 1 SA: an ISAKMP/IKE security association sometimes referred to
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 7]
+
+Internet-Draft opportunistic May 2003
+
+
+ as a keying channel.
+
+ Phase 2 SA: an IPsec security association.
+
+ Tunnel: another term for a set of phase 2 SA (one in each direction).
+
+ NAT: Network Address Translation (see [20]).
+
+ NAPT: Network Address and Port Translation (see [20]).
+
+ AS: an autonomous system (AS) is a group of systems (a network) that
+ are under the administrative control of a single organization.
+
+ Default-free zone: a set of routers that maintain a complete set of
+ routes to all currently reachable destinations. Having such a
+ list, these routers never make use of a default route. A datagram
+ with a destination address not matching any route will be dropped
+ by such a router.
+
+
+2.3 Model of operation
+
+ The opportunistic encryption security gateway (OE gateway) is a
+ regular gateway node as described in [2] section 2.4 and [3] with the
+ additional capabilities described here and in [7]. The algorithm
+ described here provides a way to determine, for each datagram,
+ whether or not to encrypt and tunnel the datagram. Two important
+ things that must be determined are whether or not to encrypt and
+ tunnel and, if so, the destination address or name of the tunnel end
+ point which should be used.
+
+2.3.1 Tunnel authorization
+
+ The OE gateway determines whether or not to create a tunnel based on
+ the destination address of each packet. Upon receiving a packet with
+ a destination address not recently seen, the OE gateway performs a
+ lookup in DNS for an authorization resource record (see Section 5.2).
+ The record is located using the IP address to perform a search in the
+ in-addr.arpa (IPv4) or ip6.arpa (IPv6) maps. If an authorization
+ record is found, the OE gateway interprets this as a request for a
+ tunnel to be formed.
+
+2.3.2 Tunnel end-point discovery
+
+ The authorization resource record also provides the address or name
+ of the tunnel end point which should be used.
+
+ The record may also provide the public RSA key of the tunnel end
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 8]
+
+Internet-Draft opportunistic May 2003
+
+
+ point itself. This is provided for efficiency only. If the public
+ RSA key is not present, the OE gateway performs a second lookup to
+ find a KEY resource record for the end point address or name.
+
+ Origin and integrity protection of the resource records is provided
+ by DNSSEC ([16]). Section 3.2.4.1 documents an optional restriction
+ on the tunnel end point if DNSSEC signatures are not available for
+ the relevant records.
+
+2.3.3 Caching of authorization results
+
+ The OE gateway maintains a cache, in the forwarding plane, of source/
+ destination pairs for which opportunistic encryption has been
+ attempted. This cache maintains a record of whether or not OE was
+ successful so that subsequent datagrams can be forwarded properly
+ without additional delay.
+
+ Successful negotiation of OE instantiates a new security association.
+ Failure to negotiate OE results in creation of a forwarding policy
+ entry either to drop or transmit in the clear future datagrams. This
+ negative cache is necessary to avoid the possibly lengthy process of
+ repeatedly looking up the same information.
+
+ The cache is timed out periodically, as described in Section 3.4.
+ This removes entries that are no longer being used and permits the
+ discovery of changes in authorization policy.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 9]
+
+Internet-Draft opportunistic May 2003
+
+
+3. Specification
+
+ The OE gateway is modeled to have a forwarding plane and a control
+ plane. A control channel, such as PF_KEY, connects the two planes.
+ (See [6].) The forwarding plane performs per datagram operations.
+ The control plane contains a keying daemon, such as ISAKMP/IKE, and
+ performs all authorization, peer authentication and key derivation
+ functions.
+
+3.1 Datagram state machine
+
+ Let the OE gateway maintain a collection of objects -- a superset of
+ the security policy database (SPD) specified in [7]. For each
+ combination of source and destination address, an SPD object exists
+ in one of five following states. Prior to forwarding each datagram,
+ the responder uses the source and destination addresses to pick an
+ entry from the SPD. The SPD then determines if and how the packet is
+ forwarded.
+
+3.1.1 Non-existent policy
+
+ If the responder does not find an entry, then this policy applies.
+ The responder creates an entry with an initial state of "hold policy"
+ and requests keying material from the keying daemon. The responder
+ does not forward the datagram, rather it attaches the datagram to the
+ SPD entry as the "first" datagram and retains it for eventual
+ transmission in a new state.
+
+3.1.2 Hold policy
+
+ The responder requests keying material. If the interface to the
+ keying system is lossy (PF_KEY, for instance, can be), the
+ implementation SHOULD include a mechanism to retransmit the keying
+ request at a rate limited to less than 1 request per second. The
+ responder does not forward the datagram. It attaches the datagram to
+ the SPD entry as the "last" datagram where it is retained for
+ eventual transmission. If there is a datagram already so stored,
+ then that already stored datagram is discarded.
+
+ Because the "first" datagram is probably a TCP SYN packet, the
+ responder retains the "first" datagram in an attempt to avoid waiting
+ for a TCP retransmit. The responder retains the "last" datagram in
+ deference to streaming protocols that find it useful to know how much
+ data has been lost. These are recommendations to decrease latency.
+ There are no operational requirements for this.
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 10]
+
+Internet-Draft opportunistic May 2003
+
+
+3.1.3 Pass-through policy
+
+ The responder forwards the datagram using the normal forwarding
+ table. The responder enters this state only by command from the
+ keying daemon, and upon entering this state, also forwards the
+ "first" and "last" datagrams.
+
+3.1.4 Deny policy
+
+ The responder discards the datagram. The responder enters this state
+ only by command from the keying daemon, and upon entering this state,
+ discards the "first" and "last" datagrams. Local administration
+ decides if further datagrams cause ICMP messages to be generated
+ (i.e. ICMP Destination Unreachable, Communication Administratively
+ Prohibited. type=3, code=13).
+
+3.1.5 Encrypt policy
+
+ The responder encrypts the datagram using the indicated security
+ association database (SAD) entry. The responder enters this state
+ only by command from the keying daemon, and upon entering this state,
+ releases and forwards the "first" and "last" datagrams using the new
+ encrypt policy.
+
+ If the associated SAD entry expires because of byte, packet or time
+ limits, then the entry returns to the Hold policy, and an expire
+ message is sent to the keying daemon.
+
+ All states may be created directly by the keying daemon while acting
+ as a responder.
+
+3.2 Keying state machine - initiator
+
+ Let the keying daemon maintain a collection of objects. Let them be
+ called "connections" or "conn"s. There are two categories of
+ connection objects: classes and instances. A class represents an
+ abstract policy - what could be. An instance represents an actual
+ connection - what is implemented at the time.
+
+ Let there be two further subtypes of connections: keying channels
+ (Phase 1 SAs) and data channels (Phase 2 SAs). Each data channel
+ object may have a corresponding SPD and SAD entry maintained by the
+ datagram state machine.
+
+ For the purposes of opportunistic encryption, there MUST, at least,
+ be connection classes known as "deny", "always-clear-text", "OE-
+ permissive", and "OE-paranoid". The latter two connection classes
+ define a set of source and/or destination addresses for which
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 11]
+
+Internet-Draft opportunistic May 2003
+
+
+ opportunistic encryption will be attempted. The administrator MAY
+ set policy options in a number of additional places. An
+ implementation MAY create additional connection classes to further
+ refine these policies.
+
+ The simplest system may need only the "OE-permissive" connection, and
+ would list its own (single) IP address as the source address of this
+ policy and the wild-card address 0.0.0.0/0 as the destination IPv4
+ address. That is, the simplest policy is to try opportunistic
+ encryption with all destinations.
+
+ The distinction between permissive and paranoid OE use will become
+ clear in the state transition differences. In general a permissive
+ OE will, on failure, install a pass-through policy, while a paranoid
+ OE will, on failure, install a drop policy.
+
+ In this description of the keying machine's state transitions, the
+ states associated with the keying system itself are omitted because
+ they are best documented in the keying system ([8], [9] and [10] for
+ ISAKMP/IKE), and the details are keying system specific.
+ Opportunistic encryption is not dependent upon any specific keying
+ protocol, but this document does provide requirements for those using
+ ISAKMP/IKE to assure that implementations inter-operate.
+
+ The state transitions that may be involved in communicating with the
+ forwarding plane are omitted. PF_KEY and similar protocols have
+ their own set of states required for message sends and completion
+ notifications.
+
+ Finally, the retransmits and recursive lookups that are normal for
+ DNS are not included in this description of the state machine.
+
+3.2.1 Nonexistent connection
+
+ There is no connection instance for a given source/destination
+ address pair. Upon receipt of a request for keying material for this
+ source/destination pair, the initiator searches through the
+ connection classes to determine the most appropriate policy. Upon
+ determining an appropriate connection class, an instance object is
+ created of that type. Both of the OE types result in a potential OE
+ connection.
+
+ Failure to find an appropriate connection class results in an
+ administrator defined default.
+
+ In each case, when the initiator finds an appropriate class for the
+ new flow, an instance connection is made of the class which matched.
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 12]
+
+Internet-Draft opportunistic May 2003
+
+
+3.2.2 Clear-text connection
+
+ The non-existent connection makes a transition to this state when an
+ always-clear-text class is instantiated, or when an OE-permissive
+ connection fails. During the transition, the initiator creates a
+ pass-through policy object in the forwarding plane for the
+ appropriate flow.
+
+ Timing out is the only way to leave this state (see Section 3.2.7).
+
+3.2.3 Deny connection
+
+ The empty connection makes a transition to this state when a deny
+ class is instantiated, or when an OE-paranoid connection fails.
+ During the transition, the initiator creates a deny policy object in
+ the forwarding plane for the appropriate flow.
+
+ Timing out is the only way to leave this state (see Section 3.2.7).
+
+3.2.4 Potential OE connection
+
+ The empty connection makes a transition to this state when one of
+ either OE class is instantiated. During the transition to this
+ state, the initiator creates a hold policy object in the forwarding
+ plane for the appropriate flow.
+
+ In addition, when making a transition into this state, DNS lookup is
+ done in the reverse-map for a TXT delegation resource record (see
+ Section 5.2). The lookup key is the destination address of the flow.
+
+ There are three ways to exit this state:
+
+ 1. DNS lookup finds a TXT delegation resource record.
+
+ 2. DNS lookup does not find a TXT delegation resource record.
+
+ 3. DNS lookup times out.
+
+ Based upon the results of the DNS lookup, the potential OE connection
+ makes a transition to the pending OE connection state. The
+ conditions for a successful DNS look are:
+
+ 1. DNS finds an appropriate resource record
+
+ 2. It is properly formatted according to Section 5.2
+
+ 3. if DNSSEC is enabled, then the signature has been vouched for.
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 13]
+
+Internet-Draft opportunistic May 2003
+
+
+ Note that if the initiator does not find the public key present in
+ the TXT delegation record, then the public key must be looked up as a
+ sub-state. Only successful completion of all the DNS lookups is
+ considered a success.
+
+ If DNS lookup does not find a resource record or DNS times out, then
+ the initiator considers the receiver not OE capable. If this is an
+ OE-paranoid instance, then the potential OE connection makes a
+ transition to the deny connection state. If this is an OE-permissive
+ instance, then the potential OE connection makes a transition to the
+ clear-text connection state.
+
+ If the initiator finds a resource record but it is not properly
+ formatted, or if DNSSEC is enabled and reports a failure to
+ authenticate, then the potential OE connection should make a
+ transition to the deny connection state. This action SHOULD be
+ logged. If the administrator wishes to override this transition
+ between states, then an always-clear class can be installed for this
+ flow. An implementation MAY make this situation a new class.
+
+3.2.4.1 Restriction on unauthenticated TXT delegation records
+
+ An implementation SHOULD also provide an additional administrative
+ control on delegation records and DNSSEC. This control would apply
+ to delegation records (the TXT records in the reverse-map) that are
+ not protected by DNSSEC. Records of this type are only permitted to
+ delegate to their own address as a gateway. When this option is
+ enabled, an active attack on DNS will be unable to redirect packets
+ to other than the original destination.
+
+3.2.5 Pending OE connection
+
+ The potential OE connection makes a transition to this state when the
+ initiator determines that all the information required from the DNS
+ lookup is present. Upon entering this state, the initiator attempts
+ to initiate keying to the gateway provided.
+
+ Exit from this state occurs either with a successfully created IPsec
+ SA, or with a failure of some kind. Successful SA creation results
+ in a transition to the key connection state.
+
+ Three failures have caused significant problems. They are clearly
+ not the only possible failures from keying.
+
+ Note that if there are multiple gateways available in the TXT
+ delegation records, then a failure can only be declared after all
+ have been tried. Further, creation of a phase 1 SA does not
+ constitute success. A set of phase 2 SAs (a tunnel) is considered
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 14]
+
+Internet-Draft opportunistic May 2003
+
+
+ success.
+
+ The first failure occurs when an ICMP port unreachable is
+ consistently received without any other communication, or when there
+ is silence from the remote end. This usually means that either the
+ gateway is not alive, or the keying daemon is not functional. For an
+ OE-permissive connection, the initiator makes a transition to the
+ clear-text connection but with a low lifespan. For an OE-pessimistic
+ connection, the initiator makes a transition to the deny connection
+ again with a low lifespan. The lifespan in both cases is kept low
+ because the remote gateway may be in the process of rebooting or be
+ otherwise temporarily unavailable.
+
+ The length of time to wait for the remote keying daemon to wake up is
+ a matter of some debate. If there is a routing failure, 5 minutes is
+ usually long enough for the network to re-converge. Many systems can
+ reboot in that amount of time as well. However, 5 minutes is far too
+ long for most users to wait to hear that they can not connect using
+ OE. Implementations SHOULD make this a tunable parameter.
+
+ The second failure occurs after a phase 1 SA has been created, but
+ there is either no response to the phase 2 proposal, or the initiator
+ receives a negative notify (the notify must be authenticated). The
+ remote gateway is not prepared to do OE at this time. As before, the
+ initiator makes a transition to the clear-text or the deny connection
+ based upon connection class, but this time with a normal lifespan.
+
+ The third failure occurs when there is signature failure while
+ authenticating the remote gateway. This can occur when there has
+ been a key roll-over, but DNS has not caught up. In this case again,
+ the initiator makes a transition to the clear-text or the deny
+ connection based upon the connection class. However, the lifespan
+ depends upon the remaining time to live in the DNS. (Note that
+ DNSSEC signed resource records have a different expiry time than non-
+ signed records.)
+
+3.2.6 Keyed connection
+
+ The pending OE connection makes a transition to this state when
+ session keying material (the phase 2 SAs) is derived. The initiator
+ creates an encrypt policy in the forwarding plane for this flow.
+
+ There are three ways to exit this state. The first is by receipt of
+ an authenticated delete message (via the keying channel) from the
+ peer. This is normal teardown and results in a transition to the
+ expired connection state.
+
+ The second exit is by expiry of the forwarding plane keying material.
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 15]
+
+Internet-Draft opportunistic May 2003
+
+
+ This starts a re-key operation with a transition back to pending OE
+ connection. In general, the soft expiry occurs with sufficient time
+ left to continue to use the keys. A re-key can fail, which may
+ result in the connection failing to clear-text or deny as
+ appropriate. In the event of a failure, the forwarding plane policy
+ does not change until the phase 2 SA (IPsec SA) reaches its hard
+ expiry.
+
+ The third exit is in response to a negotiation from a remote gateway.
+ If the forwarding plane signals the control plane that it has
+ received an unknown SPI from the remote gateway, or an ICMP is
+ received from the remote gateway indicating an unknown SPI, the
+ initiator should consider that the remote gateway has rebooted or
+ restarted. Since these indications are easily forged, the
+ implementation must exercise care. The initiator should make a
+ cautious (rate-limited) attempt to re-key the connection.
+
+3.2.7 Expiring connection
+
+ The initiator will periodically place each of the deny, clear-text,
+ and keyed connections into this sub-state. See Section 3.4 for more
+ details of how often this occurs. The initiator queries the
+ forwarding plane for last use time of the appropriate policy. If the
+ last use time is relatively recent, then the connection returns to
+ the previous deny, clear-text or keyed connection state. If not,
+ then the connection enters the expired connection state.
+
+ The DNS query and answer that lead to the expiring connection state
+ are also examined. The DNS query may become stale. (A negative,
+ i.e. no such record, answer is valid for the period of time given by
+ the MINIMUM field in an attached SOA record. See [12] section
+ 4.3.4.) If the DNS query is stale, then a new query is made. If the
+ results change, then the connection makes a transition to a new state
+ as described in potential OE connection state.
+
+ Note that when considering how stale a connection is, both outgoing
+ SPD and incoming SAD must be queried as some flows may be
+ unidirectional for some time.
+
+ Also note that the policy at the forwarding plane is not updated
+ unless there is a conclusion that there should be a change.
+
+3.2.8 Expired connection
+
+ Entry to this state occurs when no datagrams have been forwarded
+ recently via the appropriate SPD and SAD objects. The objects in the
+ forwarding plane are removed (logging any final byte and packet
+ counts if appropriate) and the connection instance in the keying
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 16]
+
+Internet-Draft opportunistic May 2003
+
+
+ plane is deleted.
+
+ The initiator sends an ISAKMP/IKE delete to clean up the phase 2 SAs
+ as described in Section 3.4.
+
+ Whether or not to delete the phase 1 SAs at this time is left as a
+ local implementation issue. Implementations that do delete the phase
+ 1 SAs MUST send authenticated delete messages to indicate that they
+ are doing so. There is an advantage to keeping the phase 1 SAs until
+ they expire - they may prove useful again in the near future.
+
+3.3 Keying state machine - responder
+
+ The responder has a set of objects identical to those of the
+ initiator.
+
+ The responder receives an invitation to create a keying channel from
+ an initiator.
+
+3.3.1 Unauthenticated OE peer
+
+ Upon entering this state, the responder starts a DNS lookup for a KEY
+ record for the initiator. The responder looks in the reverse-map for
+ a KEY record for the initiator if the initiator has offered an
+ ID_IPV4_ADDR, and in the forward map if the initiator has offered an
+ ID_FQDN type. (See [8] section 4.6.2.1.)
+
+ The responder exits this state upon successful receipt of a KEY from
+ DNS, and use of the key to verify the signature of the initiator.
+
+ Successful authentication of the peer results in a transition to the
+ authenticated OE Peer state.
+
+ Note that the unauthenticated OE peer state generally occurs in the
+ middle of the key negotiation protocol. It is really a form of
+ pseudo-state.
+
+3.3.2 Authenticated OE Peer
+
+ The peer will eventually propose one or more phase 2 SAs. The
+ responder uses the source and destination address in the proposal to
+ finish instantiating the connection state using the connection class
+ table. The responder MUST search for an identical connection object
+ at this point.
+
+ If an identical connection is found, then the responder deletes the
+ old instance, and the new object makes a transition to the pending OE
+ connection state. This means that new ISAKMP connections with a
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 17]
+
+Internet-Draft opportunistic May 2003
+
+
+ given peer will always use the latest instance, which is the correct
+ one if the peer has rebooted in the interim.
+
+ If an identical connection is not found, then the responder makes the
+ transition according to the rules given for the initiator.
+
+ Note that if the initiator is in OE-paranoid mode and the responder
+ is in either always-clear-text or deny, then no communication is
+ possible according to policy. An implementation is permitted to
+ create new types of policies such as "accept OE but do not initiate
+ it". This is a local matter.
+
+3.4 Renewal and teardown
+
+3.4.1 Aging
+
+ A potentially unlimited number of tunnels may exist. In practice,
+ only a few tunnels are used during a period of time. Unused tunnels
+ MUST, therefore, be torn down. Detecting when tunnels are no longer
+ in use is the subject of this section.
+
+ There are two methods for removing tunnels: explicit deletion or
+ expiry.
+
+ Explicit deletion requires an IKE delete message. As the deletes
+ MUST be authenticated, both ends of the tunnel must maintain the key
+ channel (phase 1 ISAKMP SA). An implementation which refuses to
+ either maintain or recreate the keying channel SA will be unable to
+ use this method.
+
+ The tunnel expiry method, simply allows the IKE daemon to expire
+ normally without attempting to re-key it.
+
+ Regardless of which method is used to remove tunnels, the
+ implementation requires a method to determine if the tunnel is still
+ in use. The specifics are a local matter, but the FreeS/WAN project
+ uses the following criteria. These criteria are currently
+ implemented in the key management daemon, but could also be
+ implemented at the SPD layer using an idle timer.
+
+ Set a short initial (soft) lifespan of 1 minute since many net flows
+ last only a few seconds.
+
+ At the end of the lifespan, check to see if the tunnel was used by
+ traffic in either direction during the last 30 seconds. If so,
+ assign a longer tentative lifespan of 20 minutes after which, look
+ again. If the tunnel is not in use, then close the tunnel.
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 18]
+
+Internet-Draft opportunistic May 2003
+
+
+ The expiring state in the key management system (see Section 3.2.7)
+ implements these timeouts. The timer above may be in the forwarding
+ plane, but then it must be re-settable.
+
+ The tentative lifespan is independent of re-keying; it is just the
+ time when the tunnel's future is next considered. (The term lifespan
+ is used here rather than lifetime for this reason.) Unlike re-keying,
+ this tunnel use check is not costly and should happen reasonably
+ frequently.
+
+ A multi-step back-off algorithm is not considered worth the effort
+ here.
+
+ If the security gateway and the client host are the same and not a
+ Bump-in-the-Stack or Bump-in-the-Wire implementation, tunnel teardown
+ decisions MAY pay attention to TCP connection status as reported by
+ the local TCP layer. A still-open TCP connection is almost a
+ guarantee that more traffic is expected. Closing of the only TCP
+ connection through a tunnel is a strong hint that no more traffic is
+ expected.
+
+3.4.2 Teardown and cleanup
+
+ Teardown should always be coordinated between the two ends of the
+ tunnel by interpreting and sending delete notifications. There is a
+ detailed sub-state in the expired connection state of the key manager
+ that relates to retransmits of the delete notifications, but this is
+ considered to be a keying system detail.
+
+ On receiving a delete for the outbound SAs of a tunnel (or some
+ subset of them), tear down the inbound ones also and notify the
+ remote end with a delete. If the local system receives a delete for
+ a tunnel which is no longer in existence, then two delete messages
+ have crossed paths. Ignore the delete. The operation has already
+ been completed. Do not generate any messages in this situation.
+
+ Tunnels are to be considered as bidirectional entities, even though
+ the low-level protocols don't treat them this way.
+
+ When the deletion is initiated locally, rather than as a response to
+ a received delete, send a delete for (all) the inbound SAs of a
+ tunnel. If the local system does not receive a responding delete for
+ the outbound SAs, try re-sending the original delete. Three tries
+ spaced 10 seconds apart seems a reasonable level of effort. A
+ failure of the other end to respond after 3 attempts, indicates that
+ the possibility of further communication is unlikely. Remove the
+ outgoing SAs. (The remote system may be a mobile node that is no
+ longer present or powered on.)
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 19]
+
+Internet-Draft opportunistic May 2003
+
+
+ After re-keying, transmission should switch to using the new outgoing
+ SAs (ISAKMP or IPsec) immediately, and the old leftover outgoing SAs
+ should be cleared out promptly (delete should be sent for the
+ outgoing SAs) rather than waiting for them to expire. This reduces
+ clutter and minimizes confusion for the operator doing diagnostics.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 20]
+
+Internet-Draft opportunistic May 2003
+
+
+4. Impacts on IKE
+
+4.1 ISAKMP/IKE protocol
+
+ The IKE wire protocol needs no modifications. The major changes are
+ implementation issues relating to how the proposals are interpreted,
+ and from whom they may come.
+
+ As opportunistic encryption is designed to be useful between peers
+ without prior operator configuration, an IKE daemon must be prepared
+ to negotiate phase 1 SAs with any node. This may require a large
+ amount of resources to maintain cookie state, as well as large
+ amounts of entropy for nonces, cookies and so on.
+
+ The major changes to support opportunistic encryption are at the IKE
+ daemon level. These changes relate to handling of key acquisition
+ requests, lookup of public keys and TXT records, and interactions
+ with firewalls and other security facilities that may be co-resident
+ on the same gateway.
+
+4.2 Gateway discovery process
+
+ In a typical configured tunnel, the address of SG-B is provided via
+ configuration. Furthermore, the mapping of an SPD entry to a gateway
+ is typically a 1:1 mapping. When the 0.0.0.0/0 SPD entry technique
+ is used, then the mapping to a gateway is determined by the reverse
+ DNS records.
+
+ The need to do a DNS lookup and wait for a reply will typically
+ introduce a new state and a new event source (DNS replies) to IKE.
+ Although a synchronous DNS request can be implemented for proof of
+ concept, experience is that it can cause very high latencies when a
+ queue of queries must all timeout in series.
+
+ Use of an asynchronous DNS lookup will also permit overlap of DNS
+ lookups with some of the protocol steps.
+
+4.3 Self identification
+
+ SG-A will have to establish its identity. Use an IPv4 ID in phase 1.
+
+ There are many situations where the administrator of SG-A may not be
+ able to control the reverse DNS records for SG-A's public IP address.
+ Typical situations include dialup connections and most residential-
+ type broadband Internet access (ADSL, cable-modem) connections. In
+ these situations, a fully qualified domain name that is under the
+ control of SG-A's administrator may be used when acting as an
+ initiator only. The FQDN ID should be used in phase 1. See Section
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 21]
+
+Internet-Draft opportunistic May 2003
+
+
+ 5.3 for more details and restrictions.
+
+4.4 Public key retrieval process
+
+ Upon receipt of a phase 1 SA proposal with either an IPv4 (IPv6) ID
+ or an FQDN ID, an IKE daemon needs to examine local caches and
+ configuration files to determine if this is part of a configured
+ tunnel. If no configured tunnels are found, then the implementation
+ should attempt to retrieve a KEY record from the reverse DNS in the
+ case of an IPv4/IPv6 ID, or from the forward DNS in the case of FQDN
+ ID.
+
+ It is reasonable that if other non-local sources of policy are used
+ (COPS, LDAP), they be consulted concurrently but some clear ordering
+ of policy be provided. Note that due to variances in latency,
+ implementations must wait for positive or negative replies from all
+ sources of policy before making any decisions.
+
+4.5 Interactions with DNSSEC
+
+ The implementation described (1.98) neither uses DNSSEC directly to
+ explicitly verify the authenticity of zone information, nor uses the
+ NXT records to provide authentication of the absence of a TXT or KEY
+ record. Rather, this implementation uses a trusted path to a DNSSEC
+ capable caching resolver.
+
+ To distinguish between an authenticated and an unauthenticated DNS
+ resource record, a stub resolver capable of returning DNSSEC
+ information MUST be used.
+
+4.6 Required proposal types
+
+4.6.1 Phase 1 parameters
+
+ Main mode MUST be used.
+
+ The initiator MUST offer at least one proposal using some combination
+ of: 3DES, HMAC-MD5 or HMAC-SHA1, DH group 2 or 5. Group 5 SHOULD be
+ proposed first. [11]
+
+ The initiator MAY offer additional proposals, but the cipher MUST not
+ be weaker than 3DES. The initiator SHOULD limit the number of
+ proposals such that the IKE datagrams do not need to be fragmented.
+
+ The responder MUST accept one of the proposals. If any configuration
+ of the responder is required then the responder is not acting in an
+ opportunistic way.
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 22]
+
+Internet-Draft opportunistic May 2003
+
+
+ SG-A SHOULD use an ID_IPV4_ADDR (ID_IPV6_ADDR for IPv6) of the
+ external interface of SG-A for phase 1. (There is an exception, see
+ Section 5.3.) The authentication method MUST be RSA public key
+ signatures. The RSA key for SG-A SHOULD be placed into a DNS KEY
+ record in the reverse space of SG-A (i.e. using in-addr.arpa).
+
+4.6.2 Phase 2 parameters
+
+ SG-A MUST propose a tunnel between Alice and Bob, using 3DES-CBC
+ mode, MD5 or SHA1 authentication. Perfect Forward Secrecy MUST be
+ specified.
+
+ Tunnel mode MUST be used.
+
+ Identities MUST be ID_IPV4_ADDR_SUBNET with the mask being /32.
+
+ Authorization for SG-A to act on Alice's behalf is determined by
+ looking for a TXT record in the reverse-map at Alice's address.
+
+ Compression SHOULD NOT be mandatory. It may be offered as an option.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 23]
+
+Internet-Draft opportunistic May 2003
+
+
+5. DNS issues
+
+5.1 Use of KEY record
+
+ In order to establish their own identities, SG-A and SG-B SHOULD
+ publish their public keys in their reverse DNS via DNSSEC's KEY
+ record. See section 3 of RFC 2535 [16].
+
+ For example:
+
+ KEY 0x4200 4 1 AQNJjkKlIk9...nYyUkKK8
+
+ 0x4200: The flag bits, indicating that this key is prohibited for
+ confidentiality use (it authenticates the peer only, a separate
+ Diffie-Hellman exchange is used for confidentiality), and that
+ this key is associated with the non-zone entity whose name is the
+ RR owner name. No other flags are set.
+
+ 4: This indicates that this key is for use by IPsec.
+
+ 1: An RSA key is present.
+
+ AQNJjkKlIk9...nYyUkKK8: The public key of the host as described in
+ [17].
+
+ Use of several KEY records allows for key rollover. The SIG Payload
+ in IKE phase 1 SHOULD be accepted if the public key given by any KEY
+ RR validates it.
+
+5.2 Use of TXT delegation record
+
+ Alice publishes a TXT record to provide authorization for SG-A to act
+ on Alice's behalf. Bob publishes a TXT record to provide
+ authorization for SG-B to act on Bob's behalf. These records are
+ located in the reverse DNS (in-addr.arpa) for their respective IP
+ addresses. The reverse DNS SHOULD be secured by DNSSEC, when it is
+ deployed. DNSSEC is required to defend against active attacks.
+
+ If Alice's address is P.Q.R.S, then she can authorize another node to
+ act on her behalf by publishing records at:
+
+ S.R.Q.P.in-addr.arpa
+
+ The contents of the resource record are expected to be a string that
+ uses the following syntax, as suggested in [15]. (Note that the
+ reply to query may include other TXT resource records used by other
+ applications.)
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 24]
+
+Internet-Draft opportunistic May 2003
+
+
+ ---------------------------------------------------------------------
+
+
+ X-IPsec-Server(P)=A.B.C.D KEY
+
+ Figure 2: Format of reverse delegation record
+
+ ---------------------------------------------------------------------
+
+ P: Specifies a precedence for this record. This is similar to MX
+ record preferences. Lower numbers have stronger preference.
+
+ A.B.C.D: Specifies the IP address of the Security Gateway for this
+ client machine.
+
+ KEY: Is the encoded RSA Public key of the Security Gateway. The key
+ is provided here to avoid a second DNS lookup. If this field is
+ absent, then a KEY resource record should be looked up in the
+ reverse-map of A.B.C.D. The key is transmitted in base64 format.
+
+ The pieces of the record are separated by any whitespace (space, tab,
+ newline, carriage return). An ASCII space SHOULD be used.
+
+ In the case where Alice is located at a public address behind a
+ security gateway that has no fixed address (or no control over its
+ reverse-map), then Alice may delegate to a public key by domain name.
+
+ ---------------------------------------------------------------------
+
+
+ X-IPsec-Server(P)=@FQDN KEY
+
+ Figure 3: Format of reverse delegation record (FQDN version)
+
+ ---------------------------------------------------------------------
+
+ P: Is as above.
+
+ FQDN: Specifies the FQDN that the Security Gateway will identify
+ itself with.
+
+ KEY: Is the encoded RSA Public key of the Security Gateway.
+
+ If there is more than one such TXT record with strongest (lowest
+ numbered) precedence, one Security Gateway is picked arbitrarily from
+ those specified in the strongest-preference records.
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 25]
+
+Internet-Draft opportunistic May 2003
+
+
+5.2.1 Long TXT records
+
+ When packed into transport format, TXT records which are longer than
+ 255 characters are divided into smaller <character-strings>. (See
+ [13] section 3.3 and 3.3.14.) These MUST be reassembled into a single
+ string for processing. Whitespace characters in the base64 encoding
+ are to be ignored.
+
+5.2.2 Choice of TXT record
+
+ It has been suggested to use the KEY, OPT, CERT, or KX records
+ instead of a TXT record. None is satisfactory.
+
+ The KEY RR has a protocol field which could be used to indicate a new
+ protocol, and an algorithm field which could be used to indicate
+ different contents in the key data. However, the KEY record is
+ clearly not intended for storing what are really authorizations, it
+ is just for identities. Other uses have been discouraged.
+
+ OPT resource records, as defined in [14] are not intended to be used
+ for storage of information. They are not to be loaded, cached or
+ forwarded. They are, therefore, inappropriate for use here.
+
+ CERT records [18] can encode almost any set of information. A custom
+ type code could be used permitting any suitable encoding to be
+ stored, not just X.509. According to the RFC, the certificate RRs
+ are to be signed internally which may add undesirable and unnecessary
+ bulk. Larger DNS records may require TCP instead of UDP transfers.
+
+ At the time of protocol design, the CERT RR was not widely deployed
+ and could not be counted upon. Use of CERT records will be
+ investigated, and may be proposed in a future revision of this
+ document.
+
+ KX records are ideally suited for use instead of TXT records, but had
+ not been deployed at the time of implementation.
+
+5.3 Use of FQDN IDs
+
+ Unfortunately, not every administrator has control over the contents
+ of the reverse-map. Where the initiator (SG-A) has no suitable
+ reverse-map, the authorization record present in the reverse-map of
+ Alice may refer to a FQDN instead of an IP address.
+
+ In this case, the client's TXT record gives the fully qualified
+ domain name (FQDN) in place of its security gateway's IP address.
+ The initiator should use the ID_FQDN ID-payload in phase 1. A
+ forward lookup for a KEY record on the FQDN must yield the
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 26]
+
+Internet-Draft opportunistic May 2003
+
+
+ initiator's public key.
+
+ This method can also be used when the external address of SG-A is
+ dynamic.
+
+ If SG-A is acting on behalf of Alice, then Alice must still delegate
+ authority for SG-A to do so in her reverse-map. When Alice and SG-A
+ are one and the same (i.e. Alice is acting as an end-node) then
+ there is no need for this when initiating only.
+
+ However, Alice must still delegate to herself if she wishes others
+ to initiate OE to her. See Figure 3.
+
+5.4 Key roll-over
+
+ Good cryptographic hygiene says that one should replace public/
+ private key pairs periodically. Some administrators may wish to do
+ this as often as daily. Typical DNS propagation delays are
+ determined by the SOA Resource Record MINIMUM parameter, which
+ controls how long DNS replies may be cached. For reasonable
+ operation of DNS servers, administrators usually want this value to
+ be at least several hours, sometimes as a long as a day. This
+ presents a problem - a new key MUST not be used prior to it
+ propagating through DNS.
+
+ This problem is dealt with by having the Security Gateway generate a
+ new public/private key pair at least MINIMUM seconds in advance of
+ using it. It then adds this key to the DNS (both as a second KEY
+ record and in additional TXT delegation records) at key generation
+ time. Note: only one key is allowed in each TXT record.
+
+ When authenticating, all gateways MUST have available all public keys
+ that are found in DNS for this entity. This permits the
+ authenticating end to check both the key for "today" and the key for
+ "tomorrow". Note that it is the end which is creating the signature
+ (possesses the private key) that determines which key is to be used.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 27]
+
+Internet-Draft opportunistic May 2003
+
+
+6. Network address translation interaction
+
+ There are no fundamentally new issues for implementing opportunistic
+ encryption in the presence of network address translation. Rather
+ there are only the regular IPsec issues with NAT traversal.
+
+ There are several situations to consider for NAT.
+
+6.1 Co-located NAT/NAPT
+
+ If SG-A is also performing network address translation on behalf of
+ Alice, then the packet should be translated prior to being subjected
+ to opportunistic encryption. This is in contrast to typically
+ configured tunnels which often exist to bridge islands of private
+ network address space. SG-A will use the translated source address
+ for phase 2, and so SG-B will look up that address to confirm SG-A's
+ authorization.
+
+ In the case of NAT (1:1), the address space into which the
+ translation is done MUST be globally unique, and control over the
+ reverse-map is assumed. Placing of TXT records is possible.
+
+ In the case of NAPT (m:1), the address will be SG-A. The ability to
+ get KEY and TXT records in place will again depend upon whether or
+ not there is administrative control over the reverse-map. This is
+ identical to situations involving a single host acting on behalf of
+ itself. FQDN style can be used to get around a lack of a reverse-map
+ for initiators only.
+
+6.2 SG-A behind NAT/NAPT
+
+ If there is a NAT or NAPT between SG-A and SG-B, then normal IPsec
+ NAT traversal rules apply. In addition to the transport problem
+ which may be solved by other mechanisms, there is the issue of what
+ phase 1 and phase 2 IDs to use. While FQDN could be used during
+ phase 1 for SG-A, there is no appropriate ID for phase 2 that permits
+ SG-B to determine that SG-A is in fact authorized to speak for Alice.
+
+6.3 Bob is behind a NAT/NAPT
+
+ If Bob is behind a NAT (perhaps SG-B), then there is, in fact, no way
+ for Alice to address a packet to Bob. Not only is opportunistic
+ encryption impossible, but it is also impossible for Alice to
+ initiate any communication to Bob. It may be possible for Bob to
+ initiate in such a situation. This creates an asymmetry, but this is
+ common for NAPT.
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 28]
+
+Internet-Draft opportunistic May 2003
+
+
+7. Host implementations
+
+ When Alice and SG-A are components of the same system, they are
+ considered to be a host implementation. The packet sequence scenario
+ remains unchanged.
+
+ Components marked Alice are the upper layers (TCP, UDP, the
+ application), and SG-A is the IP layer.
+
+ Note that tunnel mode is still required.
+
+ As Alice and SG-A are acting on behalf of themselves, no TXT based
+ delegation record is necessary for Alice to initiate. She can rely
+ on FQDN in a forward map. This is particularly attractive to mobile
+ nodes such as notebook computers at conferences. To respond, Alice/
+ SG-A will still need an entry in Alice's reverse-map.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 29]
+
+Internet-Draft opportunistic May 2003
+
+
+8. Multi-homing
+
+ If there are multiple paths between Alice and Bob (as illustrated in
+ the diagram with SG-D), then additional DNS records are required to
+ establish authorization.
+
+ In Figure 1, Alice has two ways to exit her network: SG-A and SG-D.
+ Previously SG-D has been ignored. Postulate that there are routers
+ between Alice and her set of security gateways (denoted by the +
+ signs and the marking of an autonomous system number for Alice's
+ network). Datagrams may, therefore, travel to either SG-A or SG-D en
+ route to Bob.
+
+ As long as all network connections are in good order, it does not
+ matter how datagrams exit Alice's network. When they reach either
+ security gateway, the security gateway will find the TXT delegation
+ record in Bob's reverse-map, and establish an SA with SG-B.
+
+ SG-B has no problem establishing that either of SG-A or SG-D may
+ speak for Alice, because Alice has published two equally weighted TXT
+ delegation records:
+
+ ---------------------------------------------------------------------
+
+
+ X-IPsec-Server(10)=192.1.1.5 AQMM...3s1Q==
+ X-IPsec-Server(10)=192.1.1.6 AAJN...j8r9==
+
+ Figure 4: Multiple gateway delegation example for Alice
+
+ ---------------------------------------------------------------------
+
+ Alice's routers can now do any kind of load sharing needed. Both SG-
+ A and SG-D send datagrams addressed to Bob through their tunnel to
+ SG-B.
+
+ Alice's use of non-equal weight delegation records to show preference
+ of one gateway over another, has relevance only when SG-B is
+ initiating to Alice.
+
+ If the precedences are the same, then SG-B has a more difficult time.
+ It must decide which of the two tunnels to use. SG-B has no
+ information about which link is less loaded, nor which security
+ gateway has more cryptographic resources available. SG-B, in fact,
+ has no knowledge of whether both gateways are even reachable.
+
+ The Public Internet's default-free zone may well know a good route to
+ Alice, but the datagrams that SG-B creates must be addressed to
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 30]
+
+Internet-Draft opportunistic May 2003
+
+
+ either SG-A or SG-D; they can not be addressed to Alice directly.
+
+ SG-B may make a number of choices:
+
+ 1. It can ignore the problem and round robin among the tunnels.
+ This causes losses during times when one or the other security
+ gateway is unreachable. If this worries Alice, she can change
+ the weights in her TXT delegation records.
+
+ 2. It can send to the gateway from which it most recently received
+ datagrams. This assumes that routing and reachability are
+ symmetrical.
+
+ 3. It can listen to BGP information from the Internet to decide
+ which system is currently up. This is clearly much more
+ complicated, but if SG-B is already participating in the BGP
+ peering system to announce Bob, the results data may already be
+ available to it.
+
+ 4. It can refuse to negotiate the second tunnel. (It is unclear
+ whether or not this is even an option.)
+
+ 5. It can silently replace the outgoing portion of the first tunnel
+ with the second one while still retaining the incoming portions
+ of both. SG-B can, thus, accept datagrams from either SG-A or
+ SG-D, but send only to the gateway that most recently re-keyed
+ with it.
+
+ Local policy determines which choice SG-B makes. Note that even if
+ SG-B has perfect knowledge about the reachability of SG-A and SG-D,
+ Alice may not be reachable from either of these security gateways
+ because of internal reachability issues.
+
+ FreeS/WAN implements option 5. Implementing a different option is
+ being considered. The multi-homing aspects of OE are not well
+ developed and may be the subject of a future document.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 31]
+
+Internet-Draft opportunistic May 2003
+
+
+9. Failure modes
+
+9.1 DNS failures
+
+ If a DNS server fails to respond, local policy decides whether or not
+ to permit communication in the clear as embodied in the connection
+ classes in Section 3.2. It is easy to mount a denial of service
+ attack on the DNS server responsible for a particular network's
+ reverse-map. Such an attack may cause all communication with that
+ network to go in the clear if the policy is permissive, or fail
+ completely if the policy is paranoid. Please note that this is an
+ active attack.
+
+ There are still many networks that do not have properly configured
+ reverse-maps. Further, if the policy is not to communicate, the
+ above denial of service attack isolates the target network.
+ Therefore, the decision of whether or not to permit communication in
+ the clear MUST be a matter of local policy.
+
+9.2 DNS configured, IKE failures
+
+ DNS records claim that opportunistic encryption should occur, but the
+ target gateway either does not respond on port 500, or refuses the
+ proposal. This may be because of a crash or reboot, a faulty
+ configuration, or a firewall filtering port 500.
+
+ The receipt of ICMP port, host or network unreachable messages
+ indicates a potential problem, but MUST NOT cause communication to
+ fail immediately. ICMP messages are easily forged by attackers. If
+ such a forgery caused immediate failure, then an active attacker
+ could easily prevent any encryption from ever occurring, possibly
+ preventing all communication.
+
+ In these situations a clear log should be produced and local policy
+ should dictate if communication is then permitted in the clear.
+
+9.3 System reboots
+
+ Tunnels sometimes go down because the remote end crashes,
+ disconnects, or has a network link break. In general there is no
+ notification of this. Even in the event of a crash and successful
+ reboot, other SGs don't hear about it unless the rebooted SG has
+ specific reason to talk to them immediately. Over-quick response to
+ temporary network outages is undesirable. Note that a tunnel can be
+ torn down and then re-established without any effect visible to the
+ user except a pause in traffic. On the other hand, if one end
+ reboots, the other end can't get datagrams to it at all (except via
+ IKE) until the situation is noticed. So a bias toward quick response
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 32]
+
+Internet-Draft opportunistic May 2003
+
+
+ is appropriate even at the cost of occasional false alarms.
+
+ A mechanism for recovery after reboot is a topic of current research
+ and is not specified in this document.
+
+ A deliberate shutdown should include an attempt, using deletes, to
+ notify all other SGs currently connected by phase 1 SAs that
+ communication is about to fail. Again, a remote SG will assume this
+ is a teardown. Attempts by the remote SGs to negotiate new tunnels
+ as replacements should be ignored. When possible, SGs should attempt
+ to preserve information about currently-connected SGs in non-volatile
+ storage, so that after a crash, an Initial-Contact can be sent to
+ previous partners to indicate loss of all previously established
+ connections.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 33]
+
+Internet-Draft opportunistic May 2003
+
+
+10. Unresolved issues
+
+10.1 Control of reverse DNS
+
+ The method of obtaining information by reverse DNS lookup causes
+ problems for people who cannot control their reverse DNS bindings.
+ This is an unresolved problem in this version, and is out of scope.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 34]
+
+Internet-Draft opportunistic May 2003
+
+
+11. Examples
+
+11.1 Clear-text usage (permit policy)
+
+ Two example scenarios follow. In the first example GW-A (Gateway A)
+ and GW-B (Gateway B) have always-clear-text policies, and in the
+ second example they have an OE policy.
+
+ ---------------------------------------------------------------------
+
+
+ Alice SG-A DNS SG-B Bob
+ (1)
+ ------(2)-------------->
+ <-----(3)---------------
+ (4)----(5)----->
+ ----------(6)------>
+ ------(7)----->
+ <------(8)------
+ <----------(9)------
+ <----(10)-----
+ (11)----------->
+ ----------(12)----->
+ -------------->
+ <---------------
+ <-------------------
+ <-------------
+
+ Figure 5: Timing of regular transaction
+
+ ---------------------------------------------------------------------
+
+ Alice wants to communicate with Bob. Perhaps she wants to retrieve a
+ web page from Bob's web server. In the absence of opportunistic
+ encryptors, the following events occur:
+
+ (1) Human or application 'clicks' with a name.
+
+ (2) Application looks up name in DNS to get IP address.
+
+ (3) Resolver returns A record to application.
+
+ (4) Application starts a TCP session or UDP session and OS sends
+ datagram.
+
+ (5) Datagram is seen at first gateway from Alice (SG-A). (SG-A makes
+ a transition through Empty connection to always-clear connection
+ and instantiates a pass-through policy at the forwarding plane.)
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 35]
+
+Internet-Draft opportunistic May 2003
+
+
+ (6) Datagram is seen at last gateway before Bob (SG-B).
+
+ (7) First datagram from Alice is seen by Bob.
+
+ (8) First return datagram is sent by Bob.
+
+ (9) Datagram is seen at Bob's gateway. (SG-B makes a transition
+ through Empty connection to always-clear connection and
+ instantiates a pass-through policy at the forwarding plane.)
+
+ (10) Datagram is seen at Alice's gateway.
+
+ (11) OS hands datagram to application. Alice sends another datagram.
+
+ (12) A second datagram traverses the Internet.
+
+
+11.2 Opportunistic encryption
+
+ In the presence of properly configured opportunistic encryptors, the
+ event list is extended.
+
+ ---------------------------------------------------------------------
+
+
+ Alice SG-A DNS SG-B Bob
+ (1)
+ ------(2)-------------->
+ <-----(3)---------------
+ (4)----(5)----->+
+ ----(5B)->
+ <---(5C)--
+ ~~~~~~~~~~~~~(5D)~~~>
+ <~~~~~~~~~~~~(5E1)~~~
+ ~~~~~~~~~~~~~(5E2)~~>
+ <~~~~~~~~~~~~(5E3)~~~
+ #############(5E4)##>
+ <############(5E5)###
+ <----(5F1)--
+ -----(5F2)->
+ #############(5G1)##>
+ <----(5H1)--
+ -----(5H2)->
+ <############(5G2)###
+ #############(5G3)##>
+ ============(6)====>
+ ------(7)----->
+ <------(8)------
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 36]
+
+Internet-Draft opportunistic May 2003
+
+
+ <==========(9)======
+ <-----(10)----
+ (11)----------->
+ ==========(12)=====>
+ -------------->
+ <---------------
+ <===================
+ <-------------
+
+ Figure 6: Timing of opportunistic encryption transaction
+
+ ---------------------------------------------------------------------
+
+ (1) Human or application clicks with a name.
+
+ (2) Application initiates DNS mapping.
+
+ (3) Resolver returns A record to application.
+
+ (4) Application starts a TCP session or UDP.
+
+ (5) SG-A (host or SG) sees datagram to target, and buffers it.
+
+ (5B) SG-A asks DNS for TXT record.
+
+ (5C) DNS returns TXT record(s).
+
+ (5D) Initial IKE Main Mode Packet goes out.
+
+ (5E) IKE ISAKMP phase 1 succeeds.
+
+ (5F) SG-B asks DNS for TXT record to prove SG-A is an agent for
+ Alice.
+
+ (5G) IKE phase 2 negotiation.
+
+ (5H) DNS lookup by responder (SG-B).
+
+ (6) Buffered datagram is sent by SG-A.
+
+ (7) Datagram is received by SG-B, decrypted, and sent to Bob.
+
+ (8) Bob replies, and datagram is seen by SG-B.
+
+ (9) SG-B already has tunnel up with SG-A, and uses it.
+
+ (10) SG-A decrypts datagram and gives it to Alice.
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 37]
+
+Internet-Draft opportunistic May 2003
+
+
+ (11) Alice receives datagram. Sends new packet to Bob.
+
+ (12) SG-A gets second datagram, sees that tunnel is up, and uses it.
+
+ For the purposes of this section, we will describe only the changes
+ that occur between Figure 5 and Figure 6. This corresponds to time
+ points 5, 6, 7, 9 and 10 on the list above.
+
+11.2.1 (5) IPsec datagram interception
+
+ At point (5), SG-A intercepts the datagram because this source/
+ destination pair lacks a policy (the non-existent policy state). SG-
+ A creates a hold policy, and buffers the datagram. SG-A requests
+ keys from the keying daemon.
+
+11.2.2 (5B) DNS lookup for TXT record
+
+ SG-A's IKE daemon, having looked up the source/destination pair in
+ the connection class list, creates a new Potential OE connection
+ instance. SG-A starts DNS queries.
+
+11.2.3 (5C) DNS returns TXT record(s)
+
+ DNS returns properly formed TXT delegation records, and SG-A's IKE
+ daemon causes this instance to make a transition from Potential OE
+ connection to Pending OE connection.
+
+ Using the example above, the returned record might contain:
+
+ ---------------------------------------------------------------------
+
+
+ X-IPsec-Server(10)=192.1.1.5 AQMM...3s1Q==
+
+ Figure 7: Example of reverse delegation record for Bob
+
+ ---------------------------------------------------------------------
+
+ with SG-B's IP address and public key listed.
+
+11.2.4 (5D) Initial IKE main mode packet goes out
+
+ Upon entering Pending OE connection, SG-A sends the initial ISAKMP
+ message with proposals. See Section 4.6.1.
+
+11.2.5 (5E1) Message 2 of phase 1 exchange
+
+ SG-B receives the message. A new connection instance is created in
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 38]
+
+Internet-Draft opportunistic May 2003
+
+
+ the unauthenticated OE peer state.
+
+11.2.6 (5E2) Message 3 of phase 1 exchange
+
+ SG-A sends a Diffie-Hellman exponent. This is an internal state of
+ the keying daemon.
+
+11.2.7 (5E3) Message 4 of phase 1 exchange
+
+ SG-B responds with a Diffie-Hellman exponent. This is an internal
+ state of the keying protocol.
+
+11.2.8 (5E4) Message 5 of phase 1 exchange
+
+ SG-A uses the phase 1 SA to send its identity under encryption. The
+ choice of identity is discussed in Section 4.6.1. This is an
+ internal state of the keying protocol.
+
+11.2.9 (5F1) Responder lookup of initiator key
+
+ SG-B asks DNS for the public key of the initiator. DNS looks for a
+ KEY record by IP address in the reverse-map. That is, a KEY resource
+ record is queried for 4.1.1.192.in-addr.arpa (recall that SG-A's
+ external address is 192.1.1.4). SG-B uses the resulting public key
+ to authenticate the initiator. See Section 5.1 for further details.
+
+11.2.10 (5F2) DNS replies with public key of initiator
+
+ Upon successfully authenticating the peer, the connection instance
+ makes a transition to authenticated OE peer on SG-B.
+
+ The format of the TXT record returned is described in Section 5.2.
+
+11.2.11 (5E5) Responder replies with ID and authentication
+
+ SG-B sends its ID along with authentication material. This is an
+ internal state for the keying protocol.
+
+11.2.12 (5G) IKE phase 2
+
+11.2.12.1 (5G1) Initiator proposes tunnel
+
+ Having established mutually agreeable authentications (via KEY) and
+ authorizations (via TXT), SG-A proposes to create an IPsec tunnel for
+ datagrams transiting from Alice to Bob. This tunnel is established
+ only for the Alice/Bob combination, not for any subnets that may be
+ behind SG-A and SG-B.
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 39]
+
+Internet-Draft opportunistic May 2003
+
+
+11.2.12.2 (5H1) Responder determines initiator's authority
+
+ While the identity of SG-A has been established, its authority to
+ speak for Alice has not yet been confirmed. SG-B does a reverse
+ lookup on Alice's address for a TXT record.
+
+ Upon receiving this specific proposal, SG-B's connection instance
+ makes a transition into the potential OE connection state. SG-B may
+ already have an instance, and the check is made as described above.
+
+11.2.12.3 (5H2) DNS replies with TXT record(s)
+
+ The returned key and IP address should match that of SG-A.
+
+11.2.12.4 (5G2) Responder agrees to proposal
+
+ Should additional communication occur between, for instance, Dave and
+ Bob using SG-A and SG-B, a new tunnel (phase 2 SA) would be
+ established. The phase 1 SA may be reusable.
+
+ SG-A, having successfully keyed the tunnel, now makes a transition
+ from Pending OE connection to Keyed OE connection.
+
+ The responder MUST setup the inbound IPsec SAs before sending its
+ reply.
+
+11.2.12.5 (5G3) Final acknowledgment from initiator
+
+ The initiator agrees with the responder's choice and sets up the
+ tunnel. The initiator sets up the inbound and outbound IPsec SAs.
+
+ The proper authorization returned with keys prompts SG-B to make a
+ transition to the keyed OE connection state.
+
+ Upon receipt of this message, the responder may now setup the
+ outbound IPsec SAs.
+
+11.2.13 (6) IPsec succeeds, and sets up tunnel for communication between
+ Alice and Bob
+
+ SG-A sends the datagram saved at step (5) through the newly created
+ tunnel to SG-B, where it gets decrypted and forwarded. Bob receives
+ it at (7) and replies at (8).
+
+11.2.14 (9) SG-B already has tunnel up with G1 and uses it
+
+ At (9), SG-B has already established an SPD entry mapping Bob->Alice
+ via a tunnel, so this tunnel is simply applied. The datagram is
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 40]
+
+Internet-Draft opportunistic May 2003
+
+
+ encrypted to SG-A, decrypted by SG-A and passed to Alice at (10).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 41]
+
+Internet-Draft opportunistic May 2003
+
+
+12. Security considerations
+
+12.1 Configured vs opportunistic tunnels
+
+ Configured tunnels are those which are setup using bilateral
+ mechanisms: exchanging public keys (raw RSA, DSA, PKIX), pre-shared
+ secrets, or by referencing keys that are in known places
+ (distinguished name from LDAP, DNS). These keys are then used to
+ configure a specific tunnel.
+
+ A pre-configured tunnel may be on all the time, or may be keyed only
+ when needed. The end points of the tunnel are not necessarily
+ static: many mobile applications (road warrior) are considered to be
+ configured tunnels.
+
+ The primary characteristic is that configured tunnels are assigned
+ specific security properties. They may be trusted in different ways
+ relating to exceptions to firewall rules, exceptions to NAT
+ processing, and to bandwidth or other quality of service
+ restrictions.
+
+ Opportunistic tunnels are not inherently trusted in any strong way.
+ They are created without prior arrangement. As the two parties are
+ strangers, there MUST be no confusion of datagrams that arrive from
+ opportunistic peers and those that arrive from configured tunnels. A
+ security gateway MUST take care that an opportunistic peer can not
+ impersonate a configured peer.
+
+ Ingress filtering MUST be used to make sure that only datagrams
+ authorized by negotiation (and the concomitant authentication and
+ authorization) are accepted from a tunnel. This is to prevent one
+ peer from impersonating another.
+
+ An implementation suggestion is to treat opportunistic tunnel
+ datagrams as if they arrive on a logical interface distinct from
+ other configured tunnels. As the number of opportunistic tunnels
+ that may be created automatically on a system is potentially very
+ high, careful attention to scaling should be taken into account.
+
+ As with any IKE negotiation, opportunistic encryption cannot be
+ secure without authentication. Opportunistic encryption relies on
+ DNS for its authentication information and, therefore, cannot be
+ fully secure without a secure DNS. Without secure DNS, opportunistic
+ encryption can protect against passive eavesdropping but not against
+ active man-in-the-middle attacks.
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 42]
+
+Internet-Draft opportunistic May 2003
+
+
+12.2 Firewalls versus Opportunistic Tunnels
+
+ Typical usage of per datagram access control lists is to implement
+ various kinds of security gateways. These are typically called
+ "firewalls".
+
+ Typical usage of a virtual private network (VPN) within a firewall is
+ to bypass all or part of the access controls between two networks.
+ Additional trust (as outlined in the previous section) is given to
+ datagrams that arrive in the VPN.
+
+ Datagrams that arrive via opportunistically configured tunnels MUST
+ not be trusted. Any security policy that would apply to a datagram
+ arriving in the clear SHOULD also be applied to datagrams arriving
+ opportunistically.
+
+12.3 Denial of service
+
+ There are several different forms of denial of service that an
+ implementor should concern themselves with. Most of these problems
+ are shared with security gateways that have large numbers of mobile
+ peers (road warriors).
+
+ The design of ISAKMP/IKE, and its use of cookies, defend against many
+ kinds of denial of service. Opportunism changes the assumption that
+ if the phase 1 (ISAKMP) SA is authenticated, that it was worthwhile
+ creating. Because the gateway will communicate with any machine, it
+ is possible to form phase 1 SAs with any machine on the Internet.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 43]
+
+Internet-Draft opportunistic May 2003
+
+
+13. IANA Considerations
+
+ There are no known numbers which IANA will need to manage.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 44]
+
+Internet-Draft opportunistic May 2003
+
+
+14. Acknowledgments
+
+ Substantive portions of this document are based upon previous work by
+ Henry Spencer.
+
+ Thanks to Tero Kivinen, Sandy Harris, Wes Hardarker, Robert
+ Moskowitz, Jakob Schlyter, Bill Sommerfeld, John Gilmore and John
+ Denker for their comments and constructive criticism.
+
+ Sandra Hoffman and Bill Dickie did the detailed proof reading and
+ editing.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 45]
+
+Internet-Draft opportunistic May 2003
+
+
+Normative references
+
+ [1] Redelmeier, D. and H. Spencer, "Opportunistic Encryption",
+ paper http://www.freeswan.org/freeswan_trees/freeswan-1.91/doc/
+ opportunism.spec, May 2001.
+
+ [2] Defense Advanced Research Projects Agency (DARPA), Information
+ Processing Techniques Office and University of Southern
+ California (USC)/Information Sciences Institute, "Internet
+ Protocol", STD 5, RFC 791, September 1981.
+
+ [3] Braden, R. and J. Postel, "Requirements for Internet gateways",
+ RFC 1009, June 1987.
+
+ [4] IAB, IESG, Carpenter, B. and F. Baker, "IAB and IESG Statement
+ on Cryptographic Technology and the Internet", RFC 1984, August
+ 1996.
+
+ [5] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [6] McDonald, D., Metz, C. and B. Phan, "PF_KEY Key Management API,
+ Version 2", RFC 2367, July 1998.
+
+ [7] Kent, S. and R. Atkinson, "Security Architecture for the
+ Internet Protocol", RFC 2401, November 1998.
+
+ [8] Piper, D., "The Internet IP Security Domain of Interpretation
+ for ISAKMP", RFC 2407, November 1998.
+
+ [9] Maughan, D., Schneider, M. and M. Schertler, "Internet Security
+ Association and Key Management Protocol (ISAKMP)", RFC 2408,
+ November 1998.
+
+ [10] Harkins, D. and D. Carrel, "The Internet Key Exchange (IKE)",
+ RFC 2409, November 1998.
+
+ [11] Kivinen, T. and M. Kojo, "More MODP Diffie-Hellman groups for
+ IKE", RFC 3526, March 2003.
+
+ [12] Mockapetris, P., "Domain names - concepts and facilities", STD
+ 13, RFC 1034, November 1987.
+
+ [13] Mockapetris, P., "Domain names - implementation and
+ specification", STD 13, RFC 1035, November 1987.
+
+ [14] Vixie, P., "Extension Mechanisms for DNS (EDNS0)", RFC 2671,
+ August 1999.
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 46]
+
+Internet-Draft opportunistic May 2003
+
+
+ [15] Rosenbaum, R., "Using the Domain Name System To Store Arbitrary
+ String Attributes", RFC 1464, May 1993.
+
+ [16] Eastlake, D., "Domain Name System Security Extensions", RFC
+ 2535, March 1999.
+
+ [17] Eastlake, D., "RSA/SHA-1 SIGs and RSA KEYs in the Domain Name
+ System (DNS)", RFC 3110, May 2001.
+
+ [18] Eastlake, D. and O. Gudmundsson, "Storing Certificates in the
+ Domain Name System (DNS)", RFC 2538, March 1999.
+
+ [19] Durham, D., Boyle, J., Cohen, R., Herzog, S., Rajan, R. and A.
+ Sastry, "The COPS (Common Open Policy Service) Protocol", RFC
+ 2748, January 2000.
+
+ [20] Srisuresh, P. and M. Holdrege, "IP Network Address Translator
+ (NAT) Terminology and Considerations", RFC 2663, August 1999.
+
+
+Authors' Addresses
+
+ Michael C. Richardson
+ Sandelman Software Works
+ 470 Dawson Avenue
+ Ottawa, ON K1Z 5V7
+ CA
+
+ EMail: mcr@sandelman.ottawa.on.ca
+ URI: http://www.sandelman.ottawa.on.ca/
+
+
+ D. Hugh Redelmeier
+ Mimosa
+ Toronto, ON
+ CA
+
+ EMail: hugh@mimosa.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 47]
+
+Internet-Draft opportunistic May 2003
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2003). 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.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson & Redelmeier Expires November 19, 2003 [Page 48]
+
diff --git a/doc/draft-richardson-ipsec-rr.txt b/doc/draft-richardson-ipsec-rr.txt
new file mode 100644
index 000000000..7c229b8e1
--- /dev/null
+++ b/doc/draft-richardson-ipsec-rr.txt
@@ -0,0 +1,840 @@
+
+
+IPSECKEY WG M. Richardson
+Internet-Draft SSW
+Expires: March 4, 2004 September 4, 2003
+
+
+ A method for storing IPsec keying material in DNS.
+ draft-ietf-ipseckey-rr-07.txt
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of RFC2026.
+
+ Internet-Drafts are working documents of the Internet Engineering
+ Task Force (IETF), its areas, and its working groups. Note that
+ other groups may also distribute working documents as Internet-
+ Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress."
+
+ The list of current Internet-Drafts can be accessed at http://
+ www.ietf.org/ietf/1id-abstracts.txt.
+
+ The list of Internet-Draft Shadow Directories can be accessed at
+ http://www.ietf.org/shadow.html.
+
+ This Internet-Draft will expire on March 4, 2004.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+Abstract
+
+ This document describes a new resource record for DNS. This record
+ may be used to store public keys for use in IPsec systems.
+
+ This record replaces the functionality of the sub-type #1 of the KEY
+ Resource Record, which has been obsoleted by RFC3445.
+
+
+
+
+
+
+
+
+
+
+Richardson Expires March 4, 2004 [Page 1]
+
+Internet-Draft ipsecrr September 2003
+
+
+Table of Contents
+
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 1.2 Usage Criteria . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 2. Storage formats . . . . . . . . . . . . . . . . . . . . . . . 4
+ 2.1 IPSECKEY RDATA format . . . . . . . . . . . . . . . . . . . . 4
+ 2.2 RDATA format - precedence . . . . . . . . . . . . . . . . . . 4
+ 2.3 RDATA format - algorithm type . . . . . . . . . . . . . . . . 4
+ 2.4 RDATA format - gateway type . . . . . . . . . . . . . . . . . 4
+ 2.5 RDATA format - gateway . . . . . . . . . . . . . . . . . . . . 5
+ 2.6 RDATA format - public keys . . . . . . . . . . . . . . . . . . 5
+ 3. Presentation formats . . . . . . . . . . . . . . . . . . . . . 7
+ 3.1 Representation of IPSECKEY RRs . . . . . . . . . . . . . . . . 7
+ 3.2 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
+ 4. Security Considerations . . . . . . . . . . . . . . . . . . . 9
+ 4.1 Active attacks against unsecured IPSECKEY resource records . . 9
+ 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 11
+ 6. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 12
+ Normative references . . . . . . . . . . . . . . . . . . . . . 13
+ Non-normative references . . . . . . . . . . . . . . . . . . . 14
+ Author's Address . . . . . . . . . . . . . . . . . . . . . . . 14
+ Full Copyright Statement . . . . . . . . . . . . . . . . . . . 15
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson Expires March 4, 2004 [Page 2]
+
+Internet-Draft ipsecrr September 2003
+
+
+1. Introduction
+
+ The type number for the IPSECKEY RR is TBD.
+
+1.1 Overview
+
+ The IPSECKEY resource record (RR) is used to publish a public key
+ that is to be associated with a Domain Name System (DNS) name for use
+ with the IPsec protocol suite. This can be the public key of a
+ host, network, or application (in the case of per-port keying).
+
+ 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 RFC2119 [8].
+
+1.2 Usage Criteria
+
+ An IPSECKEY resource record SHOULD be used in combination with DNSSEC
+ unless some other means of authenticating the IPSECKEY resource
+ record is available.
+
+ It is expected that there will often be multiple IPSECKEY resource
+ records at the same name. This will be due to the presence of
+ multiple gateways and the need to rollover keys.
+
+ This resource record is class independent.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson Expires March 4, 2004 [Page 3]
+
+Internet-Draft ipsecrr September 2003
+
+
+2. Storage formats
+
+2.1 IPSECKEY RDATA format
+
+ The RDATA for an IPSECKEY RR consists of a precedence value, a public
+ key, algorithm type, and an optional gateway address.
+
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | precedence | gateway type | algorithm | gateway |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------+ +
+ ~ gateway ~
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | /
+ / public key /
+ / /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
+
+
+2.2 RDATA format - precedence
+
+ This is an 8-bit precedence for this record. This is interpreted in
+ the same way as the PREFERENCE field described in section 3.3.9 of
+ RFC1035 [2].
+
+ Gateways listed in IPSECKEY records with lower precedence are to be
+ attempted first. Where there is a tie in precedence, the order
+ should be non-deterministic.
+
+2.3 RDATA format - algorithm type
+
+ The algorithm type field identifies the public key's cryptographic
+ algorithm and determines the format of the public key field.
+
+ A value of 0 indicates that no key is present.
+
+ The following values are defined:
+
+ 1 A DSA key is present, in the format defined in RFC2536 [11]
+
+ 2 A RSA key is present, in the format defined in RFC3110 [12]
+
+
+2.4 RDATA format - gateway type
+
+ The gateway type field indicates the format of the information that
+ is stored in the gateway field.
+
+
+
+Richardson Expires March 4, 2004 [Page 4]
+
+Internet-Draft ipsecrr September 2003
+
+
+ The following values are defined:
+
+ 0 No gateway is present
+
+ 1 A 4-byte IPv4 address is present
+
+ 2 A 16-byte IPv6 address is present
+
+ 3 A wire-encoded domain name is present. The wire-encoded format is
+ self-describing, so the length is implicit. The domain name MUST
+ NOT be compressed.
+
+
+2.5 RDATA format - gateway
+
+ The gateway field indicates a gateway to which an IPsec tunnel may be
+ created in order to reach the entity named by this resource record.
+
+ There are three formats:
+
+ A 32-bit IPv4 address is present in the gateway field. The data
+ portion is an IPv4 address as described in section 3.4.1 of RFC1035
+ [2]. This is a 32-bit number in network byte order.
+
+ A 128-bit IPv6 address is present in the gateway field. The data
+ portion is an IPv6 address as described in section 2.2 of RFC1886
+ [7]. This is a 128-bit number in network byte order.
+
+ The gateway field is a normal wire-encoded domain name, as described
+ in section 3.3 of RFC1035 [2]. Compression MUST NOT be used.
+
+2.6 RDATA format - public keys
+
+ Both of the public key types defined in this document (RSA and DSA)
+ inherit their public key formats from the corresponding KEY RR
+ formats. Specifically, the public key field contains the algorithm-
+ specific portion of the KEY RR RDATA, which is all of the KEY RR DATA
+ after the first four octets. This is the same portion of the KEY RR
+ that must be specified by documents that define a DNSSEC algorithm.
+ Those documents also specify a message digest to be used for
+ generation of SIG RRs; that specification is not relevant for
+ IPSECKEY RR.
+
+ Future algorithms, if they are to be used by both DNSSEC (in the KEY
+ RR) and IPSECKEY, are likely to use the same public key encodings in
+ both records. Unless otherwise specified, the IPSECKEY public key
+ field will contain the algorithm-specific portion of the KEY RR RDATA
+ for the corresponding algorithm. The algorithm must still be
+
+
+
+Richardson Expires March 4, 2004 [Page 5]
+
+Internet-Draft ipsecrr September 2003
+
+
+ designated for use by IPSECKEY, and an IPSECKEY algorithm type number
+ (which might be different than the DNSSEC algorithm number) must be
+ assigned to it.
+
+ The DSA key format is defined in RFC2536 [11]
+
+ The RSA key format is defined in RFC3110 [12], with the following
+ changes:
+
+ The earlier definition of RSA/MD5 in RFC2065 limited the exponent and
+ modulus to 2552 bits in length. RFC3110 extended that limit to 4096
+ bits for RSA/SHA1 keys. The IPSECKEY RR imposes no length limit on
+ RSA public keys, other than the 65535 octet limit imposed by the two-
+ octet length encoding. This length extension is applicable only to
+ IPSECKEY and not to KEY RRs.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson Expires March 4, 2004 [Page 6]
+
+Internet-Draft ipsecrr September 2003
+
+
+3. Presentation formats
+
+3.1 Representation of IPSECKEY RRs
+
+ IPSECKEY RRs may appear in a zone data master file. The precedence,
+ gateway type and algorithm and gateway fields are REQUIRED. The
+ base64 encoded public key block is OPTIONAL; if not present, then the
+ public key field of the resource record MUST be construed as being
+ zero octets in length.
+
+ The algorithm field is an unsigned integer. No mnemonics are
+ defined.
+
+ If no gateway is to be indicated, then the gateway type field MUST be
+ zero, and the gateway field MUST be "."
+
+ The Public Key field is represented as a Base64 encoding of the
+ Public Key. Whitespace is allowed within the Base64 text. For a
+ definition of Base64 encoding, see RFC1521 [3] Section 5.2.
+
+ The general presentation for the record as as follows:
+
+ IN IPSECKEY ( precedence gateway-type algorithm
+ gateway base64-encoded-public-key )
+
+
+3.2 Examples
+
+ An example of a node 192.0.2.38 that will accept IPsec tunnels on its
+ own behalf.
+
+ 38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2
+ 192.0.2.38
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+
+ An example of a node, 192.0.2.38 that has published its key only.
+
+ 38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 0 2
+ .
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+
+ An example of a node, 192.0.2.38 that has delegated authority to the
+ node 192.0.2.3.
+
+ 38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2
+ 192.0.2.3
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+
+
+
+
+Richardson Expires March 4, 2004 [Page 7]
+
+Internet-Draft ipsecrr September 2003
+
+
+ An example of a node, 192.0.1.38 that has delegated authority to the
+ node with the identity "mygateway.example.com".
+
+ 38.1.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 3 2
+ mygateway.example.com.
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+
+ An example of a node, 2001:0DB8:0200:1:210:f3ff:fe03:4d0 that has
+ delegated authority to the node 2001:0DB8:c000:0200:2::1
+
+ $ORIGIN 1.0.0.0.0.0.2.8.B.D.0.1.0.0.2.ip6.int.
+ 0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0 7200 IN IPSECKEY ( 10 2 2
+ 2001:0DB8:0:8002::2000:1
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson Expires March 4, 2004 [Page 8]
+
+Internet-Draft ipsecrr September 2003
+
+
+4. Security Considerations
+
+ This entire memo pertains to the provision of public keying material
+ for use by key management protocols such as ISAKMP/IKE (RFC2407) [9].
+
+ The IPSECKEY resource record contains information that SHOULD be
+ communicated to the end client in an integral fashion - i.e. free
+ from modification. The form of this channel is up to the consumer of
+ the data - there must be a trust relationship between the end
+ consumer of this resource record and the server. This relationship
+ may be end-to-end DNSSEC validation, a TSIG or SIG(0) channel to
+ another secure source, a secure local channel on the host, or some
+ combination of the above.
+
+ The keying material provided by the IPSECKEY resource record is not
+ sensitive to passive attacks. The keying material may be freely
+ disclosed to any party without any impact on the security properties
+ of the resulting IPsec session: IPsec and IKE provide for defense
+ against both active and passive attacks.
+
+ Any user of this resource record MUST carefully document their trust
+ model, and why the trust model of DNSSEC is appropriate, if that is
+ the secure channel used.
+
+4.1 Active attacks against unsecured IPSECKEY resource records
+
+ This section deals with active attacks against the DNS. These
+ attacks require that DNS requests and responses be intercepted and
+ changed. DNSSEC is designed to defend against attacks of this kind.
+
+ The first kind of active attack is when the attacker replaces the
+ keying material with either a key under its control or with garbage.
+
+ If the attacker is not able to mount a subsequent man-in-the-middle
+ attack on the IKE negotiation after replacing the public key, then
+ this will result in a denial of service, as the authenticator used by
+ IKE would fail.
+
+ If the attacker is able to both to mount active attacks against DNS
+ and is also in a position to perform a man-in-the-middle attack on
+ IKE and IPsec negotiations, then the attacker will be in a position
+ to compromise the resulting IPsec channel. Note that an attacker
+ must be able to perform active DNS attacks on both sides of the IKE
+ negotiation in order for this to succeed.
+
+ The second kind of active attack is one in which the attacker
+ replaces the the gateway address to point to a node under the
+ attacker's control. The attacker can then either replace the public
+
+
+
+Richardson Expires March 4, 2004 [Page 9]
+
+Internet-Draft ipsecrr September 2003
+
+
+ key or remove it, thus providing an IPSECKEY record of its own to
+ match the gateway address.
+
+ This later form creates a simple man-in-the-middle since the attacker
+ can then create a second tunnel to the real destination. Note that,
+ as before, this requires that the attacker also mount an active
+ attack against the responder.
+
+ Note that the man-in-the-middle can not just forward cleartext
+ packets to the original destination. While the destination may be
+ willing to speak in the clear, replying to the original sender, the
+ sender will have already created a policy expecting ciphertext.
+ Thus, the attacker will need to intercept traffic from both sides.
+ In some cases, the attacker may be able to accomplish the full
+ intercept by use of Network Addresss/Port Translation (NAT/NAPT)
+ technology.
+
+ Note that the danger here only applies to cases where the gateway
+ field of the IPSECKEY RR indicates a different entity than the owner
+ name of the IPSECKEY RR. In cases where the end-to-end integrity of
+ the IPSECKEY RR is suspect, the end client MUST restrict its use of
+ the IPSECKEY RR to cases where the RR owner name matches the content
+ of the gateway field.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson Expires March 4, 2004 [Page 10]
+
+Internet-Draft ipsecrr September 2003
+
+
+5. IANA Considerations
+
+ This document updates the IANA Registry for DNS Resource Record Types
+ by assigning type X to the IPSECKEY record.
+
+ This document creates an IANA registry for the algorithm type field.
+
+ Values 0, 1 and 2 are defined in Section 2.3. Algorithm numbers 3
+ through 255 can be assigned by IETF Consensus (see RFC2434 [6]).
+
+ This document creates an IANA registry for the gateway type field.
+
+ Values 0, 1, 2 and 3 are defined in Section 2.4. Algorithm numbers 4
+ through 255 can be assigned by Standards Action (see RFC2434 [6]).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson Expires March 4, 2004 [Page 11]
+
+Internet-Draft ipsecrr September 2003
+
+
+6. Acknowledgments
+
+ My thanks to Paul Hoffman, Sam Weiler, Jean-Jacques Puig, Rob
+ Austein, and Olafur Gurmundsson who reviewed this document carefully.
+ Additional thanks to Olafur Gurmundsson for a reference
+ implementation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson Expires March 4, 2004 [Page 12]
+
+Internet-Draft ipsecrr September 2003
+
+
+Normative references
+
+ [1] Mockapetris, P., "Domain names - concepts and facilities", STD
+ 13, RFC 1034, November 1987.
+
+ [2] Mockapetris, P., "Domain names - implementation and
+ specification", STD 13, RFC 1035, November 1987.
+
+ [3] Borenstein, N. and N. Freed, "MIME (Multipurpose Internet Mail
+ Extensions) Part One: Mechanisms for Specifying and Describing
+ the Format of Internet Message Bodies", RFC 1521, September
+ 1993.
+
+ [4] Bradner, S., "The Internet Standards Process -- Revision 3", BCP
+ 9, RFC 2026, October 1996.
+
+ [5] Eastlake, D. and C. Kaufman, "Domain Name System Security
+ Extensions", RFC 2065, January 1997.
+
+ [6] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA
+ Considerations Section in RFCs", BCP 26, RFC 2434, October 1998.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson Expires March 4, 2004 [Page 13]
+
+Internet-Draft ipsecrr September 2003
+
+
+Non-normative references
+
+ [7] Thomson, S. and C. Huitema, "DNS Extensions to support IP
+ version 6", RFC 1886, December 1995.
+
+ [8] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [9] Piper, D., "The Internet IP Security Domain of Interpretation
+ for ISAKMP", RFC 2407, November 1998.
+
+ [10] Eastlake, D., "Domain Name System Security Extensions", RFC
+ 2535, March 1999.
+
+ [11] Eastlake, D., "DSA KEYs and SIGs in the Domain Name System
+ (DNS)", RFC 2536, March 1999.
+
+ [12] Eastlake, D., "RSA/SHA-1 SIGs and RSA KEYs in the Domain Name
+ System (DNS)", RFC 3110, May 2001.
+
+ [13] Massey, D. and S. Rose, "Limiting the Scope of the KEY Resource
+ Record (RR)", RFC 3445, December 2002.
+
+
+Author's Address
+
+ Michael C. Richardson
+ Sandelman Software Works
+ 470 Dawson Avenue
+ Ottawa, ON K1Z 5V7
+ CA
+
+ EMail: mcr@sandelman.ottawa.on.ca
+ URI: http://www.sandelman.ottawa.on.ca/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson Expires March 4, 2004 [Page 14]
+
+Internet-Draft ipsecrr September 2003
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2003). 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.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Richardson Expires March 4, 2004 [Page 15]
+
diff --git a/doc/draft-spencer-ipsec-ike-implementation.nr b/doc/draft-spencer-ipsec-ike-implementation.nr
new file mode 100644
index 000000000..5b5776e22
--- /dev/null
+++ b/doc/draft-spencer-ipsec-ike-implementation.nr
@@ -0,0 +1,1203 @@
+.\" date, expiry date, copyright year, and revision
+.DA "26 Feb 2002"
+.ds e "26 Aug 2002
+.ds c 2002
+.ds r 02
+.\" boilerplate
+.pl 10i
+.nr PL 10i
+.po 0
+.nr PO 0
+.ll 7.2i
+.nr LL 7.2i
+.lt 7.2i
+.nr LT 7.2i
+.hy 0
+.nr HY 0
+.ad l
+.nr PD 1v
+.\" macros for paragraph, section header, reference, TOC
+.de P
+.br
+.LP
+.in 3
+..
+.de H
+.br
+.ne 5
+.LP
+.in 0
+..
+.de R
+.IP " [\\$1]" 14
+..
+.de T
+.ie \\$1=1 \{\
+.nf
+.ta \n(LLu-3nR
+.\}
+.el \{\
+.fi
+.\}
+..
+.de S
+.ie '\\$1'' \\$2 \a \\$3
+.el \\$1. \\$2 \a \\$3
+..
+.\" headers/footers
+.ds LH "Internet Draft
+.ds CH "IKE Implementation Issues
+.ds RH "\*(DY
+.ds LF "Spencer & Redelmeier
+.ds CF "
+.ds RF "[Page %]
+.\" and let's get started
+.RT
+.nf
+.tl 'Network Working Group''Henry Spencer'
+.tl 'Internet Draft''SP Systems'
+.tl 'Expires: \*e''D. Hugh Redelmeier'
+.tl '''Mimosa Systems'
+.tl '''\*(DY'
+.sp
+.ce 99
+IKE Implementation Issues
+<draft-spencer-ipsec-ike-implementation-\*r.txt>
+.ce 0
+.H
+Status of this Memo
+.P
+This document is an Internet-Draft and is in full conformance with
+all provisions of Section 10 of RFC2026.
+.P
+(If approved as an Informational RFC...)
+This memo provides information for the Internet community.
+This memo does not specify an Internet standard of any kind.
+.P
+Distribution of this memo is unlimited.
+.P
+Internet-Drafts are working documents of the Internet Engineering
+Task Force (IETF), its areas, and its working groups.
+Note that
+other groups may also distribute working documents as Internet-Drafts.
+.P
+Internet-Drafts are draft documents valid for a maximum of six months
+and may be updated, replaced, or obsoleted by other documents at any
+time.
+It is inappropriate to use Internet-Drafts as reference
+material or to cite them other than as "work in progress."
+.P
+The list of current Internet-Drafts can be accessed at
+http://www.ietf.org/ietf/1id-abstracts.txt.
+.P
+The list of Internet-Draft Shadow Directories can be accessed at
+http://www.ietf.org/shadow.html.
+.P
+This Internet-Draft will expire on \*e.
+.H
+Copyright Notice
+.P
+Copyright (C) The Internet Society \*c. All Rights Reserved.
+.bp
+.H
+Table of Contents
+.P
+.T 1
+.S "1" "Introduction" "3"
+.S "2" "Lower-level Background and Notes" "4"
+.S "2.1" "Packet Handling" "4"
+.S "2.2" "Ciphers" "5"
+.S "2.3" "Interfaces" "5"
+.S "3" "IKE Infrastructural Issues" "5"
+.S "3.1" "Continuous Channel" "5"
+.S "3.2" "Retransmission" "5"
+.S "3.3" "Replay Prevention" "6"
+.S "4" "Basic Keying and Rekeying" "7"
+.S "4.1" "When to Create SAs" "7"
+.S "4.2" "When to Rekey" "8"
+.S "4.3" "Choosing an SA" "9"
+.S "4.4" "Why to Rekey" "9"
+.S "4.5" "Rekeying ISAKMP SAs" "10"
+.S "4.6" "Bulk Negotiation" "10"
+.S "5" "Deletions, Teardowns, Crashes" "11"
+.S "5.1" "Deletions" "11"
+.S "5.2" "Teardowns and Shutdowns" "12"
+.S "5.3" "Crashes" "13"
+.S "5.4" "Network Partitions" "13"
+.S "5.5" "Unknown SAs" "14"
+.S "6" "Misc. IKE Issues" "16"
+.S "6.1" "Groups 1 and 5" "16"
+.S "6.2" "To PFS Or Not To PFS" "16"
+.S "6.3" "Debugging Tools, Lack Thereof" "16"
+.S "6.4" "Terminology, Vagueness Thereof" "17"
+.S "6.5" "A Question of Identity" "17"
+.S "6.6" "Opportunistic Encryption" "17"
+.S "6.7" "Authentication and RSA Keys" "17"
+.S "6.8" "Misc. Snags" "18"
+.S "7" "Security Considerations" "19"
+.S "8" "References" "19"
+.S "" "Authors' Addresses" "20"
+.S "" "Full Copyright Statement" "21"
+.T 0
+.bp
+.H
+Abstract
+.P
+The current IPsec specifications for key exchange and connection management,
+RFCs 2408 [ISAKMP] and 2409 [IKE],
+leave many aspects of connection management unspecified,
+most prominently rekeying practices.
+Pending clarifications in future revisions of the specifications,
+this document sets down some successful experiences,
+to minimize the extent to which new implementors have to rely
+on unwritten folklore.
+.P
+The Linux FreeS/WAN implementation of IPsec interoperates
+with almost every other IPsec implementation.
+This document describes how the FreeS/WAN project has resolved
+some of the gaps in the IPsec specifications
+(and plans to resolve some others),
+and what difficulties have been encountered,
+in hopes that this generally-successful experience
+might be informative to new implementors.
+.P
+This is offered as an Informational RFC.
+.P
+This -\*r revision mainly:
+discusses ISAKMP SA expiry during IPsec-SA rekeying (4.5),
+revises the discussion of bidirectional Deletes (5.1),
+suggests remembering the parameters of successful negotiations
+for later use (4.2, 5.3),
+notes an unsuccessful negotiation from the other end as a hint of a possibly
+broken connection (5.5),
+and adds sections on network partitions (5.4),
+authentication methods and the subtleties of RSA public keys (6.7),
+and miscellaneous interoperability concerns (6.8).
+.H
+1. Introduction
+.P
+The current IPsec specifications for key exchange and connection management,
+RFCs 2408 [ISAKMP] and 2409 [IKE],
+leave many aspects of connection management unspecified,
+most prominently rekeying practices.
+This is a cryptic puzzle which
+each group of implementors has to struggle with,
+and differences in how the ambiguities and gaps are resolved are
+potentially a fruitful source of interoperability problems.
+We can hope that future revisions of the specifications will clear this up.
+Meanwhile, it seems useful to set down some successful experiences,
+to minimize the extent to which new implementors have to rely
+on unwritten folklore.
+.P
+The Linux FreeS/WAN implementation of IPsec interoperates
+with almost every other IPsec implementation,
+and because of its free nature,
+it also sees some use as a reference implementation by other implementors.
+The high degree of interoperability is noteworthy
+given its organizers' strong minimalist bias,
+which has caused them to implement only
+a small subset of the full glory of IPsec.
+This document describes how the FreeS/WAN project has resolved
+some of the gaps in the IPsec specifications
+(and plans to resolve some others),
+and what difficulties have been encountered,
+in hopes that this generally-successful experience
+might be informative to new implementors.
+.P
+One small caution about applicability:
+this experience may not be relevant
+to severely resource-constrained implementations.
+FreeS/WAN's target environment is previous-generation PCs,
+now available at trivial cost (often,
+within an organization, at no cost),
+which have quite impressive CPU power and memory by the standards
+of only a few years ago.
+Some of the approaches discussed here may be inapplicable to
+implementations with severe external constraints which prevent them
+from taking advantage of modern hardware technology.
+.H
+2. Lower-level Background and Notes
+.H
+2.1. Packet Handling
+.P
+FreeS/WAN implements ESP [ESP] and AH [AH] straightforwardly,
+although AH sees little use among our users.
+Our ESP/AH implementation cannot currently handle packets
+with IP options;
+somewhat surprisingly, this has caused little difficulty.
+We insist on encryption and do not support authentication-only
+connections, and this has not caused significant difficulty either.
+.P
+MTU and fragmentation issues, by contrast, have been a constant headache.
+We will not describe the details of our current approach to them,
+because it still needs work.
+One difficulty we have encountered is that many combinations of
+packet source and packet destination
+apparently cannot cope with an "interior minimum" in the path MTU,
+e.g. where an IPsec tunnel intervenes and its headers reduce the MTU
+for an intermediate link.
+This is particularly prevalent when using common PC software to
+connect to large well-known web sites;
+we think it is largely due to
+misconfigured firewalls which do not pass ICMP
+Fragmentation Required messages.
+The only solution we have yet found is to lie about the MTU of the tunnel,
+accepting the (undesirable) fragmentation of the ESP packets
+for the sake of preserving connectivity.
+.P
+We currently zero out the TOS field of ESP packets,
+rather than copying it from the inner header,
+on the grounds that it lends itself too well to traffic analysis
+and covert channels.
+We provide an option to restore RFC 2401 [IPSEC] copying behavior,
+but this appears to see little use.
+.H
+2.2. Ciphers
+.P
+We initially implemented both DES [DES] and 3DES [CIPHERS] for both
+IKE and ESP,
+but after the Deep Crack effort [CRACK] demonstrated its inherent insecurity,
+we dropped support for DES.
+Somewhat surprisingly,
+our insistence on 3DES has caused almost no interoperability problems,
+despite DES being officially mandatory.
+A very few other systems either do not support 3DES or support it only
+as an optional upgrade,
+which inconveniences a few would-be users.
+There have also been one or two cases of systems
+which don't quite seem to know the difference!
+.P
+See also section 6.1 for a consequence of our insistence on 3DES.
+.H
+2.3. Interfaces
+.P
+We currently employ PF_KEY version 2 [PFKEY],
+plus various non-standard extensions,
+as our interface between keying and ESP.
+This has not proven entirely satisfactory.
+Our feeling now is that keying issues and policy issues
+do not really lend
+themselves to the clean separation that PF_KEY envisions.
+.H
+3. IKE Infrastructural Issues
+.P
+A number of problems in IPsec connection management become easier if
+some attention is first paid to providing an infrastructure
+to support solving them.
+.H
+3.1. Continuous Channel
+.P
+FreeS/WAN uses an approximation to the "continuous channel" model,
+in which ISAKMP SAs are maintained between IKEs
+so long as any IPsec SAs are open between the two systems.
+The resource consumption of this is minor:
+the only substantial overhead is occasional rekeying.
+IPsec SA management becomes significantly simpler if there is always
+a channel for transmission of control messages.
+We suggest (although we do not yet fully implement this) that
+inability to maintain (e.g., to rekey) this control path
+should be grounds for tearing down the IPsec SAs as well.
+.P
+As a corollary of this,
+there is one and only one ISAKMP SA maintained between a pair of IKEs
+(although see sections 5.3 and 6.5 for minor complications).
+.H
+3.2. Retransmission
+.P
+The unreliable nature of UDP transmission is a nuisance.
+IKE implementations should always be prepared to retransmit the most recent
+message they sent on an ISAKMP SA,
+since there is some possibility that the other end did not get it.
+This means, in particular,
+that the system sending the supposedly-last message of an exchange
+cannot relax and assume that the exchange is complete,
+at least not until a significant timeout has elapsed.
+.P
+Systems must also retain information about the message most recently received
+in an exchange,
+so that a duplicate of it can be detected
+(and possibly interpreted as a NACK for the response).
+.P
+The retransmission rules FreeS/WAN follows are:
+(1) if a reply is expected, retransmit only if it does not appear
+before a timeout;
+and (2) if a reply is not expected (last message of the exchange),
+retransmit only on receiving a retransmission of the previous message.
+Notably, in case (1) we do NOT retransmit on receiving a retransmission,
+which avoids possible congestion problems arising from packet duplication,
+at the price of slowing response to packet loss.
+The timeout for case (1) is 10 seconds for the first retry,
+20 seconds for the second, and 40 seconds for all subsequent
+retries (normally only one,
+except when
+configuration settings call for persistence and the message is
+the first message of Main Mode with a new peer).
+These retransmission rules have been entirely successful.
+.P
+(Michael Thomas of Cisco has pointed out that the retry timeouts should
+include some random jitter, to de-synchronize hosts which are
+initially synchronized by, e.g., a power outage.
+We already jitter our rekeying times,
+as noted in section 4.2,
+but that does not help with initial startup.
+We're implementing jittered retries,
+but cannot yet report on experience with this.)
+.P
+There is a deeper problem, of course, when an entire "exchange" consists
+of a single message,
+e.g. the ISAKMP Informational Exchange.
+Then there is no way to decide whether or when a retransmission is
+warranted at all.
+This seems like poor design, to put it mildly
+(and there is now talk of fixing it).
+We have no experience in dealing with this problem at this time,
+although it is part of the reason why we have delayed implementing
+Notification messages.
+.H
+3.3. Replay Prevention
+.P
+The unsequenced nature of UDP transmission is also troublesome,
+because it means that higher levels must consider the possibility
+of replay attacks.
+FreeS/WAN takes the position that systematically eliminating this
+possibility at a low level is strongly preferable to forcing careful
+consideration of possible impacts at every step of an exchange.
+RFC 2408 [ISAKMP] section 3.1 states that the Message ID of an
+ISAKMP message must be "unique".
+FreeS/WAN interprets this literally,
+as forbidding duplication of Message IDs
+within the set of all messages sent via a single ISAKMP SA.
+.P
+This requires remembering all Message IDs until the ISAKMP SA is
+superseded by rekeying,
+but that is not costly (four bytes per sent or received message),
+and it ELIMINATES replay attacks from consideration;
+we believe this investment of resources is well worthwhile.
+If the resource consumption becomes excessive\(emin our experience
+it has not\(emthe ISAKMP SA can be rekeyed early to collect the garbage.
+.P
+There is theoretically an interoperability problem when talking to
+implementations which interpret "unique" more loosely
+and may re-use Message IDs,
+but it has not been encountered in practice.
+This approach appears to be completely interoperable.
+.P
+The proposal by
+Andrew Krywaniuk [REPLAY],
+which advocates turning the Message ID into an anti-replay counter,
+would achieve the same goal without the minor per-message memory overhead.
+This may be preferable,
+although it means an actual protocol change and more study is needed.
+.H
+4. Basic Keying and Rekeying
+.H
+4.1. When to Create SAs
+.P
+As Tim Jenkins [REKEY] pointed out,
+there is a potential race condition in Quick Mode:
+a fast lightly-loaded Initiator might start using IPsec SAs very
+shortly after sending QM3 (the third and last message of Quick Mode),
+while a slow heavily-loaded Responder might
+not be ready to receive them until after spending
+a significant amount of time creating its inbound SAs.
+The problem is even worse if QM3 gets delayed or lost.
+.P
+FreeS/WAN's approach to this is what Jenkins called "Responder Pre-Setup":
+the Responder creates its inbound IPsec SAs before it sends QM2,
+so they are always ready and waiting
+when the Initiator sends QM3 and begins sending traffic.
+This approach is simple and reliable,
+and in our experience it interoperates with everybody.
+(There is potentially still a problem if FreeS/WAN is the Initiator
+and the Responder does not use Responder Pre-Setup,
+but no such problems have been seen.)
+The only real weakness of Responder Pre-Setup
+is the possibility of replay attacks,
+which we have eliminated by other means (see section 3.3).
+.P
+With this approach, the Commit Bit is useless,
+and we ignore it.
+In fact, until quite recently we discarded any IKE message containing it,
+and this caused surprisingly few interoperability problems;
+apparently it is not widely used.
+We have recently been persuaded that simply ignoring it is preferable;
+preliminary experience with this indicates that the result is successful
+interoperation with implementations which set it.
+.H
+4.2. When to Rekey
+.P
+To preserve connectivity for user traffic,
+rekeying of a connection
+(that is, creation of new IPsec SAs to supersede the current ones)
+must begin before its current IPsec SAs expire.
+Preferably one end should predictably start rekeying negotiations first,
+to avoid the extra overhead of two simultaneous negotiations,
+although either end should be prepared to rekey if the other does not.
+There is also a problem with "convoys" of keying negotiations:
+for example, a "hub" gateway with many IPsec connections
+can be inundated with rekeying negotiations
+exactly one connection-expiry time after it reboots,
+and the massive overload this induces tends to make this
+situation self-perpetuating,
+so it recurs regularly.
+(Convoys can also evolve gradually from initially-unsynchronized negotiations.)
+.P
+FreeS/WAN has the concept of a "rekeying margin", measured in seconds.
+If FreeS/WAN was the Initiator for the previous rekeying
+(or the startup, if none) of the connection,
+it nominally starts rekeying negotiations at expiry time
+minus one rekeying margin.
+Some random jitter is added to break up convoys:
+rather than starting rekeying exactly at minus one margin,
+it starts at a random time between minus one margin
+and minus two margins.
+(The randomness here need not be cryptographic in quality,
+so long as it varies over time and between hosts.
+We use an ordinary PRNG seeded with a few bytes from a cryptographic
+randomness source.
+The seeding mostly just ensures that the PRNG sequence is different
+for different hosts, even if they start up simultaneously.)
+.P
+If FreeS/WAN was the Responder for the previous rekeying/startup,
+and nothing has been heard from the previous Initiator
+at expiry time minus one-half the rekeying margin,
+FreeS/WAN will initiate rekeying negotiations.
+No jitter is applied;
+we now believe that it should be jittered,
+say between minus one-half margin and minus one-quarter margin.
+.P
+Having the Initiator lead the way is an obvious way of deciding
+who should speak first,
+since there is already an Initiator/Responder asymmetry in the connection.
+Moreover, our experience has been that Initiator lead gives a significantly
+higher probability of successful negotiation!
+The negotiation process itself is asymmetric,
+because the Initiator must make a few specific proposals which the Responder
+can only accept or reject,
+so the Initiator must try to guess where its "acceptable" region
+(in parameter space)
+might overlap with the Responder's.
+We have seen situations where negotiations would succeed or fail
+depending on which end initiated them,
+because one end was making better guesses.
+Given an existing connection,
+we KNOW that the previous Initiator WAS able to initiate a successful
+negotiation,
+so it should (if at all possible) take the lead again.
+Also, the Responder should remember the Initiator's successful proposal,
+and start from that
+rather than from his own default proposals if he must take the lead;
+we don't currently implement this completely but plan to.
+.P
+FreeS/WAN defaults the rekeying margin to 9 minutes,
+although this can be changed by configuration.
+There is also
+a configuration option to alter the permissible range of jitter.
+The defaults were chosen somewhat arbitrarily,
+but they work extremely well
+and the configuration options are rarely used.
+.H
+4.3. Choosing an SA
+.P
+Once rekeying has occurred,
+both old and new IPsec SAs for the connection exist,
+at least momentarily.
+FreeS/WAN accepts incoming traffic
+on either old or new inbound SAs,
+but sends outgoing traffic only on the new outbound ones.
+This approach appears to be significantly more robust than
+using the old ones until they expire,
+notably in cases where renegotiation has occurred because something has
+gone wrong on the other end.
+It avoids having to pay meticulous attention to the state of the other end,
+state which is difficult to learn reliably given the limitations of IKE.
+.P
+This approach has interoperated successfully with ALMOST all other
+implementations.
+The only (well-characterized) problem cases have been implementations
+which rely on receiving a Delete message for the old SAs to tell them
+to switch over to the new ones.
+Since delivery of Delete is unreliable,
+and support for Delete is optional,
+this reliance seems like a serious mistake.
+This is all the more true because Delete
+announces that the deletion has
+already occurred [ISAKMP, section 3.15], not that it is about to occur,
+so packets already in transit in the other direction could be lost.
+Delete should be used for resource cleanup, not for switchover control.
+(These matters are discussed further in section 5.)
+.H
+4.4. Why to Rekey
+.P
+FreeS/WAN currently implements only time-based expiry (life in seconds),
+although we are working toward
+supporting volume-based expiry (life in kilobytes) as well.
+The lack of volume-based expiry has not been an interoperability
+problem so far.
+.P
+Volume-based expiry does add some minor complications.
+In particular, it makes explicit Delete of now-disused SAs more important,
+because once an SA stops being used,
+it might not expire on its own.
+We believe this lacks robustness and is generally unwise,
+especially given the lack of a reliable Delete,
+and expect to use volume-based expiry only as a supplement
+to time-based expiry.
+However, Delete support (see section 5) does seem advisable
+for use with volume-based expiry.
+.P
+We do not believe that volume-based expiry alters the desirability
+of switching immediately to the new SAs after rekeying.
+Rekeying margins are normally a small fraction of the total life of an SA,
+so we feel there is no great need to "use it all up".
+.H
+4.5. Rekeying ISAKMP SAs
+.P
+The above discussion has focused on rekeying for IPsec SAs,
+but FreeS/WAN applies the same approaches to rekeying for ISAKMP SAs,
+with similar success.
+.P
+One issue which we have noticed, but not explicitly dealt with,
+is that difficulties may ensue if an IPsec-SA rekeying negotiation
+is in progress at the time when the relevant ISAKMP SA gets rekeyed.
+The IKE specification [IKE] hints, but does not actually say,
+that a Quick Mode negotiation should remain on a single ISAKMP SA throughout.
+.P
+A reasonable rekeying margin will generally
+prevent the old ISAKMP SA from actually expiring during a negotiation.
+Some attention may be needed to prevent in-progress negotiations from
+being switched to the new ISAKMP SA.
+Any attempt at pre-expiry deletion of the ISAKMP SA must be postponed
+until after such dangling negotiations are completed,
+and there should be enough delay between ISAKMP-SA rekeying and a
+deletion attempt to (more or less)
+ensure that there are no negotiation-starting packets still in transit
+from before the rekeying.
+.P
+At present, FreeS/WAN does none of this,
+and we don't KNOW of any resulting trouble.
+With normal lifetimes, the problem should be uncommon,
+and we speculate that an occasional disrupted negotiation simply gets retried.
+.H
+4.6. Bulk Negotiation
+.P
+Quick Mode nominally provides for negotiating possibly-large numbers of
+similar but unrelated IPsec SAs simultaneously
+[IKE, section 9].
+Nobody appears to do this.
+FreeS/WAN does not support it, and its absence has caused no problems.
+.H
+5. Deletions, Teardowns, Crashes
+.P
+FreeS/WAN currently ignores all Notifications and Deletes,
+and never generates them.
+This has caused little difficulty in interoperability,
+which shouldn't be surprising (since Notification and Delete support is
+officially entirely optional) but does seem to surprise some people.
+Nevertheless, we do plan some changes to this approach
+based on past experience.
+.H
+5.1. Deletions
+.P
+As hinted at above,
+we plan to implement Delete support, done as follows.
+Shortly after rekeying of IPsec SAs,
+the Responder issues a Delete for its old inbound SAs
+(but does not actually delete them yet).
+The Responder initiates this because the Initiator started using the
+new SAs on sending QM3, while the Responder started using them only
+on (or somewhat after) receiving QM3,
+so there is less chance of old-SA packets still being in transit from
+the Initiator.
+The Initiator issues an unsolicited Delete only if it does not hear one
+from the Responder after a longer delay.
+.P
+Either party, on receiving a Delete
+for one or more of the old outbound SAs of a connection,
+deletes ALL the connection's SAs,
+and acknowledges with a Delete for the old inbound SAs.
+A Delete for nonexistent SAs
+(e.g., SAs which have already been expired or deleted) is ignored.
+There is no retransmission of unacknowledged Deletes.
+.P
+In the normal case,
+with prompt reliable transmission (except possibly for loss of the
+Responder's initial Delete)
+and conforming implementations
+on both ends, this results in three Deletes being transmitted,
+resembling the classic three-way handshake.
+Loss of a Delete after the first, or multiple losses,
+will cause the SAs not to be deleted on at least one end.
+It appears difficult to do much better without at least
+a distinction between request and acknowledgement.
+.P
+RFC 2409 section 9 "strongly suggests" that there be no response to
+informational messages such as Deletes,
+but the only rationale offered is prevention of infinite loops
+endlessly exchanging "I don't understand you" informationals.
+Since Deletes cannot lead to such a loop
+(and in any case, the nonexistent-SA rule prevents more than one
+acknowledgement for the same connection),
+we believe this recommendation is inapplicable here.
+.P
+As noted in section 4.3, these Deletes are intended for
+resource cleanup, not to control switching between SAs.
+But we expect that they will improve interoperability
+with some broken implementations.
+.P
+We believe strongly that connections need to be considered as a whole,
+rather than treating each SA as an independent entity.
+We will issue Deletes only for the full set of inbound SAs of
+a connection,
+and will treat a Delete for any outbound SA as equivalent to deletion
+of all the outbound SAs for the associated connection.
+.P
+The above is phrased in terms of IPsec SAs,
+but essentially the same approach can be applied to ISAKMP SAs
+(the Deletes for the old ISAKMP SA should be sent via the new one).
+.H
+5.2. Teardowns and Shutdowns
+.P
+When a connection is not intended to be up permanently,
+there is a need to coordinate teardown,
+so that both ends are aware that the connection is down.
+This is both for recovery of resources,
+and to avoid routing packets through
+dangling SAs which can no longer deliver them.
+.P
+Connection teardown will use the same bidirectional exchange of Deletes
+as discussed in section 5.1:
+a Delete received for current IPsec SAs (not yet obsoleted by rekeying)
+indicates that the other host wishes to tear down the associated connection.
+.P
+A Delete received for a current ISAKMP SA indicates that the other host
+wishes to tear down not only the ISAKMP SA but also all IPsec SAs
+currently under the supervision of that ISAKMP SA.
+The 5.1 bidirectional exchange might seem impossible in this case,
+since reception of an ISAKMP-SA Delete indicates that the other end
+will ignore further traffic on that ISAKMP SA.
+We suggest using the same tactic discussed in 5.1 for IPsec SAs:
+the first Delete is sent without actually doing the deletion,
+and the response to receiving a Delete is to do the deletion and reply
+with another Delete.
+If there is no response to the first Delete,
+retry a small number of times and then give up and do the deletion;
+apart from being robust against packet loss,
+this also maximizes the probability that an implementation which does
+not do the bidirectional Delete will receive at least one of the Deletes.
+.P
+When a host with current connections knows that it is about to shut down,
+it will issue Deletes for all SAs involved (both IPsec and ISAKMP),
+advising its peers (as per the meaning of Delete [ISAKMP, section 3.15])
+that the SAs have become useless.
+It will ignore attempts at rekeying or connection startup thereafter,
+until it shuts down.
+.P
+It would be better to have a Final-Contact notification,
+analogous to Initial-Contact but indicating that no new negotiations
+should be attempted until further notice.
+Initial-Contact actually could be used for shutdown notification (!),
+but in networks where connections are intended to exist permanently,
+it seems likely to provoke unwanted attempts
+to renegotiate the lost connections.
+.H
+5.3. Crashes
+.P
+Systems sometimes crash.
+Coping with the resulting loss of information is easily the most
+difficult problem we have found in implementing robust IPsec systems.
+.P
+When connections are intended to be permanent,
+it is simple to specify renegotiation on reboot.
+With our approach to SA selection (see section 4.3),
+this handles such cases robustly and well.
+We do have to tell users that BOTH hosts should be set this way.
+In cases where crashes are synchronized (e.g. by power interruptions),
+this may result in simultaneous negotiations at reboot.
+We currently allow both negotiations to proceed to completion,
+but our use-newest selection method
+effectively ignores one connection or the other,
+and when one of them rekeys,
+we notice that the new SAs replace those of both old connections,
+and we then refrain from rekeying the other.
+(This duplicate detection is desirable in any event, for robustness,
+to ensure that the system converges on a reasonable state eventually
+after it is perturbed by difficulties or bugs.)
+.P
+When connections are not permanent, the situation is less happy.
+One particular situation in which we see problems is when a number of
+"Road Warrior" hosts occasionally call in to a central server.
+The server is normally configured not to initiate such connections,
+since it does not know when the Road Warrior is available (or what IP
+address it is using).
+Unfortunately, if the server crashes and reboots,
+any Road Warriors then connected have a problem:
+they don't know that the server has crashed,
+so they can't renegotiate,
+and the server has forgotten both the connections and
+their (transient) IP addresses,
+so it cannot renegotiate.
+.P
+We believe that the simplest answer to this problem is what John Denker
+has dubbed "address inertia":
+the server makes a best-effort attempt to remember (in nonvolatile storage)
+which connections were active and what the far-end addresses were
+(and what the successful proposal's parameters were),
+so that it can attempt renegotiation on reboot.
+We have not implemented this yet, but intend to;
+Denker has implemented it himself,
+although in a somewhat messy way,
+and reports excellent results.
+.H
+5.4. Network Partitions
+.P
+A network partition, making the two ends unable to reach each other,
+has many of the same characteristics as having the other end crash... until
+the network reconnects.
+It is desirable that recovery from this be automatic.
+.P
+If the network reconnects before any rekeying attempts
+or other IKE activities occurred,
+recovery is fully transparent,
+because the IKEs have no idea that there was any problem.
+(Complaints such as ICMP Host Unreachable messages are unauthenticated
+and hence cannot be given much weight.)
+This fits the general mold of TCP/IP:
+if nobody wanted to send any traffic, a network outage doesn't matter.
+.P
+If IKE activity did occur,
+the IKE implementation will discover that the other end doesn't seem
+to be responding.
+The preferred response to this depends on the nature of the connection.
+If it was intended to be ephemeral (e.g. opportunistic encryption [OE]),
+closing it down after a few retries is reasonable.
+If the other end is expected to sometimes drop the connection without
+warning, it may not be desirable to retry at all.
+(We support both these forms of configurability,
+and indeed we also have a configuration option to suppress
+rekeying entirely on one end.)
+.P
+If the connection was intended to be permanent, however,
+then persistent attempts to re-establish it are appropriate.
+Some degree of backoff is appropriate here,
+so that retries get less frequent as the outage gets prolonged.
+Backoff should be limited,
+so that re-established connectivity is not followed by a long delay
+before a retry.
+Finally, after many retries (say 24 hours' worth),
+it may be preferable to just declare the connection down and rely
+on manual intervention to re-establish it,
+should this be desirable.
+We do not yet fully support all this.
+.H
+5.5. Unknown SAs
+.P
+A more complete solution to crashes
+would be for an IPsec host to note the arrival
+of ESP packets on an unknown IPsec SA,
+and report it somehow to the other host, which can then decide to renegotiate.
+This arguably might be preferable in any case\(emif
+the non-rebooted host has no traffic to send,
+it does not care whether the connection is intact\(embut
+delays and packet loss will be reduced
+if the connection is renegotiated BEFORE there is traffic for it.
+So unknown-SA detection is best reserved as a fallback method,
+with address inertia used to deal with most such cases.
+.P
+A difficulty with unknown-SA detection is,
+just HOW should the other host be notified?
+IKE provides no good way to do the notification:
+Notification payloads (e.g., Initial-Contact) are unauthenticated
+unless they are sent under protection of an ISAKMP SA.
+A "Security Failures - Bad SPI" ICMP message [SECFAIL]
+is an interesting alternative,
+but has the disadvantage of likewise being unauthenticated.
+It's fundamentally unlikely that there is a simple solution to this,
+given that almost any way of arranging or checking authentication for such a
+notification is costly.
+.P
+We think the best answer to this is a two-step approach.
+An unauthenticated Initial-Contact or
+Security Failures - Bad SPI cannot be taken as a reliable
+report of a problem,
+but can be taken as a hint that a problem MIGHT exist.
+Then there needs to be some reliable way of checking such hints,
+subject to rate limiting since the checks are likely to be costly
+(and checking the same connection repeatedly at short intervals is unlikely
+to be worthwhile anyway).
+So the rebooted host sends the notification,
+and the non-rebooted host\(emwhich still thinks it has a connection\(emchecks
+whether the connection still works,
+and renegotiates if not.
+.P
+Also, if an IPsec host which believes it has a connection to another host
+sees an unsuccessful attempt by that host to negotiate a new one,
+that is also a hint of possible problems,
+justifying a check and possible renegotiation.
+("Unsuccessful" here means a negotiation failure due to lack of a
+satisfactory proposal.
+A failure due to authentication failure
+suggests a denial-of-service attack by a third party,
+rather than a genuine problem on the legitimate other end.)
+As noted in section 4.2,
+it is possible for negotiations to succeed or fail based on which
+end initiates them, and some robustness against that is desirable.
+.P
+We have not yet decided what form the notification should take.
+IKE Initial-Contact is an obvious possibility,
+but has some disadvantages.
+It does not specify which connection has had difficulties.
+Also, the specification [IKE section 4.6.3.3]
+refers to "remote system" and "sending system"
+without clearly specifying just what "system" means;
+in the case of a multi-homed host using multiple forms of identification,
+the question is not trivial.
+Initial-Contact does have the fairly-decisive advantage
+that it is likely to convey the right general
+meaning even to an implementation which does not do things
+exactly the way ours does.
+.P
+A more fundamental difficulty is what form the reliable check takes.
+What is wanted is an "IKE ping",
+verifying that the ISAKMP SA is still intact
+(it being unlikely that IPsec SAs have been lost while the ISAKMP SA has not).
+The lack of such a facility is a serious failing of IKE.
+An acknowledged Notification of some sort would be ideal,
+but there is none at present.
+Some existing implementations are known
+to use the private Notification values 30000 as ping
+and 30002 as ping reply,
+and that seems the most attractive choice at present.
+If it is not recognized, there will probably be no reply,
+and the result will be an unnecessary renegotiation,
+so this needs strict rate limiting.
+(Also, when a new connection is set up,
+it's probably worth determining by experiment whether the other end
+supports IKE ping, and remembering that.)
+.P
+While we think this facility is desirable,
+and is about the best that can be done with the poor tools available,
+we have not gotten very far in implementation and cannot comment
+intelligently about how well it works or interoperates.
+.H
+6. Misc. IKE Issues
+.H
+6.1. Groups 1 and 5
+.P
+We have dropped support for the first Oakley Group (group 1),
+despite it being officially mandatory,
+on the grounds that it is
+grossly too weak to provide enough randomness for 3DES.
+There have been some interoperability problems,
+mostly quite minor:
+ALMOST everyone supports group 2 as well,
+although sometimes it has to be explicitly configured.
+.P
+We also support the quasi-standard group 5 [GROUPS].
+This has not been seriously exercised yet,
+because historically
+we offered group 2 first and almost everyone accepted it.
+We have recently changed to offering group 5 first,
+and no difficulties have been reported.
+.H
+6.2. To PFS Or Not To PFS
+.P
+A persistent small interoperability problem is that
+the presence or absence of PFS (for keys [IKE, section 5.5])
+is neither negotiated nor announced.
+We have it enabled by default,
+and successful interoperation often requires having
+the other end turn it on in their implementation,
+or having the FreeS/WAN end disable it.
+Almost everyone supports it, but it's usually not the default,
+and interoperability is often impossible unless the two ends
+somehow reach prior agreement on it.
+.P
+We do not explicitly support the other flavor of PFS,
+for identities [IKE, section 8],
+and this has caused no interoperability problems.
+.H
+6.3. Debugging Tools, Lack Thereof
+.P
+We find IKE lacking in basic debugging tools.
+Section 5.4, above,
+notes that an IKE ping would be useful for connectivity verification.
+It would also be extremely helpful for determining that UDP/500
+packets get back and forth successfully between the two ends,
+which is often an important first step in debugging.
+.P
+It's also quite common to have IKE negotiate a connection successfully,
+but to have some firewall along the way blocking ESP.
+Users find this mysterious and difficult to diagnose.
+We have no immediate suggestions on what could be done about it.
+.H
+6.4. Terminology, Vagueness Thereof
+.P
+The terminology of IPsec needs work.
+We feel that both the specifications and user-oriented
+documentation would be greatly clarified by concise, intelligible names for
+certain concepts.
+.P
+We semi-consistently use "group" for the set of IPsec SAs which are
+established in one direction
+by a single Quick Mode negotiation and are used together
+to process a packet (e.g., an ESP SA plus an AH SA),
+"connection" for the logical packet path provided
+by a succession of pairs of groups
+(each rekeying providing a new pair, one group in each direction),
+and "keying channel" for the corresponding supervisory path provided
+by a sequence of ISAKMP SAs.
+.P
+We think it's a botch that "PFS" is used to refer to two very different things,
+but we have no specific new terms to suggest, since we only implement
+one kind of PFS and thus can just ignore the other.
+.H
+6.5. A Question of Identity
+.P
+One specification problem deserves note:
+exactly when can an existing phase 1 negotiation
+be re-used for a new phase 2 negotiation,
+as IKE [IKE, section 4] specifies?
+Presumably,
+when it connects the same two "parties"... but exactly what is a "party"?
+.P
+As noted in section 5.4,
+in cases involving multi-homing and multiple identities,
+it's not clear exactly what criteria are used for deciding
+whether the intended far end for a new negotiation is the same one
+as for a previous negotiation.
+Is it by Identification Payload?
+By IP address?
+Or what?
+.P
+We currently use a somewhat-vague notion of "identity",
+basically what gets sent in Identification Payloads,
+for this, and this seems to be successful,
+but we think this needs better specification.
+.H
+6.6. Opportunistic Encryption
+.P
+Further IKE challenges appear in the context of Opportunistic Encryption
+[OE],
+but operational experience with it is too limited as yet for us
+to comment usefully right now.
+.H
+6.7. Authentication and RSA Keys
+.P
+We provide two IKE authentication methods:
+shared secrets ("pre-shared keys")
+and RSA digital signatures.
+(A user-provided add-on package generalizes the latter to limited
+support for certificates;
+we have not worked extensively with it ourselves yet and cannot comment
+on it yet.)
+.P
+Shared secrets, despite their administrative difficulties,
+see considerable use,
+and are also the method of last resort for interoperability problems.
+.P
+For digital signatures,
+we have taken the somewhat unorthodox approach of using "bare" RSA public keys,
+either supplied in configuration files or fetched from DNS,
+rather than getting involved in the complexity of certificates.
+We encode our RSA public keys using the DNS KEY encoding [DNSRSA]
+(aka "RFC 2537", although that RFC is now outdated),
+which has given us no difficulties and which we highly recommend.
+We have seen two difficulties in connection with RSA keys, however.
+.P
+First,
+while a number of IPsec implementations are able to take "bare" RSA public keys,
+each one seems to have its own idea of what format should be used
+for transporting them.
+We've had little success with interoperability here,
+mostly because of key-format issues;
+the implementations generally WILL interoperate successfully if you can
+somehow get an RSA key into them at all, but that's hard.
+X.509 certificates seem to be the lowest (!)
+common denominator for key transfer.
+.P
+Second,
+although the content of RSA public keys has been stable,
+there has been a small but subtle change over time in the content
+of RSA private keys.
+The "internal modulus",
+used to compute the private exponent "d" from the public exponent "e"
+(or vice-versa)
+was originally [RSA] [PKCS1v1] [SCHNEIER] specified to be (p-1)*(q-1),
+where p and q are the two primes.
+However, more recent definitions [PKCS1v2] call it
+"lambda(n)" and define it to be lcm(p-1,\ q-1);
+this appears to be a minor optimization.
+The result is that private keys generated with the new definition
+often fail consistency checks in implementations using the old definition.
+Fortunately, it is seldom necessary to move private keys around.
+Our software now consistently uses the new definition
+(and thus will accept keys generated with either definition),
+but our key generator also has an option to generate old-definition keys,
+for the benefit of users who upgrade their networks incrementally.
+.H
+6.8. Misc. Snags
+.P
+Nonce size is another characteristic that is neither negotiated nor announced
+but that the two ends must somehow be able to agree on.
+Our software accepts anything between 8 and 256, and defaults to 16.
+These numbers were chosen rather arbitrarily,
+but we have seen no interoperability failures here.
+.P
+Nothing in the ISAKMP [ISAKMP] or IKE [IKE] specifications says
+explicitly that a normal Message ID must be non-zero,
+but a zero Message ID in fact causes failures.
+.P
+Similarly, there is nothing in the specs which says that ISAKMP cookies
+must be non-zero, but zero cookies will in fact cause trouble.
+.H
+7. Security Considerations
+.P
+Since this document discusses aspects of building robust and
+interoperable IPsec implementations,
+security considerations permeate it.
+.H
+8. References
+.R AH
+Kent, S., and Atkinson, R.,
+"IP Authentication Header",
+RFC 2402,
+Nov 1998.
+.R CIPHERS
+Pereira, R., and Adams, R.,
+"The ESP CBC-Mode Cipher Algorithms",
+RFC 2451,
+Nov 1998.
+.R CRACK
+Electronic Frontier Foundation,
+"Cracking DES:
+Secrets of Encryption Research, Wiretap Politics and Chip Design",
+O'Reilly 1998,
+ISBN 1-56592-520-3.
+.R DES
+Madson, C., and Doraswamy, N.,
+"The ESP DES-CBC Cipher Algorithm",
+RFC 2405,
+Nov 1998.
+.R DNSRSA
+D. Eastlake 3rd,
+"RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)",
+RFC 3110,
+May 2001.
+.R ESP
+Kent, S., and Atkinson, R.,
+"IP Encapsulating Security Payload (ESP)",
+RFC 2406,
+Nov 1998.
+.R GROUPS
+Kivinen, T., and Kojo, M.,
+"More MODP Diffie-Hellman groups for IKE",
+<draft-ietf-ipsec-ike-modp-groups-04.txt>,
+13 Dec 2001 (work in progress).
+.R IKE
+Harkins, D., and Carrel, D.,
+"The Internet Key Exchange (IKE)",
+RFC 2409, Nov 1998.
+.R IPSEC
+Kent, S., and Atkinson, R.,
+"Security Architecture for the Internet Protocol",
+RFC 2401, Nov 1998.
+.R ISAKMP
+Maughan, D., Schertler, M., Schneider, M., and Turner, J.,
+"Internet Security Association and Key Management Protocol (ISAKMP)",
+RFC 2408, Nov 1998.
+.R OE
+Richardson, M., Redelmeier, D. H., and Spencer, H.,
+"A method for doing opportunistic encryption with IKE",
+<draft-richardson-ipsec-opportunistic-06.txt>,
+21 Feb 2002 (work in progress).
+.R PKCS1v1
+Kaliski, B.,
+"PKCS #1: RSA Encryption, Version 1.5",
+RFC 2313, March 1998.
+.R PKCS1v2
+Kaliski, B., and Staddon, J.,
+"PKCS #1: RSA Cryptography Specifications, Version 2.0",
+RFC 2437, Oct 1998.
+.R PFKEY
+McDonald, D., Metz, C., and Phan, B.,
+"PF_KEY Key Management API, Version 2",
+RFC 2367, July 1998.
+.R REKEY
+Tim Jenkins, "IPsec Re-keying Issues",
+<draft-jenkins-ipsec-rekeying-06.txt>,
+2 May 2000 (draft expired, work no longer in progress).
+.R REPLAY
+Krywaniuk, A.,
+"Using Isakmp Message Ids for Replay Protection",
+<draft-krywaniuk-ipsec-antireplay-00.txt>,
+9 July 2001
+(work in progress).
+.R RSA
+Rivest, R.L., Shamir, A., and Adleman, L.,
+"A Method for Obtaining Digital Signatures and Public-Key
+Cryptosystems",
+Communications of the ACM v21n2, Feb 1978, p. 120.
+.R SCHNEIER
+Bruce Schneier, "Applied Cryptography", 2nd ed.,
+Wiley 1996, ISBN 0-471-11709-9.
+.R SECFAIL
+Karn, P., and Simpson, W.,
+"ICMP Security Failures Messages",
+RFC 2521,
+March 1999.
+.H
+Authors' Addresses
+.P
+.nf
+.ne 8
+Henry Spencer
+SP Systems
+Box 280 Stn. A
+Toronto, Ont. M5W1B2
+Canada
+
+henry@spsystems.net
+416-690-6561
+.ne 8
+.sp 2
+D. Hugh Redelmeier
+Mimosa Systems Inc.
+29 Donino Ave.
+Toronto, Ont. M4N2W6
+Canada
+
+hugh@mimosa.com
+416-482-8253
+.bp
+.H
+Full Copyright Statement
+.P
+Copyright (C) The Internet Society \*c. 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 implmentation 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.
diff --git a/doc/draft-spencer-ipsec-ike-implementation.txt b/doc/draft-spencer-ipsec-ike-implementation.txt
new file mode 100644
index 000000000..145c00ba8
--- /dev/null
+++ b/doc/draft-spencer-ipsec-ike-implementation.txt
@@ -0,0 +1,1232 @@
+
+
+
+Network Working Group Henry Spencer
+Internet Draft SP Systems
+Expires: 26 Aug 2002 D. Hugh Redelmeier
+ Mimosa Systems
+ 26 Feb 2002
+
+ IKE Implementation Issues
+ <draft-spencer-ipsec-ike-implementation-02.txt>
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of RFC2026.
+
+ (If approved as an Informational RFC...) This memo provides
+ information for the Internet community. This memo does not specify
+ an Internet standard of any kind.
+
+ Distribution of this memo is unlimited.
+
+ Internet-Drafts are working documents of the Internet Engineering
+ Task Force (IETF), its areas, and its working groups. Note that
+ other groups may also distribute working documents as Internet-
+ Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress."
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt.
+
+ The list of Internet-Draft Shadow Directories can be accessed at
+ http://www.ietf.org/shadow.html.
+
+ This Internet-Draft will expire on 26 Aug 2002.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society 2002. All Rights Reserved.
+
+
+
+
+
+
+
+
+
+
+Spencer & Redelmeier [Page 1]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+Table of Contents
+
+ 1. Introduction ................................................... 3
+ 2. Lower-level Background and Notes ............................... 4
+ 2.1. Packet Handling .............................................. 4
+ 2.2. Ciphers ...................................................... 5
+ 2.3. Interfaces ................................................... 5
+ 3. IKE Infrastructural Issues ..................................... 5
+ 3.1. Continuous Channel ........................................... 5
+ 3.2. Retransmission ............................................... 5
+ 3.3. Replay Prevention ............................................ 6
+ 4. Basic Keying and Rekeying ...................................... 7
+ 4.1. When to Create SAs ........................................... 7
+ 4.2. When to Rekey ................................................ 8
+ 4.3. Choosing an SA ............................................... 9
+ 4.4. Why to Rekey ................................................. 9
+ 4.5. Rekeying ISAKMP SAs ......................................... 10
+ 4.6. Bulk Negotiation ............................................ 10
+ 5. Deletions, Teardowns, Crashes ................................. 11
+ 5.1. Deletions ................................................... 11
+ 5.2. Teardowns and Shutdowns ..................................... 12
+ 5.3. Crashes ..................................................... 13
+ 5.4. Network Partitions .......................................... 13
+ 5.5. Unknown SAs ................................................. 14
+ 6. Misc. IKE Issues .............................................. 16
+ 6.1. Groups 1 and 5 .............................................. 16
+ 6.2. To PFS Or Not To PFS ........................................ 16
+ 6.3. Debugging Tools, Lack Thereof ............................... 16
+ 6.4. Terminology, Vagueness Thereof .............................. 17
+ 6.5. A Question of Identity ...................................... 17
+ 6.6. Opportunistic Encryption .................................... 17
+ 6.7. Authentication and RSA Keys ................................. 17
+ 6.8. Misc. Snags ................................................. 18
+ 7. Security Considerations ....................................... 19
+ 8. References .................................................... 19
+ Authors' Addresses ............................................... 20
+ Full Copyright Statement ......................................... 21
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Spencer & Redelmeier [Page 2]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+Abstract
+
+ The current IPsec specifications for key exchange and connection
+ management, RFCs 2408 [ISAKMP] and 2409 [IKE], leave many aspects of
+ connection management unspecified, most prominently rekeying
+ practices. Pending clarifications in future revisions of the
+ specifications, this document sets down some successful experiences,
+ to minimize the extent to which new implementors have to rely on
+ unwritten folklore.
+
+ The Linux FreeS/WAN implementation of IPsec interoperates with almost
+ every other IPsec implementation. This document describes how the
+ FreeS/WAN project has resolved some of the gaps in the IPsec
+ specifications (and plans to resolve some others), and what
+ difficulties have been encountered, in hopes that this generally-
+ successful experience might be informative to new implementors.
+
+ This is offered as an Informational RFC.
+
+ This -02 revision mainly: discusses ISAKMP SA expiry during IPsec-SA
+ rekeying (4.5), revises the discussion of bidirectional Deletes
+ (5.1), suggests remembering the parameters of successful negotiations
+ for later use (4.2, 5.3), notes an unsuccessful negotiation from the
+ other end as a hint of a possibly broken connection (5.5), and adds
+ sections on network partitions (5.4), authentication methods and the
+ subtleties of RSA public keys (6.7), and miscellaneous
+ interoperability concerns (6.8).
+
+1. Introduction
+
+ The current IPsec specifications for key exchange and connection
+ management, RFCs 2408 [ISAKMP] and 2409 [IKE], leave many aspects of
+ connection management unspecified, most prominently rekeying
+ practices. This is a cryptic puzzle which each group of implementors
+ has to struggle with, and differences in how the ambiguities and gaps
+ are resolved are potentially a fruitful source of interoperability
+ problems. We can hope that future revisions of the specifications
+ will clear this up. Meanwhile, it seems useful to set down some
+ successful experiences, to minimize the extent to which new
+ implementors have to rely on unwritten folklore.
+
+ The Linux FreeS/WAN implementation of IPsec interoperates with almost
+ every other IPsec implementation, and because of its free nature, it
+ also sees some use as a reference implementation by other
+ implementors. The high degree of interoperability is noteworthy
+ given its organizers' strong minimalist bias, which has caused them
+ to implement only a small subset of the full glory of IPsec. This
+ document describes how the FreeS/WAN project has resolved some of the
+
+
+
+Spencer & Redelmeier [Page 3]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ gaps in the IPsec specifications (and plans to resolve some others),
+ and what difficulties have been encountered, in hopes that this
+ generally-successful experience might be informative to new
+ implementors.
+
+ One small caution about applicability: this experience may not be
+ relevant to severely resource-constrained implementations.
+ FreeS/WAN's target environment is previous-generation PCs, now
+ available at trivial cost (often, within an organization, at no
+ cost), which have quite impressive CPU power and memory by the
+ standards of only a few years ago. Some of the approaches discussed
+ here may be inapplicable to implementations with severe external
+ constraints which prevent them from taking advantage of modern
+ hardware technology.
+
+2. Lower-level Background and Notes
+
+2.1. Packet Handling
+
+ FreeS/WAN implements ESP [ESP] and AH [AH] straightforwardly,
+ although AH sees little use among our users. Our ESP/AH
+ implementation cannot currently handle packets with IP options;
+ somewhat surprisingly, this has caused little difficulty. We insist
+ on encryption and do not support authentication-only connections, and
+ this has not caused significant difficulty either.
+
+ MTU and fragmentation issues, by contrast, have been a constant
+ headache. We will not describe the details of our current approach
+ to them, because it still needs work. One difficulty we have
+ encountered is that many combinations of packet source and packet
+ destination apparently cannot cope with an "interior minimum" in the
+ path MTU, e.g. where an IPsec tunnel intervenes and its headers
+ reduce the MTU for an intermediate link. This is particularly
+ prevalent when using common PC software to connect to large well-
+ known web sites; we think it is largely due to misconfigured
+ firewalls which do not pass ICMP Fragmentation Required messages.
+ The only solution we have yet found is to lie about the MTU of the
+ tunnel, accepting the (undesirable) fragmentation of the ESP packets
+ for the sake of preserving connectivity.
+
+ We currently zero out the TOS field of ESP packets, rather than
+ copying it from the inner header, on the grounds that it lends itself
+ too well to traffic analysis and covert channels. We provide an
+ option to restore RFC 2401 [IPSEC] copying behavior, but this appears
+ to see little use.
+
+
+
+
+
+
+Spencer & Redelmeier [Page 4]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+2.2. Ciphers
+
+ We initially implemented both DES [DES] and 3DES [CIPHERS] for both
+ IKE and ESP, but after the Deep Crack effort [CRACK] demonstrated its
+ inherent insecurity, we dropped support for DES. Somewhat
+ surprisingly, our insistence on 3DES has caused almost no
+ interoperability problems, despite DES being officially mandatory. A
+ very few other systems either do not support 3DES or support it only
+ as an optional upgrade, which inconveniences a few would-be users.
+ There have also been one or two cases of systems which don't quite
+ seem to know the difference!
+
+ See also section 6.1 for a consequence of our insistence on 3DES.
+
+2.3. Interfaces
+
+ We currently employ PF_KEY version 2 [PFKEY], plus various non-
+ standard extensions, as our interface between keying and ESP. This
+ has not proven entirely satisfactory. Our feeling now is that keying
+ issues and policy issues do not really lend themselves to the clean
+ separation that PF_KEY envisions.
+
+3. IKE Infrastructural Issues
+
+ A number of problems in IPsec connection management become easier if
+ some attention is first paid to providing an infrastructure to
+ support solving them.
+
+3.1. Continuous Channel
+
+ FreeS/WAN uses an approximation to the "continuous channel" model, in
+ which ISAKMP SAs are maintained between IKEs so long as any IPsec SAs
+ are open between the two systems. The resource consumption of this
+ is minor: the only substantial overhead is occasional rekeying.
+ IPsec SA management becomes significantly simpler if there is always
+ a channel for transmission of control messages. We suggest (although
+ we do not yet fully implement this) that inability to maintain (e.g.,
+ to rekey) this control path should be grounds for tearing down the
+ IPsec SAs as well.
+
+ As a corollary of this, there is one and only one ISAKMP SA
+ maintained between a pair of IKEs (although see sections 5.3 and 6.5
+ for minor complications).
+
+3.2. Retransmission
+
+ The unreliable nature of UDP transmission is a nuisance. IKE
+ implementations should always be prepared to retransmit the most
+
+
+
+Spencer & Redelmeier [Page 5]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ recent message they sent on an ISAKMP SA, since there is some
+ possibility that the other end did not get it. This means, in
+ particular, that the system sending the supposedly-last message of an
+ exchange cannot relax and assume that the exchange is complete, at
+ least not until a significant timeout has elapsed.
+
+ Systems must also retain information about the message most recently
+ received in an exchange, so that a duplicate of it can be detected
+ (and possibly interpreted as a NACK for the response).
+
+ The retransmission rules FreeS/WAN follows are: (1) if a reply is
+ expected, retransmit only if it does not appear before a timeout; and
+ (2) if a reply is not expected (last message of the exchange),
+ retransmit only on receiving a retransmission of the previous
+ message. Notably, in case (1) we do NOT retransmit on receiving a
+ retransmission, which avoids possible congestion problems arising
+ from packet duplication, at the price of slowing response to packet
+ loss. The timeout for case (1) is 10 seconds for the first retry, 20
+ seconds for the second, and 40 seconds for all subsequent retries
+ (normally only one, except when configuration settings call for
+ persistence and the message is the first message of Main Mode with a
+ new peer). These retransmission rules have been entirely successful.
+
+ (Michael Thomas of Cisco has pointed out that the retry timeouts
+ should include some random jitter, to de-synchronize hosts which are
+ initially synchronized by, e.g., a power outage. We already jitter
+ our rekeying times, as noted in section 4.2, but that does not help
+ with initial startup. We're implementing jittered retries, but
+ cannot yet report on experience with this.)
+
+ There is a deeper problem, of course, when an entire "exchange"
+ consists of a single message, e.g. the ISAKMP Informational Exchange.
+ Then there is no way to decide whether or when a retransmission is
+ warranted at all. This seems like poor design, to put it mildly (and
+ there is now talk of fixing it). We have no experience in dealing
+ with this problem at this time, although it is part of the reason why
+ we have delayed implementing Notification messages.
+
+3.3. Replay Prevention
+
+ The unsequenced nature of UDP transmission is also troublesome,
+ because it means that higher levels must consider the possibility of
+ replay attacks. FreeS/WAN takes the position that systematically
+ eliminating this possibility at a low level is strongly preferable to
+ forcing careful consideration of possible impacts at every step of an
+ exchange. RFC 2408 [ISAKMP] section 3.1 states that the Message ID
+ of an ISAKMP message must be "unique". FreeS/WAN interprets this
+ literally, as forbidding duplication of Message IDs within the set of
+
+
+
+Spencer & Redelmeier [Page 6]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ all messages sent via a single ISAKMP SA.
+
+ This requires remembering all Message IDs until the ISAKMP SA is
+ superseded by rekeying, but that is not costly (four bytes per sent
+ or received message), and it ELIMINATES replay attacks from
+ consideration; we believe this investment of resources is well
+ worthwhile. If the resource consumption becomes excessive--in our
+ experience it has not--the ISAKMP SA can be rekeyed early to collect
+ the garbage.
+
+ There is theoretically an interoperability problem when talking to
+ implementations which interpret "unique" more loosely and may re-use
+ Message IDs, but it has not been encountered in practice. This
+ approach appears to be completely interoperable.
+
+ The proposal by Andrew Krywaniuk [REPLAY], which advocates turning
+ the Message ID into an anti-replay counter, would achieve the same
+ goal without the minor per-message memory overhead. This may be
+ preferable, although it means an actual protocol change and more
+ study is needed.
+
+4. Basic Keying and Rekeying
+
+4.1. When to Create SAs
+
+ As Tim Jenkins [REKEY] pointed out, there is a potential race
+ condition in Quick Mode: a fast lightly-loaded Initiator might start
+ using IPsec SAs very shortly after sending QM3 (the third and last
+ message of Quick Mode), while a slow heavily-loaded Responder might
+ not be ready to receive them until after spending a significant
+ amount of time creating its inbound SAs. The problem is even worse
+ if QM3 gets delayed or lost.
+
+ FreeS/WAN's approach to this is what Jenkins called "Responder Pre-
+ Setup": the Responder creates its inbound IPsec SAs before it sends
+ QM2, so they are always ready and waiting when the Initiator sends
+ QM3 and begins sending traffic. This approach is simple and
+ reliable, and in our experience it interoperates with everybody.
+ (There is potentially still a problem if FreeS/WAN is the Initiator
+ and the Responder does not use Responder Pre-Setup, but no such
+ problems have been seen.) The only real weakness of Responder Pre-
+ Setup is the possibility of replay attacks, which we have eliminated
+ by other means (see section 3.3).
+
+ With this approach, the Commit Bit is useless, and we ignore it. In
+ fact, until quite recently we discarded any IKE message containing
+ it, and this caused surprisingly few interoperability problems;
+ apparently it is not widely used. We have recently been persuaded
+
+
+
+Spencer & Redelmeier [Page 7]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ that simply ignoring it is preferable; preliminary experience with
+ this indicates that the result is successful interoperation with
+ implementations which set it.
+
+4.2. When to Rekey
+
+ To preserve connectivity for user traffic, rekeying of a connection
+ (that is, creation of new IPsec SAs to supersede the current ones)
+ must begin before its current IPsec SAs expire. Preferably one end
+ should predictably start rekeying negotiations first, to avoid the
+ extra overhead of two simultaneous negotiations, although either end
+ should be prepared to rekey if the other does not. There is also a
+ problem with "convoys" of keying negotiations: for example, a "hub"
+ gateway with many IPsec connections can be inundated with rekeying
+ negotiations exactly one connection-expiry time after it reboots, and
+ the massive overload this induces tends to make this situation self-
+ perpetuating, so it recurs regularly. (Convoys can also evolve
+ gradually from initially-unsynchronized negotiations.)
+
+ FreeS/WAN has the concept of a "rekeying margin", measured in
+ seconds. If FreeS/WAN was the Initiator for the previous rekeying
+ (or the startup, if none) of the connection, it nominally starts
+ rekeying negotiations at expiry time minus one rekeying margin. Some
+ random jitter is added to break up convoys: rather than starting
+ rekeying exactly at minus one margin, it starts at a random time
+ between minus one margin and minus two margins. (The randomness here
+ need not be cryptographic in quality, so long as it varies over time
+ and between hosts. We use an ordinary PRNG seeded with a few bytes
+ from a cryptographic randomness source. The seeding mostly just
+ ensures that the PRNG sequence is different for different hosts, even
+ if they start up simultaneously.)
+
+ If FreeS/WAN was the Responder for the previous rekeying/startup, and
+ nothing has been heard from the previous Initiator at expiry time
+ minus one-half the rekeying margin, FreeS/WAN will initiate rekeying
+ negotiations. No jitter is applied; we now believe that it should be
+ jittered, say between minus one-half margin and minus one-quarter
+ margin.
+
+ Having the Initiator lead the way is an obvious way of deciding who
+ should speak first, since there is already an Initiator/Responder
+ asymmetry in the connection. Moreover, our experience has been that
+ Initiator lead gives a significantly higher probability of successful
+ negotiation! The negotiation process itself is asymmetric, because
+ the Initiator must make a few specific proposals which the Responder
+ can only accept or reject, so the Initiator must try to guess where
+ its "acceptable" region (in parameter space) might overlap with the
+ Responder's. We have seen situations where negotiations would
+
+
+
+Spencer & Redelmeier [Page 8]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ succeed or fail depending on which end initiated them, because one
+ end was making better guesses. Given an existing connection, we KNOW
+ that the previous Initiator WAS able to initiate a successful
+ negotiation, so it should (if at all possible) take the lead again.
+ Also, the Responder should remember the Initiator's successful
+ proposal, and start from that rather than from his own default
+ proposals if he must take the lead; we don't currently implement this
+ completely but plan to.
+
+ FreeS/WAN defaults the rekeying margin to 9 minutes, although this
+ can be changed by configuration. There is also a configuration
+ option to alter the permissible range of jitter. The defaults were
+ chosen somewhat arbitrarily, but they work extremely well and the
+ configuration options are rarely used.
+
+4.3. Choosing an SA
+
+ Once rekeying has occurred, both old and new IPsec SAs for the
+ connection exist, at least momentarily. FreeS/WAN accepts incoming
+ traffic on either old or new inbound SAs, but sends outgoing traffic
+ only on the new outbound ones. This approach appears to be
+ significantly more robust than using the old ones until they expire,
+ notably in cases where renegotiation has occurred because something
+ has gone wrong on the other end. It avoids having to pay meticulous
+ attention to the state of the other end, state which is difficult to
+ learn reliably given the limitations of IKE.
+
+ This approach has interoperated successfully with ALMOST all other
+ implementations. The only (well-characterized) problem cases have
+ been implementations which rely on receiving a Delete message for the
+ old SAs to tell them to switch over to the new ones. Since delivery
+ of Delete is unreliable, and support for Delete is optional, this
+ reliance seems like a serious mistake. This is all the more true
+ because Delete announces that the deletion has already occurred
+ [ISAKMP, section 3.15], not that it is about to occur, so packets
+ already in transit in the other direction could be lost. Delete
+ should be used for resource cleanup, not for switchover control.
+ (These matters are discussed further in section 5.)
+
+4.4. Why to Rekey
+
+ FreeS/WAN currently implements only time-based expiry (life in
+ seconds), although we are working toward supporting volume-based
+ expiry (life in kilobytes) as well. The lack of volume-based expiry
+ has not been an interoperability problem so far.
+
+ Volume-based expiry does add some minor complications. In
+ particular, it makes explicit Delete of now-disused SAs more
+
+
+
+Spencer & Redelmeier [Page 9]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ important, because once an SA stops being used, it might not expire
+ on its own. We believe this lacks robustness and is generally
+ unwise, especially given the lack of a reliable Delete, and expect to
+ use volume-based expiry only as a supplement to time-based expiry.
+ However, Delete support (see section 5) does seem advisable for use
+ with volume-based expiry.
+
+ We do not believe that volume-based expiry alters the desirability of
+ switching immediately to the new SAs after rekeying. Rekeying
+ margins are normally a small fraction of the total life of an SA, so
+ we feel there is no great need to "use it all up".
+
+4.5. Rekeying ISAKMP SAs
+
+ The above discussion has focused on rekeying for IPsec SAs, but
+ FreeS/WAN applies the same approaches to rekeying for ISAKMP SAs,
+ with similar success.
+
+ One issue which we have noticed, but not explicitly dealt with, is
+ that difficulties may ensue if an IPsec-SA rekeying negotiation is in
+ progress at the time when the relevant ISAKMP SA gets rekeyed. The
+ IKE specification [IKE] hints, but does not actually say, that a
+ Quick Mode negotiation should remain on a single ISAKMP SA
+ throughout.
+
+ A reasonable rekeying margin will generally prevent the old ISAKMP SA
+ from actually expiring during a negotiation. Some attention may be
+ needed to prevent in-progress negotiations from being switched to the
+ new ISAKMP SA. Any attempt at pre-expiry deletion of the ISAKMP SA
+ must be postponed until after such dangling negotiations are
+ completed, and there should be enough delay between ISAKMP-SA
+ rekeying and a deletion attempt to (more or less) ensure that there
+ are no negotiation-starting packets still in transit from before the
+ rekeying.
+
+ At present, FreeS/WAN does none of this, and we don't KNOW of any
+ resulting trouble. With normal lifetimes, the problem should be
+ uncommon, and we speculate that an occasional disrupted negotiation
+ simply gets retried.
+
+4.6. Bulk Negotiation
+
+ Quick Mode nominally provides for negotiating possibly-large numbers
+ of similar but unrelated IPsec SAs simultaneously [IKE, section 9].
+ Nobody appears to do this. FreeS/WAN does not support it, and its
+ absence has caused no problems.
+
+
+
+
+
+Spencer & Redelmeier [Page 10]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+5. Deletions, Teardowns, Crashes
+
+ FreeS/WAN currently ignores all Notifications and Deletes, and never
+ generates them. This has caused little difficulty in
+ interoperability, which shouldn't be surprising (since Notification
+ and Delete support is officially entirely optional) but does seem to
+ surprise some people. Nevertheless, we do plan some changes to this
+ approach based on past experience.
+
+5.1. Deletions
+
+ As hinted at above, we plan to implement Delete support, done as
+ follows. Shortly after rekeying of IPsec SAs, the Responder issues a
+ Delete for its old inbound SAs (but does not actually delete them
+ yet). The Responder initiates this because the Initiator started
+ using the new SAs on sending QM3, while the Responder started using
+ them only on (or somewhat after) receiving QM3, so there is less
+ chance of old-SA packets still being in transit from the Initiator.
+ The Initiator issues an unsolicited Delete only if it does not hear
+ one from the Responder after a longer delay.
+
+ Either party, on receiving a Delete for one or more of the old
+ outbound SAs of a connection, deletes ALL the connection's SAs, and
+ acknowledges with a Delete for the old inbound SAs. A Delete for
+ nonexistent SAs (e.g., SAs which have already been expired or
+ deleted) is ignored. There is no retransmission of unacknowledged
+ Deletes.
+
+ In the normal case, with prompt reliable transmission (except
+ possibly for loss of the Responder's initial Delete) and conforming
+ implementations on both ends, this results in three Deletes being
+ transmitted, resembling the classic three-way handshake. Loss of a
+ Delete after the first, or multiple losses, will cause the SAs not to
+ be deleted on at least one end. It appears difficult to do much
+ better without at least a distinction between request and
+ acknowledgement.
+
+ RFC 2409 section 9 "strongly suggests" that there be no response to
+ informational messages such as Deletes, but the only rationale
+ offered is prevention of infinite loops endlessly exchanging "I don't
+ understand you" informationals. Since Deletes cannot lead to such a
+ loop (and in any case, the nonexistent-SA rule prevents more than one
+ acknowledgement for the same connection), we believe this
+ recommendation is inapplicable here.
+
+ As noted in section 4.3, these Deletes are intended for resource
+ cleanup, not to control switching between SAs. But we expect that
+ they will improve interoperability with some broken implementations.
+
+
+
+Spencer & Redelmeier [Page 11]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ We believe strongly that connections need to be considered as a
+ whole, rather than treating each SA as an independent entity. We
+ will issue Deletes only for the full set of inbound SAs of a
+ connection, and will treat a Delete for any outbound SA as equivalent
+ to deletion of all the outbound SAs for the associated connection.
+
+ The above is phrased in terms of IPsec SAs, but essentially the same
+ approach can be applied to ISAKMP SAs (the Deletes for the old ISAKMP
+ SA should be sent via the new one).
+
+5.2. Teardowns and Shutdowns
+
+ When a connection is not intended to be up permanently, there is a
+ need to coordinate teardown, so that both ends are aware that the
+ connection is down. This is both for recovery of resources, and to
+ avoid routing packets through dangling SAs which can no longer
+ deliver them.
+
+ Connection teardown will use the same bidirectional exchange of
+ Deletes as discussed in section 5.1: a Delete received for current
+ IPsec SAs (not yet obsoleted by rekeying) indicates that the other
+ host wishes to tear down the associated connection.
+
+ A Delete received for a current ISAKMP SA indicates that the other
+ host wishes to tear down not only the ISAKMP SA but also all IPsec
+ SAs currently under the supervision of that ISAKMP SA. The 5.1
+ bidirectional exchange might seem impossible in this case, since
+ reception of an ISAKMP-SA Delete indicates that the other end will
+ ignore further traffic on that ISAKMP SA. We suggest using the same
+ tactic discussed in 5.1 for IPsec SAs: the first Delete is sent
+ without actually doing the deletion, and the response to receiving a
+ Delete is to do the deletion and reply with another Delete. If there
+ is no response to the first Delete, retry a small number of times and
+ then give up and do the deletion; apart from being robust against
+ packet loss, this also maximizes the probability that an
+ implementation which does not do the bidirectional Delete will
+ receive at least one of the Deletes.
+
+ When a host with current connections knows that it is about to shut
+ down, it will issue Deletes for all SAs involved (both IPsec and
+ ISAKMP), advising its peers (as per the meaning of Delete [ISAKMP,
+ section 3.15]) that the SAs have become useless. It will ignore
+ attempts at rekeying or connection startup thereafter, until it shuts
+ down.
+
+ It would be better to have a Final-Contact notification, analogous to
+ Initial-Contact but indicating that no new negotiations should be
+ attempted until further notice. Initial-Contact actually could be
+
+
+
+Spencer & Redelmeier [Page 12]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ used for shutdown notification (!), but in networks where connections
+ are intended to exist permanently, it seems likely to provoke
+ unwanted attempts to renegotiate the lost connections.
+
+5.3. Crashes
+
+ Systems sometimes crash. Coping with the resulting loss of
+ information is easily the most difficult problem we have found in
+ implementing robust IPsec systems.
+
+ When connections are intended to be permanent, it is simple to
+ specify renegotiation on reboot. With our approach to SA selection
+ (see section 4.3), this handles such cases robustly and well. We do
+ have to tell users that BOTH hosts should be set this way. In cases
+ where crashes are synchronized (e.g. by power interruptions), this
+ may result in simultaneous negotiations at reboot. We currently
+ allow both negotiations to proceed to completion, but our use-newest
+ selection method effectively ignores one connection or the other, and
+ when one of them rekeys, we notice that the new SAs replace those of
+ both old connections, and we then refrain from rekeying the other.
+ (This duplicate detection is desirable in any event, for robustness,
+ to ensure that the system converges on a reasonable state eventually
+ after it is perturbed by difficulties or bugs.)
+
+ When connections are not permanent, the situation is less happy. One
+ particular situation in which we see problems is when a number of
+ "Road Warrior" hosts occasionally call in to a central server. The
+ server is normally configured not to initiate such connections, since
+ it does not know when the Road Warrior is available (or what IP
+ address it is using). Unfortunately, if the server crashes and
+ reboots, any Road Warriors then connected have a problem: they don't
+ know that the server has crashed, so they can't renegotiate, and the
+ server has forgotten both the connections and their (transient) IP
+ addresses, so it cannot renegotiate.
+
+ We believe that the simplest answer to this problem is what John
+ Denker has dubbed "address inertia": the server makes a best-effort
+ attempt to remember (in nonvolatile storage) which connections were
+ active and what the far-end addresses were (and what the successful
+ proposal's parameters were), so that it can attempt renegotiation on
+ reboot. We have not implemented this yet, but intend to; Denker has
+ implemented it himself, although in a somewhat messy way, and reports
+ excellent results.
+
+5.4. Network Partitions
+
+ A network partition, making the two ends unable to reach each other,
+ has many of the same characteristics as having the other end crash...
+
+
+
+Spencer & Redelmeier [Page 13]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ until the network reconnects. It is desirable that recovery from
+ this be automatic.
+
+ If the network reconnects before any rekeying attempts or other IKE
+ activities occurred, recovery is fully transparent, because the IKEs
+ have no idea that there was any problem. (Complaints such as ICMP
+ Host Unreachable messages are unauthenticated and hence cannot be
+ given much weight.) This fits the general mold of TCP/IP: if nobody
+ wanted to send any traffic, a network outage doesn't matter.
+
+ If IKE activity did occur, the IKE implementation will discover that
+ the other end doesn't seem to be responding. The preferred response
+ to this depends on the nature of the connection. If it was intended
+ to be ephemeral (e.g. opportunistic encryption [OE]), closing it down
+ after a few retries is reasonable. If the other end is expected to
+ sometimes drop the connection without warning, it may not be
+ desirable to retry at all. (We support both these forms of
+ configurability, and indeed we also have a configuration option to
+ suppress rekeying entirely on one end.)
+
+ If the connection was intended to be permanent, however, then
+ persistent attempts to re-establish it are appropriate. Some degree
+ of backoff is appropriate here, so that retries get less frequent as
+ the outage gets prolonged. Backoff should be limited, so that re-
+ established connectivity is not followed by a long delay before a
+ retry. Finally, after many retries (say 24 hours' worth), it may be
+ preferable to just declare the connection down and rely on manual
+ intervention to re-establish it, should this be desirable. We do not
+ yet fully support all this.
+
+5.5. Unknown SAs
+
+ A more complete solution to crashes would be for an IPsec host to
+ note the arrival of ESP packets on an unknown IPsec SA, and report it
+ somehow to the other host, which can then decide to renegotiate.
+ This arguably might be preferable in any case--if the non-rebooted
+ host has no traffic to send, it does not care whether the connection
+ is intact--but delays and packet loss will be reduced if the
+ connection is renegotiated BEFORE there is traffic for it. So
+ unknown-SA detection is best reserved as a fallback method, with
+ address inertia used to deal with most such cases.
+
+ A difficulty with unknown-SA detection is, just HOW should the other
+ host be notified? IKE provides no good way to do the notification:
+ Notification payloads (e.g., Initial-Contact) are unauthenticated
+ unless they are sent under protection of an ISAKMP SA. A "Security
+ Failures - Bad SPI" ICMP message [SECFAIL] is an interesting
+ alternative, but has the disadvantage of likewise being
+
+
+
+Spencer & Redelmeier [Page 14]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ unauthenticated. It's fundamentally unlikely that there is a simple
+ solution to this, given that almost any way of arranging or checking
+ authentication for such a notification is costly.
+
+ We think the best answer to this is a two-step approach. An
+ unauthenticated Initial-Contact or Security Failures - Bad SPI cannot
+ be taken as a reliable report of a problem, but can be taken as a
+ hint that a problem MIGHT exist. Then there needs to be some
+ reliable way of checking such hints, subject to rate limiting since
+ the checks are likely to be costly (and checking the same connection
+ repeatedly at short intervals is unlikely to be worthwhile anyway).
+ So the rebooted host sends the notification, and the non-rebooted
+ host--which still thinks it has a connection--checks whether the
+ connection still works, and renegotiates if not.
+
+ Also, if an IPsec host which believes it has a connection to another
+ host sees an unsuccessful attempt by that host to negotiate a new
+ one, that is also a hint of possible problems, justifying a check and
+ possible renegotiation. ("Unsuccessful" here means a negotiation
+ failure due to lack of a satisfactory proposal. A failure due to
+ authentication failure suggests a denial-of-service attack by a third
+ party, rather than a genuine problem on the legitimate other end.)
+ As noted in section 4.2, it is possible for negotiations to succeed
+ or fail based on which end initiates them, and some robustness
+ against that is desirable.
+
+ We have not yet decided what form the notification should take. IKE
+ Initial-Contact is an obvious possibility, but has some
+ disadvantages. It does not specify which connection has had
+ difficulties. Also, the specification [IKE section 4.6.3.3] refers
+ to "remote system" and "sending system" without clearly specifying
+ just what "system" means; in the case of a multi-homed host using
+ multiple forms of identification, the question is not trivial.
+ Initial-Contact does have the fairly-decisive advantage that it is
+ likely to convey the right general meaning even to an implementation
+ which does not do things exactly the way ours does.
+
+ A more fundamental difficulty is what form the reliable check takes.
+ What is wanted is an "IKE ping", verifying that the ISAKMP SA is
+ still intact (it being unlikely that IPsec SAs have been lost while
+ the ISAKMP SA has not). The lack of such a facility is a serious
+ failing of IKE. An acknowledged Notification of some sort would be
+ ideal, but there is none at present. Some existing implementations
+ are known to use the private Notification values 30000 as ping and
+ 30002 as ping reply, and that seems the most attractive choice at
+ present. If it is not recognized, there will probably be no reply,
+ and the result will be an unnecessary renegotiation, so this needs
+ strict rate limiting. (Also, when a new connection is set up, it's
+
+
+
+Spencer & Redelmeier [Page 15]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ probably worth determining by experiment whether the other end
+ supports IKE ping, and remembering that.)
+
+ While we think this facility is desirable, and is about the best that
+ can be done with the poor tools available, we have not gotten very
+ far in implementation and cannot comment intelligently about how well
+ it works or interoperates.
+
+6. Misc. IKE Issues
+
+6.1. Groups 1 and 5
+
+ We have dropped support for the first Oakley Group (group 1), despite
+ it being officially mandatory, on the grounds that it is grossly too
+ weak to provide enough randomness for 3DES. There have been some
+ interoperability problems, mostly quite minor: ALMOST everyone
+ supports group 2 as well, although sometimes it has to be explicitly
+ configured.
+
+ We also support the quasi-standard group 5 [GROUPS]. This has not
+ been seriously exercised yet, because historically we offered group 2
+ first and almost everyone accepted it. We have recently changed to
+ offering group 5 first, and no difficulties have been reported.
+
+6.2. To PFS Or Not To PFS
+
+ A persistent small interoperability problem is that the presence or
+ absence of PFS (for keys [IKE, section 5.5]) is neither negotiated
+ nor announced. We have it enabled by default, and successful
+ interoperation often requires having the other end turn it on in
+ their implementation, or having the FreeS/WAN end disable it. Almost
+ everyone supports it, but it's usually not the default, and
+ interoperability is often impossible unless the two ends somehow
+ reach prior agreement on it.
+
+ We do not explicitly support the other flavor of PFS, for identities
+ [IKE, section 8], and this has caused no interoperability problems.
+
+6.3. Debugging Tools, Lack Thereof
+
+ We find IKE lacking in basic debugging tools. Section 5.4, above,
+ notes that an IKE ping would be useful for connectivity verification.
+ It would also be extremely helpful for determining that UDP/500
+ packets get back and forth successfully between the two ends, which
+ is often an important first step in debugging.
+
+ It's also quite common to have IKE negotiate a connection
+ successfully, but to have some firewall along the way blocking ESP.
+
+
+
+Spencer & Redelmeier [Page 16]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ Users find this mysterious and difficult to diagnose. We have no
+ immediate suggestions on what could be done about it.
+
+6.4. Terminology, Vagueness Thereof
+
+ The terminology of IPsec needs work. We feel that both the
+ specifications and user-oriented documentation would be greatly
+ clarified by concise, intelligible names for certain concepts.
+
+ We semi-consistently use "group" for the set of IPsec SAs which are
+ established in one direction by a single Quick Mode negotiation and
+ are used together to process a packet (e.g., an ESP SA plus an AH
+ SA), "connection" for the logical packet path provided by a
+ succession of pairs of groups (each rekeying providing a new pair,
+ one group in each direction), and "keying channel" for the
+ corresponding supervisory path provided by a sequence of ISAKMP SAs.
+
+ We think it's a botch that "PFS" is used to refer to two very
+ different things, but we have no specific new terms to suggest, since
+ we only implement one kind of PFS and thus can just ignore the other.
+
+6.5. A Question of Identity
+
+ One specification problem deserves note: exactly when can an existing
+ phase 1 negotiation be re-used for a new phase 2 negotiation, as IKE
+ [IKE, section 4] specifies? Presumably, when it connects the same
+ two "parties"... but exactly what is a "party"?
+
+ As noted in section 5.4, in cases involving multi-homing and multiple
+ identities, it's not clear exactly what criteria are used for
+ deciding whether the intended far end for a new negotiation is the
+ same one as for a previous negotiation. Is it by Identification
+ Payload? By IP address? Or what?
+
+ We currently use a somewhat-vague notion of "identity", basically
+ what gets sent in Identification Payloads, for this, and this seems
+ to be successful, but we think this needs better specification.
+
+6.6. Opportunistic Encryption
+
+ Further IKE challenges appear in the context of Opportunistic
+ Encryption [OE], but operational experience with it is too limited as
+ yet for us to comment usefully right now.
+
+6.7. Authentication and RSA Keys
+
+ We provide two IKE authentication methods: shared secrets ("pre-
+ shared keys") and RSA digital signatures. (A user-provided add-on
+
+
+
+Spencer & Redelmeier [Page 17]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ package generalizes the latter to limited support for certificates;
+ we have not worked extensively with it ourselves yet and cannot
+ comment on it yet.)
+
+ Shared secrets, despite their administrative difficulties, see
+ considerable use, and are also the method of last resort for
+ interoperability problems.
+
+ For digital signatures, we have taken the somewhat unorthodox
+ approach of using "bare" RSA public keys, either supplied in
+ configuration files or fetched from DNS, rather than getting involved
+ in the complexity of certificates. We encode our RSA public keys
+ using the DNS KEY encoding [DNSRSA] (aka "RFC 2537", although that
+ RFC is now outdated), which has given us no difficulties and which we
+ highly recommend. We have seen two difficulties in connection with
+ RSA keys, however.
+
+ First, while a number of IPsec implementations are able to take
+ "bare" RSA public keys, each one seems to have its own idea of what
+ format should be used for transporting them. We've had little
+ success with interoperability here, mostly because of key-format
+ issues; the implementations generally WILL interoperate successfully
+ if you can somehow get an RSA key into them at all, but that's hard.
+ X.509 certificates seem to be the lowest (!) common denominator for
+ key transfer.
+
+ Second, although the content of RSA public keys has been stable,
+ there has been a small but subtle change over time in the content of
+ RSA private keys. The "internal modulus", used to compute the
+ private exponent "d" from the public exponent "e" (or vice-versa) was
+ originally [RSA] [PKCS1v1] [SCHNEIER] specified to be (p-1)*(q-1),
+ where p and q are the two primes. However, more recent definitions
+ [PKCS1v2] call it "lambda(n)" and define it to be lcm(p-1, q-1); this
+ appears to be a minor optimization. The result is that private keys
+ generated with the new definition often fail consistency checks in
+ implementations using the old definition. Fortunately, it is seldom
+ necessary to move private keys around. Our software now consistently
+ uses the new definition (and thus will accept keys generated with
+ either definition), but our key generator also has an option to
+ generate old-definition keys, for the benefit of users who upgrade
+ their networks incrementally.
+
+6.8. Misc. Snags
+
+ Nonce size is another characteristic that is neither negotiated nor
+ announced but that the two ends must somehow be able to agree on.
+ Our software accepts anything between 8 and 256, and defaults to 16.
+ These numbers were chosen rather arbitrarily, but we have seen no
+
+
+
+Spencer & Redelmeier [Page 18]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ interoperability failures here.
+
+ Nothing in the ISAKMP [ISAKMP] or IKE [IKE] specifications says
+ explicitly that a normal Message ID must be non-zero, but a zero
+ Message ID in fact causes failures.
+
+ Similarly, there is nothing in the specs which says that ISAKMP
+ cookies must be non-zero, but zero cookies will in fact cause
+ trouble.
+
+7. Security Considerations
+
+ Since this document discusses aspects of building robust and
+ interoperable IPsec implementations, security considerations permeate
+ it.
+
+8. References
+
+ [AH] Kent, S., and Atkinson, R., "IP Authentication Header",
+ RFC 2402, Nov 1998.
+
+ [CIPHERS] Pereira, R., and Adams, R., "The ESP CBC-Mode Cipher
+ Algorithms", RFC 2451, Nov 1998.
+
+ [CRACK] Electronic Frontier Foundation, "Cracking DES: Secrets of
+ Encryption Research, Wiretap Politics and Chip Design",
+ O'Reilly 1998, ISBN 1-56592-520-3.
+
+ [DES] Madson, C., and Doraswamy, N., "The ESP DES-CBC Cipher
+ Algorithm", RFC 2405, Nov 1998.
+
+ [DNSRSA] D. Eastlake 3rd, "RSA/SHA-1 SIGs and RSA KEYs in the
+ Domain Name System (DNS)", RFC 3110, May 2001.
+
+ [ESP] Kent, S., and Atkinson, R., "IP Encapsulating Security
+ Payload (ESP)", RFC 2406, Nov 1998.
+
+ [GROUPS] Kivinen, T., and Kojo, M., "More MODP Diffie-Hellman
+ groups for IKE", <draft-ietf-ipsec-ike-modp-
+ groups-04.txt>, 13 Dec 2001 (work in progress).
+
+ [IKE] Harkins, D., and Carrel, D., "The Internet Key Exchange
+ (IKE)", RFC 2409, Nov 1998.
+
+ [IPSEC] Kent, S., and Atkinson, R., "Security Architecture for the
+ Internet Protocol", RFC 2401, Nov 1998.
+
+
+
+
+
+Spencer & Redelmeier [Page 19]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ [ISAKMP] Maughan, D., Schertler, M., Schneider, M., and Turner, J.,
+ "Internet Security Association and Key Management Protocol
+ (ISAKMP)", RFC 2408, Nov 1998.
+
+ [OE] Richardson, M., Redelmeier, D. H., and Spencer, H., "A
+ method for doing opportunistic encryption with IKE",
+ <draft-richardson-ipsec-opportunistic-06.txt>, 21 Feb 2002
+ (work in progress).
+
+ [PKCS1v1] Kaliski, B., "PKCS #1: RSA Encryption, Version 1.5", RFC
+ 2313, March 1998.
+
+ [PKCS1v2] Kaliski, B., and Staddon, J., "PKCS #1: RSA Cryptography
+ Specifications, Version 2.0", RFC 2437, Oct 1998.
+
+ [PFKEY] McDonald, D., Metz, C., and Phan, B., "PF_KEY Key
+ Management API, Version 2", RFC 2367, July 1998.
+
+ [REKEY] Tim Jenkins, "IPsec Re-keying Issues", <draft-jenkins-
+ ipsec-rekeying-06.txt>, 2 May 2000 (draft expired, work no
+ longer in progress).
+
+ [REPLAY] Krywaniuk, A., "Using Isakmp Message Ids for Replay
+ Protection", <draft-krywaniuk-ipsec-antireplay-00.txt>, 9
+ July 2001 (work in progress).
+
+ [RSA] Rivest, R.L., Shamir, A., and Adleman, L., "A Method for
+ Obtaining Digital Signatures and Public-Key
+ Cryptosystems", Communications of the ACM v21n2, Feb 1978,
+ p. 120.
+
+ [SCHNEIER] Bruce Schneier, "Applied Cryptography", 2nd ed., Wiley
+ 1996, ISBN 0-471-11709-9.
+
+ [SECFAIL] Karn, P., and Simpson, W., "ICMP Security Failures
+ Messages", RFC 2521, March 1999.
+
+Authors' Addresses
+
+ Henry Spencer
+ SP Systems
+ Box 280 Stn. A
+ Toronto, Ont. M5W1B2
+ Canada
+
+ henry@spsystems.net
+ 416-690-6561
+
+
+
+
+Spencer & Redelmeier [Page 20]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+ D. Hugh Redelmeier
+ Mimosa Systems Inc.
+ 29 Donino Ave.
+ Toronto, Ont. M4N2W6
+ Canada
+
+ hugh@mimosa.com
+ 416-482-8253
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Spencer & Redelmeier [Page 21]
+
+Internet Draft IKE Implementation Issues 26 Feb 2002
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society 2002. 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 implmentation 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.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Spencer & Redelmeier [Page 22]
+
diff --git a/doc/examples b/doc/examples
deleted file mode 100644
index 315049b04..000000000
--- a/doc/examples
+++ /dev/null
@@ -1,182 +0,0 @@
-# sample connections
-# This file is RCSID $Id: examples,v 1.1 2004/03/15 20:35:21 as Exp $
-
-
-
-# basic configuration
-config setup
- # THIS SETTING MUST BE CORRECT or almost nothing will work.
- interfaces="ipsec0=eth1 ipsec1=ppp0"
- # Debug-logging controls: "none" for (almost) none, "all" for lots.
- klipsdebug=none
- plutodebug=none
- # Manual connections to be started at startup.
- manualstart="test1 test2"
- # Auto connections to be loaded into Pluto at startup.
- plutoload="samplehth samplefire"
- # Auto connections to be started at startup.
- plutostart=samplefire
-
-
-
-# defaults for subsequent connection descriptions
-conn %default
- # How persistent to be in (re)keying negotiations (0 means very).
- keyingtries=0
- # Parameters for manual-keying testing (DON'T USE OPERATIONALLY).
- spi=0x200
- esp=3des-md5-96
- espenckey=0x01234567_89abcdef_02468ace_13579bdf_12345678_9abcdef0
- espauthkey=0x12345678_9abcdef0_2468ace0_13579bdf
- # key lifetime (before automatic rekeying)
- keylife=8h
-
-
-
-# sample connection
-conn sample
- # Left security gateway and subnet behind it.
- left=10.0.0.1
- leftsubnet=172.16.0.0/24
- # Right security gateway and subnet behind it.
- right=10.12.12.1
- rightsubnet=192.168.0.0/24
- # Authorize this connection, but don't actually start it, at startup.
- auto=add
-
-# sample tunnel (manually or automatically keyed)
-# Here we just use ESP for both encryption and authentication, which is
-# the simplest and often the best method.
-conn sample
- # left security gateway (public-network address)
- left=10.0.0.1
- # next hop to reach right
- leftnexthop=10.44.55.66
- # subnet behind left (omit if left end of the tunnel is just the s.g.)
- leftsubnet=172.16.0.0/24
- # right s.g., subnet behind it, and next hop to reach left
- right=10.12.12.1
- rightnexthop=10.88.77.66
- rightsubnet=192.168.0.0/24
- # (manual) SPI number
- spi=0x200
- # (manual) encryption/authentication algorithm and parameters to it
- esp=3des-md5-96
- espenckey=[192 bits]
- espauthkey=[128 bits]
-
-# In the remaining examples, deviations from the sample-tunnel configuration
-# are marked with ###.
-
-# sample host-to-host tunnel (no subnets)
-# Here we assume (for purposes of illustration) that the hosts talk directly
-# to each other, so we don't need next-hop settings.
-conn samplehth
- ### left host (public-network address)
- left=10.0.0.1
- ### next hop to reach right
- leftnexthop=
- ### right host
- right=10.12.12.1
- ### next hop to reach left
- rightnexthop=
- ### (manual) SPI number
- spi=0x300
- # (manual) encryption/authentication algorithm and parameters to it
- esp=3des-md5-96
- espenckey=[192 bits]
- espauthkey=[128 bits]
-
-# sample hybrid tunnel, with a host on one end and a subnet (behind a
-# security gateway) on the other
-# This case is also sometimes called "road warrior".
-conn samplehyb
- ### left host (public-network address)
- left=10.0.0.1
- # next hop to reach right
- leftnexthop=10.44.55.66
- # subnet behind left
- leftsubnet=172.16.0.0/24
- ### right host, and next hop to reach left
- right=10.12.12.1
- rightnexthop=10.88.77.66
- ### (manual) SPI number
- spi=0x400
- # (manual) encryption/authentication algorithm and parameters to it
- esp=3des-md5-96
- espenckey=[192 bits]
- espauthkey=[128 bits]
-
-# sample firewall-penetrating tunnel
-# Here we assume that firewalling is being done on the left side.
-conn samplefire
- # left security gateway (public-network address)
- left=10.0.0.1
- # next hop to reach right
- leftnexthop=10.44.55.66
- # subnet behind left (omit if left end of the tunnel is just the s.g.)
- leftsubnet=172.16.0.0/24
- ### left is firewalling for its subnet
- leftfirewall=yes
- # right s.g., subnet behind it, and next hop to reach left
- right=10.12.12.1
- rightnexthop=10.88.77.66
- rightsubnet=192.168.0.0/24
- ### (manual) SPI number
- spi=0x500
- # (manual) encryption/authentication algorithm and parameters to it
- esp=3des-md5-96
- espenckey=[192 bits]
- espauthkey=[128 bits]
-
-# sample transport-mode connection (which can only be host-to-host)
-# Here we use the whole nine yards, with encryption done by ESP and
-# authentication by AH; this perhaps is slightly preferable for transport
-# mode, where the IP headers are exposed.
-conn sampletm
- ### transport mode rather than tunnel
- type=transport
- ### left host (public-network address)
- left=10.0.0.1
- # next hop to reach right
- leftnexthop=10.44.55.66
- ### right host, and next hop to reach left
- right=10.12.12.1
- rightnexthop=10.88.77.66
- ### (manual) SPI number
- spi=0x600
- ### (manual) encryption algorithm and parameters to it
- esp=3des
- espenckey=[192 bits]
- ### (manual) authentication algorithm and parameters to it
- ah=hmac-md5
- ahkey=[128 bits]
- ### (auto) authentication control
- auth=ah
-
-# sample description with keys split out into a separate section
-# Normally the key section would go in a separate file, with tighter
-# permissions set on it.
-conn samplesep
- # left security gateway (public-network address)
- left=10.0.0.1
- # next hop to reach right
- leftnexthop=10.44.55.66
- # subnet behind left (omit if left end of the tunnel is just the s.g.)
- leftsubnet=172.16.0.0/24
- # right s.g., subnet behind it, and next hop to reach left
- right=10.12.12.1
- rightnexthop=10.88.77.66
- rightsubnet=192.168.0.0/24
- ### (manual) SPI number
- spi=0x700
- # (manual) encryption/authentication algorithm and parameters to it
- esp=3des-md5-96
- also=samplesep-keys
-
-# keys for the previous section
-# Normally this would go in a separate file, picked up using an include line,
-# to allow keeping the keys confidential.
-conn samplesep-keys
- espenckey=[192 bits]
- espauthkey=[128 bits]
diff --git a/doc/impl.notes b/doc/impl.notes
deleted file mode 100644
index 6ea3678b6..000000000
--- a/doc/impl.notes
+++ /dev/null
@@ -1,127 +0,0 @@
-Introduction
-
-This document is some quick notes to sophisticated implementors, on topics
-which are a bit too arcane to be mentioned in the install instructions.
-Beware that it is not updated very often, and may be behind the times.
-This file is RCSID $Id: impl.notes,v 1.1 2004/03/15 20:35:21 as Exp $
-
-
-
-Where are things?
-
-If your kernel sources are not located in /usr/src/linux, or local manual
-pages are not in /usr/local/man/man[1-8], you've got a problem. You may
-be able to get around it to some extent just by modifying the top-level
-Makefile, but we don't promise. For a different manpage location, that
-will probably suffice; for a different kernel location, probably not.
-We'd welcome reports of what needs to be fixed for this.
-
-
-
-Cross-compiling
-
-At the moment, this distribution makes no attempt to support building
-the software on one machine for use on another. That's hard, especially
-since the Linux kernel sources are not set up for it at all.
-
-
-
-One thing at a time
-
-(CAUTION: This is somewhat outdated. It's retained because it may be a
-useful guide for experts. Consult the Makefile for current details.)
-
-If you want to do the build and install one step at a time, instead of
-using the prepackaged make commands like "make menugo", do the following
-instead. (We do things in a slightly different order here, to avoid
-unnecessary directory changing.)
-
-To fit the kernel part of KLIPS into the kernel sources, do:
-
- make insert
-
-(This makes a symbolic link /usr/src/linux/net/ipsec, pointing to the
-KLIPS source directory. It patches some kernel files, where necessary, to
-know about KLIPS and/or to fix bugs. It adds a default configuration to
-the kernel configuration file. Finally, it makes the KLIPS communication
-file, /dev/ipsec, if it's not already there.)
-
-Build the libraries, Pluto, and various user-level utilities:
-
- make programs
-
-Install the Pluto daemon and user-level utilities, and set things up for
-boot-time startup:
-
- make install
-
-Configure the kernel:
-
- cd /usr/src/linux
- make menuconfig # (or xconfig, or whatever)
-
-See the configuration step of INSTALL for details of what to do within
-the configuration program. Don't forget to save the results.
-
-Go through the usual kernel make process (still in /usr/src/linux):
-
- make dep clean zImage
-
-Caution: the Linux kernel Makefiles are not always careful about checking
-for errors. We recommend capturing the output of this step and searching
-it for any occurrence of "error", "Error", etc. The details of how to do
-so are unfortunately somewhat shell-dependent, although if you are using
-the standard shell (rather than csh, tcsh, etc.), this would do:
-
- make dep clean zImage 2>&1 | tee junk
- egrep -i error junk # no output is good output
-
-(One glitch here is that the word "error" can sometimes occur legitimately
-in the make output. For example, the kernel math emulation package has a
-source file "errors.c". Some judgement is required to ignore such false
-alarms.) The prepackaged make commands do all this for you.
-
-If your kernel is using loadable modules, you'll also need to do:
-
- make modules
-
-Now you need to install the resulting kernel. If you're not using the
-kernel's "make install" -- many people aren't -- then you need to do your
-usual install procedure. You might want to read doc/kernel.notes, which
-recounts some of our experiences with RedHat 5.2 kernel installation in
-particular.
-
-If "make install" is good enough for you, then:
-
- make install
-
-(Same comments on error checking as in previous step.) If your kernel is
-using loadable modules, you'll also need to do:
-
- make modules_install
-
-Finally, go back to INSTALL for the remaining steps.
-
-
-
-Klips as a module
-
-It is possible to run Klips as a kernel module, meaning that it does not
-have to be loaded until needed. Formerly this was necessary, in fact,
-because Klips wouldn't run any other way. Now it will, and we recommend
-static linking ("y", not "m", to the configuration question) for security.
-Klips is not terribly large (tens of KB, not hundreds) and should not
-cause size problems unless your kernel is already pushing the limits.
-
-However, Klips does still run as a module, if you want (although beware
-that we don't test this option very often). "ipsec setup start" and
-"ipsec setup stop" load and unload it as appropriate, and you should not
-need to do anything about that yourself.
-
-
-
-Old Red Hats
-
-Our development is currently on a mix of Red Hat 6.2 and 7.1, with 6.2
-fading fast. Our older Red Hats have been retired, and although FreeS/WAN
-should still work on them, we no longer make any attempt to ensure that.
diff --git a/doc/ipsec.conf.2_to_1 b/doc/ipsec.conf.2_to_1
deleted file mode 100644
index 3100ed78d..000000000
--- a/doc/ipsec.conf.2_to_1
+++ /dev/null
@@ -1,22 +0,0 @@
-version 2
-# If you put the preceding line in front of a 1.x ipsec.conf,
-# it should work within 2.x.
-
-
-# Merge the following sections with your existing config setup
-# and conn %default.
-# Allot these values to any you have not explictly defined.
-
-config setup
- interfaces=%none # new default is %defaultroute
- plutoload=%none # new default is %search
- plutostart=%none # new default is %search
-
-conn %default
- uniqueids=no # new default is yes
- keyingtries=3 # new default is %forever
- disablearrivalcheck=yes # new default is no
- authby=secret # new default is rsasig
- leftrsasigkey=%none # new default %dnsondemand
- rightrsasigkey=%none # new default %dnsondemand
-
diff --git a/doc/kernel.notes b/doc/kernel.notes
deleted file mode 100644
index 675e80be3..000000000
--- a/doc/kernel.notes
+++ /dev/null
@@ -1,173 +0,0 @@
-Notes on Red Hat 5.2 kernel installation (See Addendum for RH6.1)
-=================================================================
-
-Warning: We (the FreeS/WAN Project http://www.xs4all.nl/~freeswan/)
-had nothing to do with designing the kernel installation process. This
-document explains some tricky points that we wish we had been told.
-We don't know if these notes apply to systems other than Red Hat 5.2.
-This is meant as a supplement to other kernel install guides (such as
-the Red Hat 5.2 Installation Guide section 11.6).
-
-Goal: install a new kernel on RH5.2 in such a way that it doesn't
-interfere with any other kernels. This should be repeatable: each new
-kernel should have this property. Each should remain bootable.
-
-Problem: there are several components to a kernel, and each must be
-segregated. How are the parts kept apart? How are they found?
-
-All the parts live in the file system, so it all comes down to
-pathnames. Well, except for the fiddly bits in /etc/lilo.conf. What
-are the parts?
-
- /lib/modules/VER/ directory for kernel modules
- /boot/vmlinux-VER the kernel
- /boot/System.map-VER the kernel symbol table
- /boot/initrd-VER.img the initial ramdisk (for modules needed
- at boot time -- usually not necessary)
- /boot/boot.b the second-stage loader
- /boot/map the map file, an index into system index for
- all files used by boot loader (all kernels,
- all initrds, perhaps /boot/boot.b, and itself)
-
-This list does not include /boot/module-info-VER. That is supplied
-by RedHat, and it isn't clear to me how to build it or why.
-
-In each entry, I've used "VER" to signify a version number. For
-RH-supplied kernels, these look like 2.0.36-0.7 (the original 5.2) or
-2.0.36-3 (the kernel updates).
-
-There are also symbolic links:
- /lib/modules/preferred created by /etc/rc.d/rc.sysinit
- /boot/System.map created by /etc/rc.d/rc.sysinit
- /boot/module-info created by /etc/rc.d/rc.sysinit
- /vmlinuz created by ???
-I don't know when the /vmlinuz symlink is set up and I don't know
-for what it is used.
-
-If you follow the RH procedures, documented in 11.6 of their Installation
-Guide, all your VERs will be 2.0.36. This is very bad: all your builds
-will step on each other. Worse, your new module directory will be half
-picked up when you boot a stock RH kernel binary!
-
-It is important to know how the various parts of the built kernel are
-found at booting.
-
-- the kernel path is specified in the image= option in lilo.conf.
- (Lilo.conf may specify several and one is selected at boot time
- by default or user selection.) The kernel is loaded by the
- boot loader.
-
-- The initial ramdisk is a per-image option (initrd=) specified in
- lilo.conf. (It isn't described in the RH5.2 lilo.conf(5) manpage!).
- The initial ramdisk is loaded into RAM by the boot loader.
-
-- Since the boot loader doesn't know about the file system, it needs a
- map to figure out which absolute disk blocks to load, and where.
- This is /boot/map. It is built by the lilo command (also known as
- the map installer). It will have indices for the all the kernels
- that can be booted, all their initial ram disks, perhaps
- /boot/boot.b, and itself. This is why moving the blocks of these
- files throws off the boot loader -- lilo must be rerun after even a
- cp command to one of them.
-
-- the modules directory is found two different ways. Unfortunately,
- they don't mesh properly:
-
- + at boot time, /etc/rc.d/rc.sysinit tries to figure out the correct
- subdirectory of /lib/modules, using the .rhkmvtag trick (see
- later). It then builds a symlink /lib/modules/preferred to
- record this. It also invokes depmod to build the module
- dependency info. At the same time, it creates the symlinks
- /boot/System.map and /boot/module-info, using the inferred
- value for VER!
-
- + modprobe and friends stupidly look first in /lib/modules/2.0.36
- (more precisely, /lib/modules/`uname -r`) and then in
- /lib/modules/preferred. So if there is a /lib/modules/2.0.36 and
- it is the wrong one, you are in trouble.
-
- If there is no /lib/modules/2.0.36, then both searches above will
- agree (a very Good Thing). So I recommend strongly that you not
- have a /lib/boot/2.0.36 at boot time. Unfortunately, you will get
- one during the kernel install process. Be sure to rename it. I
- suggest using 2.0.36-x (for some unique x) as VER.
-
-- Red Hat supplied /lib/modules/VER directories contain a hidden file
- .rhkmvtag. This file contains exactly one line. This line is
- exactly the same as the contents of /proc/version while the
- corresponding kernel is running. For the stock kernel, the line is:
-Linux version 2.0.36 (root@porky.redhat.com) (gcc version 2.7.2.3) #1 Tue Dec 29 13:11:13 EST 1998
-
-- At boot time, /etc/rc.d/rc.sysinit uses the .rhkmvtag files to
- figure out which of the /lib/modules/* directories matches the
- kernel. If it could figure out the directory, it uses this
- information to set the symlinks mentioned above. It then runs
- depmod to build the module dependency information (in
- /lib/modules/preferred/modules.dep, if it created the
- /lib/modules/preferred symlink). I recommend looking at the code.
-
-- The documented kernel install procedures DO NOT fill in the
- .rhkmvtag file for the new modules directory! So you should do so
- by hand. You have to figure out what the contents should be. Here
- is is a command that will do the job, assuming that
- /usr/src/linux/vmlinux is the kernel associated with
- /lib/modules/2.0.36/:
-
- strings /usr/src/linux/vmlinux \
- | grep 'x version' >/lib/modules/2.0.36/.rhkmvtag
-
-I've recommended (above) that you use 2.0.36-x for VER when you install
-a kernel. What should x be? I have found that there is a hidden file
-/usr/src/linux/.version which contains a counter that gets incremented
-whenever you do a "make install" in the kernel (see target
-newversion). There are some other times that it gets incremented, but
-I think that it all works out. It also gets incorporated into the
-resulting kernel's /proc/version, prefixed with ``#''. This makes it
-a natural.
-
-Here is a script to do the recommended renaming:
-
- # VER will eventually need to be updated
- VER=2.0.36
- VERX=${VER}-`cat /usr/src/linux/.version`
-
- strings /usr/src/linux/vmlinux | grep 'x version' >/lib/modules/$VER/.rhkmvtag
- mv /lib/modules/$VER /lib/modules/$VERX
- mv /boot/System.map-$VER /boot/System.map-$VERX
- mv /boot/vmlinuz-$VER /boot/vmlinuz-$VERX
-
-And, if an initrd has been built (usually it is best to arrange not to
-use one -- see the Red Hat Installation Guide):
-
- /sbin/mkinitrd /boot/initrd-$VERX.img $VERX
-
-Remember: a new lilo.conf entry is needed for the new kernel, and then
-the lilo command will need to be rerun.
-
-Now that kernel installs don't overwrite the results of previous ones,
-you will need to manually delete the components and their lilo entry
-to get rid of them.
-
-Please send comments, additions, and corrections to:
-
-Hugh Redelmeier
-hugh@mimosa.com voice: +1 416 482-8253
-
-
-Addendum: Red Hat 6.1
-=====================
-
-The kernel supplied with RH6.1 kernel is out of date, so you might
-wish to use a newer one.
-
-Much of the description for 5.2 still applies, but the procedure is
-quite different because the .version file is no longer used. Instead,
-the top-level Makefile contains a definition EXTRAVERSION which adds a
-qualifier to the version for most purposes. No manual renaming is
-required.
-
-Before building the kernel, change EXTRAVERSION by editing
-/usr/src/linux/Makefile, and make an appropriate entry in /etc/lilo.conf.
-
-EXTRAVERSION is a feature of the standard kernel sources, not just the
-ones supplied by Red Hat.
diff --git a/doc/src/draft-richardson-ipsec-opportunistic.html b/doc/src/draft-richardson-ipsec-opportunistic.html
new file mode 100644
index 000000000..87a13365a
--- /dev/null
+++ b/doc/src/draft-richardson-ipsec-opportunistic.html
@@ -0,0 +1,2456 @@
+<html><head><title>Opportunistic Encryption using The Internet Key Exchange (IKE)</title>
+<STYLE type='text/css'>
+ .title { color: #990000; font-size: 22px; line-height: 22px; font-weight: bold; text-align: right;
+ font-family: helvetica, arial, sans-serif }
+ .filename { color: #666666; font-size: 18px; line-height: 28px; font-weight: bold; text-align: right;
+ font-family: helvetica, arial, sans-serif }
+ p.copyright { color: #000000; font-size: 10px;
+ font-family: verdana, charcoal, helvetica, arial, sans-serif }
+ p { margin-left: 2em; margin-right: 2em; }
+ li { margin-left: 3em; }
+ ol { margin-left: 2em; margin-right: 2em; }
+ ul.text { margin-left: 2em; margin-right: 2em; }
+ pre { margin-left: 3em; color: #333333 }
+ ul.toc { color: #000000; line-height: 16px;
+ font-family: verdana, charcoal, helvetica, arial, sans-serif }
+ H3 { color: #333333; font-size: 16px; line-height: 16px; font-family: helvetica, arial, sans-serif }
+ H4 { color: #000000; font-size: 14px; font-family: helvetica, arial, sans-serif }
+ TD.header { color: #ffffff; font-size: 10px; font-family: arial, helvetica, san-serif; valign: top }
+ TD.author-text { color: #000000; font-size: 10px;
+ font-family: verdana, charcoal, helvetica, arial, sans-serif }
+ TD.author { color: #000000; font-weight: bold; margin-left: 4em; font-size: 10px; font-family: verdana, charcoal, helvetica, arial, sans-serif }
+ A:link { color: #990000; font-weight: bold;
+ font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif }
+ A:visited { color: #333333; font-weight: bold;
+ font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif }
+ A:name { color: #333333; font-weight: bold;
+ font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif }
+ .link2 { color:#ffffff; font-weight: bold; text-decoration: none;
+ font-family: monaco, charcoal, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif;
+ font-size: 9px }
+ .RFC { color:#666666; font-weight: bold; text-decoration: none;
+ font-family: monaco, charcoal, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif;
+ font-size: 9px }
+ .hotText { color:#ffffff; font-weight: normal; text-decoration: none;
+ font-family: charcoal, monaco, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif;
+ font-size: 9px }
+</style>
+</head>
+<body bgcolor="#ffffff" text="#000000" alink="#000000" vlink="#666666" link="#990000">
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<table width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table width="100%" border="0" cellpadding="2" cellspacing="1">
+<tr valign="top"><td width="33%" bgcolor="#666666" class="header">Independent submission</td><td width="33%" bgcolor="#666666" class="header">M. Richardson</td></tr>
+<tr valign="top"><td width="33%" bgcolor="#666666" class="header">Internet-Draft</td><td width="33%" bgcolor="#666666" class="header">SSW</td></tr>
+<tr valign="top"><td width="33%" bgcolor="#666666" class="header">Expires: November 19, 2003</td><td width="33%" bgcolor="#666666" class="header">D. Redelmeier</td></tr>
+<tr valign="top"><td width="33%" bgcolor="#666666" class="header">&nbsp;</td><td width="33%" bgcolor="#666666" class="header">Mimosa</td></tr>
+<tr valign="top"><td width="33%" bgcolor="#666666" class="header">&nbsp;</td><td width="33%" bgcolor="#666666" class="header">May 21, 2003</td></tr>
+</table></td></tr></table>
+<div align="right"><font face="monaco, MS Sans Serif" color="#990000" size="+3"><b><br><span class="title">Opportunistic Encryption using The Internet Key Exchange (IKE)</span></b></font></div>
+<div align="right"><font face="monaco, MS Sans Serif" color="#666666" size="+2"><b><span class="filename">draft-richardson-ipsec-opportunistic-11.txt</span></b></font></div>
+<font face="verdana, helvetica, arial, sans-serif" size="2">
+
+<h3>Status of this Memo</h3>
+<p>
+This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026.</p>
+<p>
+Internet-Drafts are working documents of the Internet Engineering
+Task Force (IETF), its areas, and its working groups.
+Note that other groups may also distribute working documents as
+Internet-Drafts.</p>
+<p>
+Internet-Drafts are draft documents valid for a maximum of six months
+and may be updated, replaced, or obsoleted by other documents at any time.
+It is inappropriate to use Internet-Drafts as reference material or to cite
+them other than as "work in progress."</p>
+<p>
+The list of current Internet-Drafts can be accessed at
+<a href='http://www.ietf.org/ietf/1id-abstracts.txt'>http://www.ietf.org/ietf/1id-abstracts.txt</a>.</p>
+<p>
+The list of Internet-Draft Shadow Directories can be accessed at
+<a href='http://www.ietf.org/shadow.html'>http://www.ietf.org/shadow.html</a>.</p>
+<p>
+This Internet-Draft will expire on November 19, 2003.</p>
+
+<h3>Copyright Notice</h3>
+<p>
+Copyright (C) The Internet Society (2003). All Rights Reserved.</p>
+
+<h3>Abstract</h3>
+
+<p>
+This document describes opportunistic encryption (OE) using the Internet Key
+Exchange (IKE) and IPsec.
+Each system administrator adds new
+resource records to his or her Domain Name System (DNS) to support
+opportunistic encryption. The objective is to allow encryption for secure communication without
+any pre-arrangement specific to the pair of systems involved.
+
+</p>
+<p>
+DNS is used to distribute the public keys of each
+system involved. This is resistant to passive attacks. The use of DNS
+Security (DNSSEC) secures this system against active attackers as well.
+
+</p>
+<p>
+As a result, the administrative overhead is reduced
+from the square of the number of systems to a linear dependence, and it becomes
+possible to make secure communication the default even
+when the partner is not known in advance.
+
+</p>
+<p>
+This document is offered up as an Informational RFC.
+
+</p><a name="toc"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<h3>Table of Contents</h3>
+<ul compact class="toc">
+<b><a href="#anchor1">1.</a>&nbsp;
+Introduction<br></b>
+<b><a href="#anchor6">2.</a>&nbsp;
+Overview<br></b>
+<b><a href="#anchor13">3.</a>&nbsp;
+Specification<br></b>
+<b><a href="#anchor31">4.</a>&nbsp;
+Impacts on IKE<br></b>
+<b><a href="#anchor38">5.</a>&nbsp;
+DNS issues<br></b>
+<b><a href="#anchor42">6.</a>&nbsp;
+Network address translation interaction<br></b>
+<b><a href="#anchor46">7.</a>&nbsp;
+Host implementations<br></b>
+<b><a href="#anchor47">8.</a>&nbsp;
+Multi-homing<br></b>
+<b><a href="#anchor48">9.</a>&nbsp;
+Failure modes<br></b>
+<b><a href="#anchor52">10.</a>&nbsp;
+Unresolved issues<br></b>
+<b><a href="#anchor54">11.</a>&nbsp;
+Examples<br></b>
+<b><a href="#securityconsiderations">12.</a>&nbsp;
+Security considerations<br></b>
+<b><a href="#anchor79">13.</a>&nbsp;
+IANA Considerations<br></b>
+<b><a href="#anchor80">14.</a>&nbsp;
+Acknowledgments<br></b>
+<b><a href="#rfc.references1">&#167;</a>&nbsp;
+Normative references<br></b>
+<b><a href="#rfc.authors">&#167;</a>&nbsp;
+Authors' Addresses<br></b>
+<b><a href="#rfc.copyright">&#167;</a>&nbsp;
+Full Copyright Statement<br></b>
+</ul>
+<br clear="all">
+
+<a name="anchor1"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.1"></a><h3>1.&nbsp;Introduction</h3>
+
+<a name="rfc.section.1.1"></a><h4><a name="anchor2">1.1</a>&nbsp;Motivation</h4>
+
+<p>
+The objective of opportunistic encryption is to allow encryption without
+any pre-arrangement specific to the pair of systems involved. Each
+system administrator adds
+public key information to DNS records to support opportunistic
+encryption and then enables this feature in the nodes' IPsec stack.
+Once this is done, any two such nodes can communicate securely.
+
+</p>
+<p>
+This document describes opportunistic encryption as designed and
+mostly implemented by the Linux FreeS/WAN project.
+For project information, see http://www.freeswan.org.
+
+</p>
+<p>
+The Internet Architecture Board (IAB) and Internet Engineering
+Steering Group (IESG) have taken a strong stand that the Internet
+should use powerful encryption to provide security and
+privacy <a href="#RFC1984">[4]</a>.
+The Linux FreeS/WAN project attempts to provide a practical means to implement this policy.
+
+</p>
+<p>
+The project uses the IPsec, ISAKMP/IKE, DNS and DNSSEC
+protocols because they are
+standardized, widely available and can often be deployed very easily
+without changing hardware or software or retraining users.
+
+</p>
+<p>
+The extensions to support opportunistic encryption are simple. No
+changes to any on-the-wire formats are needed. The only changes are to
+the policy decision making system. This means that opportunistic
+encryption can be implemented with very minimal changes to an existing
+IPsec implementation.
+
+</p>
+<p>
+Opportunistic encryption creates a "fax effect". The proliferation
+of the fax machine was possible because it did not require that everyone
+buy one overnight. Instead, as each person installed one, the value
+of having one increased - as there were more people that could receive faxes.
+Once opportunistic encryption is installed it
+automatically recognizes
+other boxes using opportunistic encryption, without any further configuration
+by the network
+administrator. So, as opportunistic encryption software is installed on more
+boxes, its value
+as a tool increases.
+
+</p>
+<p>
+This document describes the infrastructure to permit deployment of
+Opportunistic Encryption.
+
+</p>
+<p>
+The term S/WAN is a trademark of RSA Data Systems, and is used with permission
+by this project.
+
+</p>
+<a name="rfc.section.1.2"></a><h4><a name="anchor3">1.2</a>&nbsp;Types of network traffic</h4>
+
+<p>
+ To aid in understanding the relationship between security processing and IPsec
+ we divide network traffic into four categories:
+
+<blockquote class="text"><dl>
+<dt>* Deny:</dt>
+<dd> networks to which traffic is always forbidden.
+</dd>
+<dt>* Permit:</dt>
+<dd> networks to which traffic in the clear is permitted.
+</dd>
+<dt>* Opportunistic tunnel:</dt>
+<dd> networks to which traffic is encrypted if possible, but otherwise is in the clear
+ or fails depending on the default policy in place.
+
+</dd>
+<dt>* Configured tunnel:</dt>
+<dd> networks to which traffic must be encrypted, and traffic in the clear is never permitted.
+</dd>
+</dl></blockquote><p>
+</p>
+<p>
+Traditional firewall devices handle the first two categories. No authentication is required.
+The permit policy is currently the default on the Internet.
+
+</p>
+<p>
+This document describes the third category - opportunistic tunnel, which is
+proposed as the new default for the Internet.
+
+</p>
+<p>
+ Category four, encrypt traffic or drop it, requires authentication of the
+ end points. As the number of end points is typically bounded and is typically
+ under a single authority, arranging for distribution of
+ authentication material, while difficult, does not require any new
+ technology. The mechanism described here provides an additional way to
+ distribute the authentication materials, that of a public key method that does not
+ require deployment of an X.509 based infrastructure.
+
+</p>
+<p>
+Current Virtual Private Networks can often be replaced by an "OE paranoid"
+policy as described herein.
+
+</p>
+<a name="rfc.section.1.3"></a><h4><a name="anchor4">1.3</a>&nbsp;Peer authentication in opportunistic encryption</h4>
+
+<p>
+ Opportunistic encryption creates tunnels between nodes that
+ are essentially strangers. This is done without any prior bilateral
+ arrangement.
+ There is, therefore, the difficult question of how one knows to whom one is
+ talking.
+
+</p>
+<p>
+ One possible answer is that since no useful
+ authentication can be done, none should be tried. This mode of operation is
+ named "anonymous encryption". An active man-in-the-middle attack can be
+ used to thwart the privacy of this type of communication.
+ Without peer authentication, there is no way to prevent this kind of attack.
+
+</p>
+<p>
+Although a useful mode, anonymous encryption is not the goal of this
+project. Simpler methods are available that can achieve anonymous
+encryption only, but authentication of the peer is a desireable goal.
+The latter is achieved through key distribution in DNS, leveraging upon
+the authentication of the DNS in DNSSEC.
+
+</p>
+<p>
+ Peers are, therefore, authenticated with DNSSEC when available. Local policy
+determines how much trust to extend when DNSSEC is not available.
+
+</p>
+<p>
+ However, an essential premise of building private connections with
+ strangers is that datagrams received through opportunistic tunnels
+ are no more special than datagrams that arrive in the clear.
+ Unlike in a VPN, these datagrams should not be given any special
+ exceptions when it comes to auditing, further authentication or
+ firewalling.
+
+</p>
+<p>
+ When initiating outbound opportunistic encryption, local
+ configuration determines what happens if tunnel setup fails. It may be that
+ the packet goes out in the clear, or it may be dropped.
+
+</p>
+<a name="rfc.section.1.4"></a><h4><a name="anchor5">1.4</a>&nbsp;Use of RFC2119 terms</h4>
+
+<p>
+ 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 <a href="#RFC2119">[5]</a>
+</p>
+<a name="anchor6"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.2"></a><h3>2.&nbsp;Overview</h3>
+
+<a name="rfc.section.2.1"></a><h4><a name="anchor7">2.1</a>&nbsp;Reference diagram</h4>
+<br><hr size="1" shade="0">
+<a name="networkdiagram"></a>
+
+<p>The following network diagram is used in the rest of
+ this document as the canonical diagram:
+</p></font><pre>
+ [Q] [R]
+ . . AS2
+ [A]----+----[SG-A].......+....+.......[SG-B]-------[B]
+ | ......
+ AS1 | ..PI..
+ | ......
+ [D]----+----[SG-D].......+....+.......[C] AS3
+
+
+ </pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+
+<p>
+</p><table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Reference Network Diagram&nbsp;</b></font><br></td></tr></table><hr size="1" shade="0">
+
+<p>
+ In this diagram, there are four end-nodes: A, B, C and D.
+ There are three gateways, SG-A, SG-B, SG-D. A, D, SG-A and SG-D are part
+ of the same administrative authority, AS1. SG-A and SG-D are on two different exit
+ paths from organization 1. SG-B/B is an independent organization, AS2.
+ Nodes Q and R are nodes on the Internet. PI is the Public
+ Internet ("The Wild").
+
+</p>
+<a name="rfc.section.2.2"></a><h4><a name="anchor8">2.2</a>&nbsp;Terminology</h4>
+
+<p>
+ The following terminology is used in this document:
+
+</p>
+<blockquote class="text"><dl>
+<dt>Security gateway:</dt>
+<dd> a system that performs IPsec tunnel
+ mode encapsulation/decapsulation. [SG-x] in the diagram.
+</dd>
+<dt>Alice:</dt>
+<dd> node [A] in the diagram. When an IP address is needed, this is 192.1.0.65.
+</dd>
+<dt>Bob:</dt>
+<dd> node [B] in the diagram. When an IP address is needed, this is 192.2.0.66.
+</dd>
+<dt>Carol:</dt>
+<dd> node [C] in the diagram. When an IP address is needed, this is 192.1.1.67.
+</dd>
+<dt>Dave:</dt>
+<dd> node [D] in the diagram. When an IP address is needed, this is 192.3.0.68.
+</dd>
+<dt>SG-A:</dt>
+<dd> Alice's security gateway. Internally it is 192.1.0.1, externally it is 192.1.1.4.
+</dd>
+<dt>SG-B:</dt>
+<dd> Bob's security gateway. Internally it is 192.2.0.1, externally it is 192.1.1.5.
+</dd>
+<dt>SG-D:</dt>
+<dd> Dave's security gateway. Also Alice's backup security gateway. Internally it is 192.3.0.1, externally it is 192.1.1.6.
+</dd>
+<dt>-</dt>
+<dd> A single dash represents clear-text datagrams.
+</dd>
+<dt>=</dt>
+<dd> An equals sign represents phase 2 (IPsec) cipher-text
+ datagrams.
+</dd>
+<dt>~</dt>
+<dd> A single tilde represents clear-text phase 1 datagrams.
+</dd>
+<dt>#</dt>
+<dd> A hash sign represents phase 1 (IKE) cipher-text
+ datagrams.
+</dd>
+<dt>.</dt>
+<dd> A period represents an untrusted network of unknown
+ type.
+</dd>
+<dt>Configured tunnel:</dt>
+<dd> a tunnel that
+ is directly and deliberately hand configured on participating gateways.
+ Configured tunnels are typically given a higher level of
+ trust than opportunistic tunnels.
+</dd>
+<dt>Road warrior tunnel:</dt>
+<dd> a configured tunnel connecting one
+ node with a fixed IP address and one node with a variable IP address.
+ A road warrior (RW) connection must be initiated by the
+ variable node, since the fixed node cannot know the
+ current address for the road warrior.
+</dd>
+<dt>Anonymous encryption:</dt>
+<dd>
+ the process of encrypting a session without any knowledge of who the
+ other parties are. No authentication of identities is done.
+</dd>
+<dt>Opportunistic encryption:</dt>
+<dd>
+ the process of encrypting a session with authenticated knowledge of
+ who the other parties are.
+</dd>
+<dt>Lifetime:</dt>
+<dd>
+ the period in seconds (bytes or datagrams) for which a security
+ association will remain alive before needing to be re-keyed.
+</dd>
+<dt>Lifespan:</dt>
+<dd>
+ the effective time for which a security association remains useful. A
+ security association with a lifespan shorter than its lifetime would
+ be removed when no longer needed. A security association with a
+ lifespan longer than its lifetime would need to be re-keyed one or
+ more times.
+</dd>
+<dt>Phase 1 SA:</dt>
+<dd> an ISAKMP/IKE security association sometimes
+ referred to as a keying channel.
+</dd>
+<dt>Phase 2 SA:</dt>
+<dd> an IPsec security association.
+</dd>
+<dt>Tunnel:</dt>
+<dd> another term for a set of phase 2 SA (one in each direction).
+</dd>
+<dt>NAT:</dt>
+<dd> Network Address Translation
+ (see <a href="#RFC2663">[20]</a>).
+</dd>
+<dt>NAPT:</dt>
+<dd> Network Address and Port Translation
+ (see <a href="#RFC2663">[20]</a>).
+</dd>
+<dt>AS:</dt>
+<dd> an autonomous system (AS) is a group of systems (a network) that
+ are under the administrative control of a single organization.
+</dd>
+<dt>Default-free zone:</dt>
+<dd>
+ a set of routers that maintain a complete set of routes to
+ all currently reachable destinations. Having such a list, these routers
+ never make use of a default route. A datagram with a destination address
+ not matching any route will be dropped by such a router.
+
+</dd>
+</dl></blockquote><p>
+<a name="rfc.section.2.3"></a><h4><a name="anchor9">2.3</a>&nbsp;Model of operation</h4>
+
+<p>
+The opportunistic encryption security gateway (OE gateway) is a regular
+gateway node as described in <a href="#RFC0791">[2]</a> section 2.4 and
+<a href="#RFC1009">[3]</a> with the additional capabilities described here and
+in <a href="#RFC2401">[7]</a>.
+The algorithm described here provides a way to determine, for each datagram,
+whether or not to encrypt and tunnel the datagram. Two important things
+that must be determined are whether or not to encrypt and tunnel and, if
+so, the destination address or name of the tunnel end point which should be used.
+
+</p>
+<a name="rfc.section.2.3.1"></a><h4><a name="anchor10">2.3.1</a>&nbsp;Tunnel authorization</h4>
+
+<p>
+The OE gateway determines whether or not to create a tunnel based on
+the destination address of each packet. Upon receiving a packet with a destination
+address not recently seen, the OE gateway performs a lookup in DNS for an
+authorization resource record (see <a href="#TXT">Use of TXT delegation record</a>). The record is located using
+the IP address to perform a search in the in-addr.arpa (IPv4) or ip6.arpa
+(IPv6) maps. If an authorization record is found, the OE gateway
+interprets this as a request for a tunnel to be formed.
+
+</p>
+<a name="rfc.section.2.3.2"></a><h4><a name="anchor11">2.3.2</a>&nbsp;Tunnel end-point discovery</h4>
+
+<p>
+The authorization resource record also provides the address or name of the tunnel
+end point which should be used.
+
+</p>
+<p>
+The record may also provide the public RSA key of the tunnel end point
+itself. This is provided for efficiency only. If the public RSA key is not
+present, the OE gateway performs a second lookup to find a KEY
+resource record for the end point address or name.
+
+</p>
+<p>
+Origin and integrity protection of the resource records is provided by
+DNSSEC (<a href="#RFC2535">[16]</a>). <a href="#nodnssec">Restriction on unauthenticated TXT delegation records</a>
+documents an optional restriction on the tunnel end point if DNSSEC signatures
+are not available for the relevant records.
+
+</p>
+<a name="rfc.section.2.3.3"></a><h4><a name="anchor12">2.3.3</a>&nbsp;Caching of authorization results</h4>
+
+<p>
+The OE gateway maintains a cache, in the forwarding plane, of
+source/destination pairs for which opportunistic encryption has been
+attempted. This cache maintains a record of whether or not OE was
+successful so that subsequent datagrams can be forwarded properly
+without additional delay.
+
+</p>
+<p>
+Successful negotiation of OE instantiates a new security association.
+Failure to negotiate OE results in creation of a
+forwarding policy entry either to drop or transmit in the clear future
+datagrams. This negative cache is necessary to avoid the possibly lengthy process of repeatedly looking
+up the same information.
+
+</p>
+<p>
+The cache is timed out periodically, as described in <a href="#teardown">Renewal and teardown</a>.
+This removes entries that are no longer
+being used and permits the discovery of changes in authorization policy.
+
+</p>
+<a name="anchor13"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.3"></a><h3>3.&nbsp;Specification</h3>
+
+<p>
+The OE gateway is modeled to have a forwarding plane and a control
+plane. A control channel, such as PF_KEY, connects the two planes.
+(See <a href="#RFC2367">[6]</a>.)
+The forwarding plane performs per datagram operations. The control plane
+contains a keying
+daemon, such as ISAKMP/IKE, and performs all authorization, peer authentication and
+key derivation functions.
+
+</p>
+<a name="rfc.section.3.1"></a><h4><a name="anchor14">3.1</a>&nbsp;Datagram state machine</h4>
+
+<p>
+Let the OE gateway maintain a collection of objects -- a superset of the
+security policy database (SPD) specified in <a href="#RFC2401">[7]</a>. For
+each combination of source and destination address, an SPD
+object exists in one of five following states.
+Prior to forwarding each datagram, the
+responder uses the source and destination addresses to pick an entry from the SPD.
+The SPD then determines if and how the packet is forwarded.
+
+</p>
+<a name="rfc.section.3.1.1"></a><h4><a name="anchor15">3.1.1</a>&nbsp;Non-existent policy</h4>
+
+<p>
+If the responder does not find an entry, then this policy applies.
+The responder creates an entry with an initial state of "hold policy" and requests
+keying material from the keying daemon. The responder does not forward the datagram,
+rather it attaches the datagram to the SPD entry as the "first" datagram and retains it
+for eventual transmission in a new state.
+
+
+</p>
+<a name="rfc.section.3.1.2"></a><h4><a name="anchor16">3.1.2</a>&nbsp;Hold policy</h4>
+
+<p>
+The responder requests keying material. If the interface to the keying
+system is lossy (PF_KEY, for instance, can be), the implementation
+SHOULD include a mechanism to retransmit the
+keying request at a rate limited to less than 1 request per second.
+The responder does not forward the datagram. It attaches the
+datagram to the SPD entry as the "last" datagram where it is retained
+for eventual transmission. If there is
+a datagram already so stored, then that already stored datagram is discarded.
+
+</p>
+<p>
+Because the "first" datagram is probably a TCP SYN packet, the
+responder retains the "first" datagram in an attempt to avoid waiting for a
+TCP retransmit. The responder retains the "last"
+datagram in deference to streaming protocols that find it useful to know
+how much data has been lost. These are recommendations to
+decrease latency. There are no operational requirements for this.
+
+</p>
+<a name="rfc.section.3.1.3"></a><h4><a name="anchor17">3.1.3</a>&nbsp;Pass-through policy</h4>
+
+<p>
+The responder forwards the datagram using the normal forwarding table.
+The responder enters this state only by command from the keying daemon,
+and upon entering this state, also forwards the "first" and "last" datagrams.
+
+</p>
+<a name="rfc.section.3.1.4"></a><h4><a name="anchor18">3.1.4</a>&nbsp;Deny policy</h4>
+
+<p>
+The responder discards the datagram. The responder enters this state only by
+command
+from the keying daemon, and upon entering this state, discards the "first"
+and "last" datagrams.
+Local administration decides if further datagrams cause ICMP messages
+to be generated (i.e. ICMP Destination Unreachable, Communication
+Administratively Prohibited. type=3, code=13).
+
+</p>
+<a name="rfc.section.3.1.5"></a><h4><a name="anchor19">3.1.5</a>&nbsp;Encrypt policy</h4>
+
+<p>
+The responder encrypts the datagram using the indicated security association database
+(SAD) entry. The responder enters this state only by command from the keying daemon, and upon entering
+this state, releases and forwards the "first" and "last" datagrams using the
+new encrypt policy.
+
+</p>
+<p>
+If the associated SAD entry expires because of byte, packet or time limits, then
+the entry returns to the Hold policy, and an expire message is sent to the keying daemon.
+
+</p>
+<p>
+All states may be created directly by the keying daemon while acting as a
+responder.
+
+</p>
+<a name="rfc.section.3.2"></a><h4><a name="initclasses">3.2</a>&nbsp;Keying state machine - initiator</h4>
+
+<p>
+Let the keying daemon maintain a collection of objects. Let them be
+called "connections" or "conn"s. There are two categories of
+connection objects: classes and instances. A class represents an
+abstract policy - what could be. An instance represents an actual connection -
+what is implemented at the time.
+
+</p>
+<p>
+Let there be two further subtypes of connections: keying channels (Phase
+1 SAs) and data channels (Phase 2 SAs). Each data channel object may have
+a corresponding SPD and SAD entry maintained by the datagram state machine.
+
+</p>
+<p>
+For the purposes of opportunistic encryption, there MUST, at least, be
+connection classes known as "deny", "always-clear-text", "OE-permissive", and
+"OE-paranoid".
+The latter two connection classes define a set of source and/or destination
+addresses for which opportunistic encryption will be attempted. The administrator MAY set policy
+options in a number of additional places. An implementation MAY create additional connection classes to further refine
+these policies.
+
+</p>
+<p>
+The simplest system may need only the "OE-permissive" connection, and would
+list its own (single) IP address as the source address of this policy and
+the wild-card address 0.0.0.0/0 as the destination IPv4 address. That is, the
+simplest policy is to try opportunistic encryption with all destinations.
+
+</p>
+<p>
+The distinction between permissive and paranoid OE use will become clear
+in the state transition differences. In general a permissive OE will, on
+failure, install a pass-through policy, while a paranoid OE will, on failure,
+install a drop policy.
+
+</p>
+<p>
+In this description of the keying machine's state transitions, the states
+associated with the keying system itself are omitted because they are best documented in the keying system
+(<a href="#RFC2407">[8]</a>,
+<a href="#RFC2408">[9]</a> and <a href="#RFC2409">[10]</a> for ISAKMP/IKE),
+and the details are keying system specific. Opportunistic encryption is not
+dependent upon any specific keying protocol, but this document does provide
+requirements for those using ISAKMP/IKE to assure that implementations inter-operate.
+
+</p>
+<p>
+The state transitions that may be involved in communicating with the
+forwarding plane are omitted. PF_KEY and similar protocols have their own
+set of states required for message sends and completion notifications.
+
+</p>
+<p>
+Finally, the retransmits and recursive lookups that are normal for DNS are
+not included in this description of the state machine.
+
+</p>
+<a name="rfc.section.3.2.1"></a><h4><a name="anchor20">3.2.1</a>&nbsp;Nonexistent connection</h4>
+
+<p>
+There is no connection instance for a given source/destination address pair.
+Upon receipt of a request for keying material for this
+source/destination pair, the initiator searches through the connection classes to
+determine the most appropriate policy. Upon determining an appropriate
+connection class, an instance object is created of that type.
+Both of the OE types result in a potential OE connection.
+
+</p>
+<p>Failure to find an appropriate connection class results in an
+administrator defined default.
+
+</p>
+<p>
+In each case, when the initiator finds an appropriate class for the new flow,
+an instance connection is made of the class which matched.
+
+</p>
+<a name="rfc.section.3.2.2"></a><h4><a name="anchor21">3.2.2</a>&nbsp;Clear-text connection</h4>
+
+<p>
+The non-existent connection makes a transition to this state when an
+always-clear-text class is instantiated, or when an OE-permissive
+connection fails. During the transition, the initiator creates a pass-through
+policy object in the forwarding plane for the appropriate flow.
+
+</p>
+<p>
+Timing out is the only way to leave this state
+(see <a href="#expiring">Expiring connection</a>).
+
+</p>
+<a name="rfc.section.3.2.3"></a><h4><a name="anchor22">3.2.3</a>&nbsp;Deny connection</h4>
+
+<p>
+The empty connection makes a transition to this state when a
+deny class is instantiated, or when an OE-paranoid connection fails.
+During the transition, the initiator creates a deny policy object in the forwarding plane
+for the appropriate flow.
+
+</p>
+<p>
+Timing out is the only way to leave this state
+(see <a href="#expiring">Expiring connection</a>).
+
+</p>
+<a name="rfc.section.3.2.4"></a><h4><a name="anchor23">3.2.4</a>&nbsp;Potential OE connection</h4>
+
+<p>
+The empty connection makes a transition to this state when one of either OE class is instantiated.
+During the transition to this state, the initiator creates a hold policy object in the
+forwarding plane for the appropriate flow.
+
+</p>
+<p>
+In addition, when making a transition into this state, DNS lookup is done in
+the reverse-map for a TXT delegation resource record (see <a href="#TXT">Use of TXT delegation record</a>).
+The lookup key is the destination address of the flow.
+
+</p>
+<p>
+There are three ways to exit this state:
+
+<ol class="text">
+<li>DNS lookup finds a TXT delegation resource record.
+</li>
+<li>DNS lookup does not find a TXT delegation resource record.
+</li>
+<li>DNS lookup times out.
+</li>
+</ol><p>
+</p>
+<p>
+Based upon the results of the DNS lookup, the potential OE connection makes a
+transition to the pending OE connection state. The conditions for a
+successful DNS look are:
+
+<ol class="text">
+<li>DNS finds an appropriate resource record
+</li>
+<li>It is properly formatted according to <a href="#TXT">Use of TXT delegation record</a>
+</li>
+<li> if DNSSEC is enabled, then the signature has been vouched for.
+</li>
+</ol><p>
+
+Note that if the initiator does not find the public key
+present in the TXT delegation record, then the public key must
+be looked up as a sub-state. Only successful completion of all the
+DNS lookups is considered a success.
+
+</p>
+<p>
+If DNS lookup does not find a resource record or DNS times out, then the
+initiator considers the receiver not OE capable. If this is an OE-paranoid instance,
+then the potential OE connection makes a transition to the deny connection state.
+If this is an OE-permissive instance, then the potential OE connection makes a transition to the
+clear-text connection state.
+
+</p>
+<p>
+If the initiator finds a resource record but it is not properly formatted, or
+if DNSSEC is
+enabled and reports a failure to authenticate, then the potential OE
+connection should make a
+transition to the deny connection state. This action SHOULD be logged. If the
+administrator wishes to override this transition between states, then an
+always-clear class can be installed for this flow. An implementation MAY make
+this situation a new class.
+
+</p>
+<a name="rfc.section.3.2.4.1"></a><h4><a name="nodnssec">3.2.4.1</a>&nbsp;Restriction on unauthenticated TXT delegation records</h4>
+
+<p>
+An implementation SHOULD also provide an additional administrative control
+on delegation records and DNSSEC. This control would apply to delegation
+records (the TXT records in the reverse-map) that are not protected by
+DNSSEC.
+Records of this type are only permitted to delegate to their own address as
+a gateway. When this option is enabled, an active attack on DNS will be
+unable to redirect packets to other than the original destination.
+
+</p>
+<a name="rfc.section.3.2.5"></a><h4><a name="anchor24">3.2.5</a>&nbsp;Pending OE connection</h4>
+
+<p>
+The potential OE connection makes a transition to this state when
+the initiator determines that all the information required from the DNS lookup is present.
+Upon entering this state, the initiator attempts to initiate keying to the gateway
+provided.
+
+</p>
+<p>
+Exit from this state occurs either with a successfully created IPsec SA, or
+with a failure of some kind. Successful SA creation results in a transition
+to the key connection state.
+
+</p>
+<p>
+Three failures have caused significant problems. They are clearly not the
+only possible failures from keying.
+
+</p>
+<p>
+Note that if there are multiple gateways available in the TXT delegation
+records, then a failure can only be declared after all have been
+tried. Further, creation of a phase 1 SA does not constitute success. A set
+of phase 2 SAs (a tunnel) is considered success.
+
+</p>
+<p>
+The first failure occurs when an ICMP port unreachable is consistently received
+without any other communication, or when there is silence from the remote
+end. This usually means that either the gateway is not alive, or the
+keying daemon is not functional. For an OE-permissive connection, the initiator makes a transition
+to the clear-text connection but with a low lifespan. For an OE-pessimistic connection,
+the initiator makes a transition to the deny connection again with a low lifespan. The lifespan in both
+cases is kept low because the remote gateway may
+be in the process of rebooting or be otherwise temporarily unavailable.
+
+</p>
+<p>
+The length of time to wait for the remote keying daemon to wake up is
+a matter of some debate. If there is a routing failure, 5 minutes is usually long enough for the network to
+re-converge. Many systems can reboot in that amount of
+time as well. However, 5 minutes is far too long for most users to wait to
+hear that they can not connect using OE. Implementations SHOULD make this a
+tunable parameter.
+
+</p>
+<p>
+The second failure occurs after a phase 1 SA has been created, but there is
+either no response to the phase 2 proposal, or the initiator receives a
+negative notify (the notify must be
+authenticated). The remote gateway is not prepared to do OE at this time.
+As before, the initiator makes a transition to the clear-text or the deny
+connection based upon connection class, but this
+time with a normal lifespan.
+
+</p>
+<p>
+The third failure occurs when there is signature failure while authenticating
+the remote gateway. This can occur when there has been a
+key roll-over, but DNS has not caught up. In this case again, the initiator makes a
+transition to the clear-text or the deny connection based
+upon the connection class. However, the lifespan depends upon the remaining
+time to live in the DNS. (Note that DNSSEC signed resource records have a different
+expiry time than non-signed records.)
+
+</p>
+<a name="rfc.section.3.2.6"></a><h4><a name="keyed">3.2.6</a>&nbsp;Keyed connection</h4>
+
+<p>
+The pending OE connection makes a transition to this state when
+session keying material (the phase 2 SAs) is derived. The initiator creates an encrypt
+policy in the forwarding plane for this flow.
+
+</p>
+<p>
+There are three ways to exit this state. The first is by receipt of an
+authenticated delete message (via the keying channel) from the peer. This is
+normal teardown and results in a transition to the expired connection state.
+
+</p>
+<p>
+The second exit is by expiry of the forwarding plane keying material. This
+starts a re-key operation with a transition back to pending OE
+connection. In general, the soft expiry occurs with sufficient time left
+to continue to use the keys. A re-key can fail, which may
+result in the connection failing to clear-text or deny as
+appropriate. In the event of a failure, the forwarding plane
+policy does not change until the phase 2 SA (IPsec SA) reaches its
+hard expiry.
+
+</p>
+<p>
+The third exit is in response to a negotiation from a remote
+gateway. If the forwarding plane signals the control plane that it has received an
+unknown SPI from the remote gateway, or an ICMP is received from the remote gateway
+indicating an unknown SPI, the initiator should consider that
+the remote gateway has rebooted or restarted. Since these
+indications are easily forged, the implementation must
+exercise care. The initiator should make a cautious
+(rate-limited) attempt to re-key the connection.
+
+</p>
+<a name="rfc.section.3.2.7"></a><h4><a name="expiring">3.2.7</a>&nbsp;Expiring connection</h4>
+
+<p>
+The initiator will periodically place each of the deny, clear-text, and keyed
+connections into this
+sub-state. See <a href="#teardown">Renewal and teardown</a> for more details of how often this
+occurs.
+The initiator queries the forwarding plane for last use time of the
+appropriate
+policy. If the last use time is relatively recent, then the connection
+returns to the
+previous deny, clear-text or keyed connection state. If not, then the
+connection enters
+the expired connection state.
+
+</p>
+<p>
+The DNS query and answer that lead to the expiring connection state are also
+examined. The DNS query may become stale. (A negative, i.e. no such record, answer
+is valid for the period of time given by the MINIMUM field in an attached SOA
+record. See <a href="#RFC1034">[12]</a> section 4.3.4.)
+If the DNS query is stale, then a new query is made. If the results change, then the connection
+makes a transition to a new state as described in potential OE connection state.
+
+</p>
+<p>
+Note that when considering how stale a connection is, both outgoing SPD and
+incoming SAD must be queried as some flows may be unidirectional for some time.
+
+</p>
+<p>
+Also note that the policy at the forwarding plane is not updated unless there
+is a conclusion that there should be a change.
+
+</p>
+<a name="rfc.section.3.2.8"></a><h4><a name="anchor25">3.2.8</a>&nbsp;Expired connection</h4>
+
+<p>
+Entry to this state occurs when no datagrams have been forwarded recently via the
+appropriate SPD and SAD objects. The objects in the forwarding plane are
+removed (logging any final byte and packet counts if appropriate) and the
+connection instance in the keying plane is deleted.
+
+</p>
+<p>
+The initiator sends an ISAKMP/IKE delete to clean up the phase 2 SAs as described in
+<a href="#teardown">Renewal and teardown</a>.
+
+</p>
+<p>
+Whether or not to delete the phase 1 SAs
+at this time is left as a local implementation issue. Implementations
+that do delete the phase 1 SAs MUST send authenticated delete messages to
+indicate that they are doing so. There is an advantage to keeping
+the phase 1 SAs until they expire - they may prove useful again in the
+near future.
+
+</p>
+<a name="rfc.section.3.3"></a><h4><a name="anchor26">3.3</a>&nbsp;Keying state machine - responder</h4>
+
+<p>
+The responder has a set of objects identical to those of the initiator.
+
+</p>
+<p>
+The responder receives an invitation to create a keying channel from an initiator.
+
+</p>
+<a name="rfc.section.3.3.1"></a><h4><a name="anchor27">3.3.1</a>&nbsp;Unauthenticated OE peer</h4>
+
+<p>
+Upon entering this state, the responder starts a DNS lookup for a KEY record for the
+initiator.
+The responder looks in the reverse-map for a KEY record for the initiator if the
+initiator has offered an ID_IPV4_ADDR, and in the forward map if the
+initiator has offered an ID_FQDN type. (See <a href="#RFC2407">[8]</a> section
+4.6.2.1.)
+
+</p>
+<p>
+The responder exits this state upon successful receipt of a KEY from DNS, and use of the key
+to verify the signature of the initiator.
+
+</p>
+<p>
+Successful authentication of the peer results in a transition to the
+authenticated OE Peer state.
+
+</p>
+<p>
+Note that the unauthenticated OE peer state generally occurs in the middle of the key negotiation
+protocol. It is really a form of pseudo-state.
+
+</p>
+<a name="rfc.section.3.3.2"></a><h4><a name="anchor28">3.3.2</a>&nbsp;Authenticated OE Peer</h4>
+
+<p>
+The peer will eventually propose one or more phase 2 SAs. The responder uses the source and
+destination address in the proposal to
+finish instantiating the connection state
+using the connection class table.
+The responder MUST search for an identical connection object at this point.
+
+</p>
+<p>
+If an identical connection is found, then the responder deletes the old instance,
+and the new object makes a transition to the pending OE connection state. This means
+that new ISAKMP connections with a given peer will always use the latest
+instance, which is the correct one if the peer has rebooted in the interim.
+
+</p>
+<p>
+If an identical connection is not found, then the responder makes the transition according to the
+rules given for the initiator.
+
+</p>
+<p>
+Note that if the initiator is in OE-paranoid mode and the responder is in
+either always-clear-text or deny, then no communication is possible according
+to policy. An implementation is permitted to create new types of policies
+such as "accept OE but do not initiate it". This is a local matter.
+
+</p>
+<a name="rfc.section.3.4"></a><h4><a name="teardown">3.4</a>&nbsp;Renewal and teardown</h4>
+
+<a name="rfc.section.3.4.1"></a><h4><a name="anchor29">3.4.1</a>&nbsp;Aging</h4>
+
+<p>
+A potentially unlimited number of tunnels may exist. In practice, only a few
+tunnels are used during a period of time. Unused tunnels MUST, therefore, be
+torn down. Detecting when tunnels are no longer in use is the subject of this section.
+
+</p>
+<p>
+There are two methods for removing tunnels: explicit deletion or expiry.
+
+</p>
+<p>
+Explicit deletion requires an IKE delete message. As the deletes
+MUST be authenticated, both ends of the tunnel must maintain the
+key channel (phase 1 ISAKMP SA). An implementation which refuses to either maintain or
+recreate the keying channel SA will be unable to use this method.
+
+</p>
+<p>
+The tunnel expiry method, simply allows the IKE daemon to
+expire normally without attempting to re-key it.
+
+</p>
+<p>
+Regardless of which method is used to remove tunnels, the implementation requires
+a method to determine if the tunnel is still in use. The specifics are a
+local matter, but the FreeS/WAN project uses the following criteria. These
+criteria are currently implemented in the key management daemon, but could
+also be implemented at the SPD layer using an idle timer.
+
+</p>
+<p>
+Set a short initial (soft) lifespan of 1 minute since many net flows last
+only a few seconds.
+
+</p>
+<p>
+At the end of the lifespan, check to see if the tunnel was used by
+traffic in either direction during the last 30 seconds. If so, assign a
+longer tentative lifespan of 20 minutes after which, look again. If the
+tunnel is not in use, then close the tunnel.
+
+</p>
+<p>
+The expiring state in the key management
+system (see <a href="#expiring">Expiring connection</a>) implements these timeouts.
+The timer above may be in the forwarding plane,
+but then it must be re-settable.
+
+</p>
+<p>
+The tentative lifespan is independent of re-keying; it is just the time when
+the tunnel's future is next considered.
+(The term lifespan is used here rather than lifetime for this reason.)
+Unlike re-keying, this tunnel use check is not costly and should happen
+reasonably frequently.
+
+</p>
+<p>
+A multi-step back-off algorithm is not considered worth the effort here.
+
+</p>
+<p>
+If the security gateway and the client host are the
+same and not a Bump-in-the-Stack or Bump-in-the-Wire implementation, tunnel
+teardown decisions MAY pay attention to TCP connection status as reported
+by the local TCP layer. A still-open TCP connection is almost a guarantee that more traffic is
+expected. Closing of the only TCP connection through a tunnel is a
+strong hint that no more traffic is expected.
+
+</p>
+<a name="rfc.section.3.4.2"></a><h4><a name="anchor30">3.4.2</a>&nbsp;Teardown and cleanup</h4>
+
+<p>
+Teardown should always be coordinated between the two ends of the tunnel by
+interpreting and sending delete notifications. There is a
+detailed sub-state in the expired connection state of the key manager that
+relates to retransmits of the delete notifications, but this is considered to
+be a keying system detail.
+
+</p>
+<p>
+On receiving a delete for the outbound SAs of a tunnel (or some subset of
+them), tear down the inbound ones also and notify the remote end with a
+delete. If the local system receives a delete for a tunnel which is no longer in
+existence, then two delete messages have crossed paths. Ignore the delete.
+The operation has already been completed. Do not generate any messages in this
+situation.
+
+</p>
+<p>
+Tunnels are to be considered as bidirectional entities, even though the
+low-level protocols don't treat them this way.
+
+</p>
+<p>
+When the deletion is initiated locally, rather than as a
+response to a received delete, send a delete for (all) the
+inbound SAs of a tunnel. If the local system does not receive a responding delete
+for the outbound SAs, try re-sending the original
+delete. Three tries spaced 10 seconds apart seems a reasonable
+level of effort. A failure of the other end to respond after 3 attempts,
+indicates that the possibility of further communication is unlikely. Remove the outgoing SAs.
+(The remote system may be a mobile node that is no longer present or powered on.)
+
+</p>
+<p>
+After re-keying, transmission should switch to using the new
+outgoing SAs (ISAKMP or IPsec) immediately, and the old leftover
+outgoing SAs should be cleared out promptly (delete should be sent
+for the outgoing SAs) rather than waiting for them to expire. This
+reduces clutter and minimizes confusion for the operator doing diagnostics.
+
+</p>
+<a name="anchor31"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.4"></a><h3>4.&nbsp;Impacts on IKE</h3>
+
+<a name="rfc.section.4.1"></a><h4><a name="anchor32">4.1</a>&nbsp;ISAKMP/IKE protocol</h4>
+
+<p>
+ The IKE wire protocol needs no modifications. The major changes are
+ implementation issues relating to how the proposals are interpreted, and from
+ whom they may come.
+
+</p>
+<p>
+ As opportunistic encryption is designed to be useful between peers without
+ prior operator configuration, an IKE daemon must be prepared to negotiate
+ phase 1 SAs with any node. This may require a large amount of resources to
+ maintain cookie state, as well as large amounts of entropy for nonces,
+ cookies and so on.
+
+</p>
+<p>
+ The major changes to support opportunistic encryption are at the IKE daemon
+ level. These changes relate to handling of key acquisition requests, lookup
+ of public keys and TXT records, and interactions with firewalls and other
+ security facilities that may be co-resident on the same gateway.
+
+</p>
+<a name="rfc.section.4.2"></a><h4><a name="anchor33">4.2</a>&nbsp;Gateway discovery process</h4>
+
+<p>
+ In a typical configured tunnel, the address of SG-B is provided
+ via configuration. Furthermore, the mapping of an SPD entry to a gateway is
+ typically a 1:1 mapping. When the 0.0.0.0/0 SPD entry technique is used, then
+ the mapping to a gateway is determined by the reverse DNS records.
+
+</p>
+<p>
+ The need to do a DNS lookup and wait for a reply will typically introduce a
+ new state and a new event source (DNS replies) to IKE. Although a
+synchronous DNS request can be implemented for proof of concept, experience
+is that it can cause very high latencies when a queue of queries must
+all timeout in series.
+
+</p>
+<p>
+ Use of an asynchronous DNS lookup will also permit overlap of DNS lookups with
+ some of the protocol steps.
+
+</p>
+<a name="rfc.section.4.3"></a><h4><a name="anchor34">4.3</a>&nbsp;Self identification</h4>
+
+<p>
+ SG-A will have to establish its identity. Use an
+ IPv4 ID in phase 1.
+
+</p>
+<p> There are many situations where the administrator of SG-A may not be
+ able to control the reverse DNS records for SG-A's public IP address.
+ Typical situations include dialup connections and most residential-type broadband Internet access
+ (ADSL, cable-modem) connections. In these situations, a fully qualified domain
+ name that is under the control of SG-A's administrator may be used
+ when acting as an initiator only.
+ The FQDN ID should be used in phase 1. See <a href="#fqdn">Use of FQDN IDs</a>
+ for more details and restrictions.
+
+</p>
+<a name="rfc.section.4.4"></a><h4><a name="anchor35">4.4</a>&nbsp;Public key retrieval process</h4>
+
+<p>
+ Upon receipt of a phase 1 SA proposal with either an IPv4 (IPv6) ID or
+ an FQDN ID, an IKE daemon needs to examine local caches and
+ configuration files to determine if this is part of a configured tunnel.
+ If no configured tunnels are found, then the implementation should attempt to retrieve
+ a KEY record from the reverse DNS in the case of an IPv4/IPv6 ID, or
+ from the forward DNS in the case of FQDN ID.
+
+</p>
+<p>
+ It is reasonable that if other non-local sources of policy are used
+ (COPS, LDAP), they be consulted concurrently but some
+ clear ordering of policy be provided. Note that due to variances in
+ latency, implementations must wait for positive or negative replies from all sources
+ of policy before making any decisions.
+
+</p>
+<a name="rfc.section.4.5"></a><h4><a name="anchor36">4.5</a>&nbsp;Interactions with DNSSEC</h4>
+
+<p>
+ The implementation described (1.98) neither uses DNSSEC directly to
+ explicitly verify the authenticity of zone information, nor uses the NXT
+ records to provide authentication of the absence of a TXT or KEY
+ record. Rather, this implementation uses a trusted path to a DNSSEC
+ capable caching resolver.
+
+</p>
+<p>
+ To distinguish between an authenticated and an unauthenticated DNS
+ resource record, a stub resolver capable of returning DNSSEC
+ information MUST be used.
+
+</p>
+<a name="rfc.section.4.6"></a><h4><a name="anchor37">4.6</a>&nbsp;Required proposal types</h4>
+
+<a name="rfc.section.4.6.1"></a><h4><a name="phase1id">4.6.1</a>&nbsp;Phase 1 parameters</h4>
+
+<p>
+ Main mode MUST be used.
+
+</p>
+<p>
+ The initiator MUST offer at least one proposal using some combination
+ of: 3DES, HMAC-MD5 or HMAC-SHA1, DH group 2 or 5. Group 5 SHOULD be
+ proposed first.
+ <a href="#RFC3526">[11]</a>
+</p>
+<p>
+ The initiator MAY offer additional proposals, but the cipher MUST not
+ be weaker than 3DES. The initiator SHOULD limit the number of proposals
+ such that the IKE datagrams do not need to be fragmented.
+
+</p>
+<p>
+ The responder MUST accept one of the proposals. If any configuration
+ of the responder is required then the responder is not acting in an
+ opportunistic way.
+
+</p>
+<p>
+ SG-A SHOULD use an ID_IPV4_ADDR (ID_IPV6_ADDR for IPv6) of the external
+ interface of SG-A for phase 1. (There is an exception, see <a href="#fqdn">Use of FQDN IDs</a>.) The authentication method MUST be RSA public key signatures.
+ The RSA key for SG-A SHOULD be placed into a DNS KEY record in
+ the reverse space of SG-A (i.e. using in-addr.arpa).
+
+</p>
+<a name="rfc.section.4.6.2"></a><h4><a name="phase2id">4.6.2</a>&nbsp;Phase 2 parameters</h4>
+
+<p>
+ SG-A MUST propose a tunnel between Alice and Bob, using 3DES-CBC
+ mode, MD5 or SHA1 authentication. Perfect Forward Secrecy MUST be specified.
+
+</p>
+<p>
+ Tunnel mode MUST be used.
+
+</p>
+<p>
+ Identities MUST be ID_IPV4_ADDR_SUBNET with the mask being /32.
+
+</p>
+<p>
+ Authorization for SG-A to act on Alice's behalf is determined by
+ looking for a TXT record in the reverse-map at Alice's address.
+
+</p>
+<p>
+ Compression SHOULD NOT be mandatory. It may be offered as an option.
+
+</p>
+<a name="anchor38"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.5"></a><h3>5.&nbsp;DNS issues</h3>
+
+<a name="rfc.section.5.1"></a><h4><a name="KEY">5.1</a>&nbsp;Use of KEY record</h4>
+
+<p>
+ In order to establish their own identities, SG-A and SG-B SHOULD publish
+ their public keys in their reverse DNS via
+ DNSSEC's KEY record.
+ See section 3 of <a href="#RFC2535">RFC 2535</a>[16].
+
+</p>
+<p>
+<p>For example:
+</p></font><pre>
+KEY 0x4200 4 1 AQNJjkKlIk9...nYyUkKK8
+</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+
+<blockquote class="text"><dl>
+<dt>0x4200:</dt>
+<dd> The flag bits, indicating that this key is prohibited
+ for confidentiality use (it authenticates the peer only, a separate
+ Diffie-Hellman exchange is used for
+ confidentiality), and that this key is associated with the non-zone entity
+ whose name is the RR owner name. No other flags are set.
+</dd>
+<dt>4:</dt>
+<dd>This indicates that this key is for use by IPsec.
+</dd>
+<dt>1:</dt>
+<dd>An RSA key is present.
+</dd>
+<dt>AQNJjkKlIk9...nYyUkKK8:</dt>
+<dd>The public key of the host as described in <a href="#RFC3110">[17]</a>.
+</dd>
+</dl></blockquote><p>
+</p>
+<p>Use of several KEY records allows for key rollover. The SIG Payload in
+ IKE phase 1 SHOULD be accepted if the public key given by any KEY RR
+ validates it.
+
+</p>
+<a name="rfc.section.5.2"></a><h4><a name="TXT">5.2</a>&nbsp;Use of TXT delegation record</h4>
+
+<p>
+Alice publishes a TXT record to provide authorization for SG-A to act on
+Alice's behalf.
+
+Bob publishes a TXT record to provide authorization for SG-B to act on Bob's
+behalf.
+
+These records are located in the reverse DNS (in-addr.arpa) for their
+respective IP addresses. The reverse DNS SHOULD be secured by DNSSEC, when
+it is deployed. DNSSEC is required to defend against active attacks.
+
+</p>
+<p>
+ If Alice's address is P.Q.R.S, then she can authorize another node to
+ act on her behalf by publishing records at:
+ </p>
+</font><pre>
+S.R.Q.P.in-addr.arpa
+ </pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<p>
+
+</p>
+<p>
+ The contents of the resource record are expected to be a string that
+ uses the following syntax, as suggested in <a href="#RFC1464">[15]</a>.
+ (Note that the reply to query may include other TXT resource
+ records used by other applications.)
+
+ <br><hr size="1" shade="0">
+<a name="txtformat"></a>
+</p>
+</font><pre>
+X-IPsec-Server(P)=A.B.C.D KEY
+ </pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<p>
+<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Format of reverse delegation record&nbsp;</b></font><br></td></tr></table><hr size="1" shade="0">
+
+</p>
+<blockquote class="text"><dl>
+<dt>P:</dt>
+<dd> Specifies a precedence for this record. This is
+ similar to MX record preferences. Lower numbers have stronger
+ preference.
+
+</dd>
+<dt>A.B.C.D:</dt>
+<dd> Specifies the IP address of the Security Gateway
+ for this client machine.
+
+</dd>
+<dt>KEY:</dt>
+<dd> Is the encoded RSA Public key of the Security
+ Gateway. The key is provided here to avoid a second DNS lookup. If this
+ field is absent, then a KEY resource record should be looked up in the
+ reverse-map of A.B.C.D. The key is transmitted in base64 format.
+
+</dd>
+</dl></blockquote><p>
+<p>
+ The pieces of the record are separated by any whitespace
+ (space, tab, newline, carriage return). An ASCII space SHOULD
+ be used.
+
+</p>
+<p>
+ In the case where Alice is located at a public address behind a
+ security gateway that has no fixed address (or no control over its
+ reverse-map), then Alice may delegate to a public key by domain name.
+
+ <br><hr size="1" shade="0">
+<a name="txtfqdnformat"></a>
+</p>
+</font><pre>
+X-IPsec-Server(P)=@FQDN KEY
+ </pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<p>
+<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Format of reverse delegation record (FQDN version)&nbsp;</b></font><br></td></tr></table><hr size="1" shade="0">
+
+</p>
+<blockquote class="text"><dl>
+<dt>P:</dt>
+<dd> Is as above.
+
+</dd>
+<dt>FQDN:</dt>
+<dd> Specifies the FQDN that the Security Gateway
+ will identify itself with.
+
+</dd>
+<dt>KEY:</dt>
+<dd> Is the encoded RSA Public key of the Security
+ Gateway.
+</dd>
+</dl></blockquote><p>
+<p>
+ If there is more than one such TXT record with strongest (lowest
+ numbered) precedence, one Security Gateway is picked arbitrarily from
+ those specified in the strongest-preference records.
+
+</p>
+<a name="rfc.section.5.2.1"></a><h4><a name="anchor39">5.2.1</a>&nbsp;Long TXT records</h4>
+
+<p>
+ When packed into transport format, TXT records which are longer than 255
+ characters are divided into smaller &lt;character-strings&gt;.
+ (See <a href="#RFC1035">[13]</a> section 3.3 and 3.3.14.) These MUST
+ be reassembled into a single string for processing.
+ Whitespace characters in the base64 encoding are to be ignored.
+
+</p>
+<a name="rfc.section.5.2.2"></a><h4><a name="anchor40">5.2.2</a>&nbsp;Choice of TXT record</h4>
+
+<p>
+ It has been suggested to use the KEY, OPT, CERT, or KX records
+ instead of a TXT record. None is satisfactory.
+
+</p>
+<p> The KEY RR has a protocol field which could be used to indicate a new protocol,
+and an algorithm field which could be used to
+ indicate different contents in the key data. However, the KEY record
+ is clearly not intended for storing what are really authorizations,
+ it is just for identities. Other uses have been discouraged.
+
+</p>
+<p> OPT resource records, as defined in <a href="#RFC2671">[14]</a> are not
+ intended to be used for storage of information. They are not to be loaded,
+ cached or forwarded. They are, therefore, inappropriate for use here.
+
+</p>
+<p>
+ CERT records <a href="#RFC2538">[18]</a> can encode almost any set of
+ information. A custom type code could be used permitting any suitable
+ encoding to be stored, not just X.509. According to
+ the RFC, the certificate RRs are to be signed internally which may add undesirable
+and unnecessary bulk. Larger DNS records may require TCP instead of UDP transfers.
+
+</p>
+<p>
+ At the time of protocol design, the CERT RR was not widely deployed and
+ could not be counted upon. Use of CERT records will be investigated,
+ and may be proposed in a future revision of this document.
+
+</p>
+<p>
+ KX records are ideally suited for use instead of TXT records, but had not been deployed at
+ the time of implementation.
+
+</p>
+<a name="rfc.section.5.3"></a><h4><a name="fqdn">5.3</a>&nbsp;Use of FQDN IDs</h4>
+
+<p>
+ Unfortunately, not every administrator has control over the contents
+ of the reverse-map. Where the initiator (SG-A) has no suitable reverse-map, the
+ authorization record present in the reverse-map of Alice may refer to a
+ FQDN instead of an IP address.
+
+</p>
+<p>
+ In this case, the client's TXT record gives the fully qualified domain
+ name (FQDN) in place of its security gateway's IP address.
+ The initiator should use the ID_FQDN ID-payload in phase 1.
+ A forward lookup for a KEY record on the FQDN must yield the
+ initiator's public key.
+
+</p>
+<p>
+ This method can also be used when the external address of SG-A is
+ dynamic.
+
+</p>
+<p>
+ If SG-A is acting on behalf of Alice, then Alice must still delegate
+ authority for SG-A to do so in her reverse-map. When Alice and SG-A
+ are one and the same (i.e. Alice is acting as an end-node) then there
+ is no need for this when initiating only.
+</p>
+<p>However, Alice must still delegate to herself if she wishes others to
+ initiate OE to her. See <a href="#txtfqdnformat">Format of reverse delegation record (FQDN version)</a>.
+
+</p>
+<a name="rfc.section.5.4"></a><h4><a name="anchor41">5.4</a>&nbsp;Key roll-over</h4>
+
+<p>
+Good cryptographic hygiene says that one should replace public/private key pairs
+periodically. Some administrators may wish to do this as often as daily. Typical DNS
+propagation delays are determined by the SOA Resource Record MINIMUM
+parameter, which controls how long DNS replies may be cached. For reasonable
+operation of DNS servers, administrators usually want this value to be at least several
+hours, sometimes as a long as a day. This presents a problem - a new key MUST
+not be used prior to it propagating through DNS.
+
+</p>
+<p>
+This problem is dealt with by having the Security Gateway generate a new
+public/private key pair at least MINIMUM seconds in advance of using it. It
+then adds this key to the DNS (both as a second KEY record and in additional TXT
+delegation records) at key generation time. Note: only one key is allowed in
+each TXT record.
+
+</p>
+<p>
+When authenticating, all gateways MUST have available all public keys
+that are found in DNS for this entity. This permits the authenticating end
+to check both the key for "today" and the key for "tomorrow". Note that it is
+the end which is creating the signature (possesses the private key) that
+determines which key is to be used.
+
+</p>
+<a name="anchor42"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.6"></a><h3>6.&nbsp;Network address translation interaction</h3>
+
+<p>
+ There are no fundamentally new issues for implementing opportunistic encryption
+ in the presence of network address translation. Rather there are
+ only the regular IPsec issues with NAT traversal.
+
+</p>
+<p>
+ There are several situations to consider for NAT.
+
+</p>
+<a name="rfc.section.6.1"></a><h4><a name="anchor43">6.1</a>&nbsp;Co-located NAT/NAPT</h4>
+
+<p>
+ If SG-A is also performing network address translation on
+ behalf of Alice, then the packet should be translated prior to
+ being subjected to opportunistic encryption. This is in contrast to
+ typically configured tunnels which often exist to bridge islands of
+ private network address space. SG-A will use the translated source
+ address for phase 2, and so SG-B will look up that address to
+ confirm SG-A's authorization.
+
+</p>
+<p> In the case of NAT (1:1), the address space into which the
+ translation is done MUST be globally unique, and control over the
+ reverse-map is assumed.
+ Placing of TXT records is possible.
+
+</p>
+<p> In the case of NAPT (m:1), the address will be SG-A. The ability to get
+ KEY and TXT records in place will again depend upon whether or not
+ there is administrative control over the reverse-map. This is
+ identical to situations involving a single host acting on behalf of
+ itself.
+
+ FQDN style can be used to get around a lack of a reverse-map for
+ initiators only.
+
+</p>
+<a name="rfc.section.6.2"></a><h4><a name="anchor44">6.2</a>&nbsp;SG-A behind NAT/NAPT</h4>
+
+<p>
+ If there is a NAT or NAPT between SG-A and SG-B, then normal IPsec
+ NAT traversal rules apply. In addition to the transport problem
+ which may be solved by other mechanisms, there
+ is the issue of what phase 1 and phase 2 IDs to use. While FQDN could
+ be used during phase 1 for SG-A, there is no appropriate ID for phase 2
+ that permits SG-B to determine that SG-A is in fact authorized to speak for Alice.
+
+</p>
+<a name="rfc.section.6.3"></a><h4><a name="anchor45">6.3</a>&nbsp;Bob is behind a NAT/NAPT</h4>
+
+<p>
+ If Bob is behind a NAT (perhaps SG-B), then there is, in fact, no way for
+ Alice to address a packet to Bob. Not only is opportunistic encryption
+ impossible, but it is also impossible for Alice to initiate any
+ communication to Bob. It may be possible for Bob to initiate in such
+ a situation. This creates an asymmetry, but this is common for
+ NAPT.
+
+</p>
+<a name="anchor46"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.7"></a><h3>7.&nbsp;Host implementations</h3>
+
+<p>
+ When Alice and SG-A are components of the same system, they are
+ considered to be a host implementation. The packet sequence scenario remains unchanged.
+
+</p>
+<p>
+ Components marked Alice are the upper layers (TCP, UDP, the
+ application), and SG-A is the IP layer.
+
+</p>
+<p>
+ Note that tunnel mode is still required.
+
+</p>
+<p>
+ As Alice and SG-A are acting on behalf of themselves, no TXT based delegation
+ record is necessary for Alice to initiate. She can rely on FQDN in a
+ forward map. This is particularly attractive to mobile nodes such as
+ notebook computers at conferences.
+ To respond, Alice/SG-A will still need an entry in Alice's reverse-map.
+
+</p>
+<a name="anchor47"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.8"></a><h3>8.&nbsp;Multi-homing</h3>
+
+<p>
+If there are multiple paths between Alice and Bob (as illustrated in
+the diagram with SG-D), then additional DNS records are required to establish
+authorization.
+
+</p>
+<p>
+In <a href="#networkdiagram">Reference Network Diagram</a>, Alice has two ways to
+exit her network: SG-A and SG-D. Previously SG-D has been ignored. Postulate
+that there are routers between Alice and her set of security gateways
+(denoted by the + signs and the marking of an autonomous system number for
+Alice's network). Datagrams may, therefore, travel to either SG-A or SG-D en
+route to Bob.
+
+</p>
+<p>
+As long as all network connections are in good order, it does not matter how
+datagrams exit Alice's network. When they reach either security gateway, the
+security gateway will find the TXT delegation record in Bob's reverse-map,
+and establish an SA with SG-B.
+
+</p>
+<p>
+SG-B has no problem establishing that either of SG-A or SG-D may speak for
+Alice, because Alice has published two equally weighted TXT delegation records:
+ <br><hr size="1" shade="0">
+<a name="txtmultiexample"></a>
+</p>
+</font><pre>
+X-IPsec-Server(10)=192.1.1.5 AQMM...3s1Q==
+X-IPsec-Server(10)=192.1.1.6 AAJN...j8r9==
+ </pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<p>
+<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Multiple gateway delegation example for Alice&nbsp;</b></font><br></td></tr></table><hr size="1" shade="0">
+
+</p>
+<p>
+Alice's routers can now do any kind of load sharing needed. Both SG-A and SG-D send datagrams addressed to Bob through
+their tunnel to SG-B.
+
+</p>
+<p>
+Alice's use of non-equal weight delegation records to show preference of one gateway over another, has relevance only when SG-B
+is initiating to Alice.
+
+</p>
+<p>
+If the precedences are the same, then SG-B has a more difficult time. It
+must decide which of the two tunnels to use. SG-B has no information about
+which link is less loaded, nor which security gateway has more cryptographic
+resources available. SG-B, in fact, has no knowledge of whether both gateways
+are even reachable.
+
+</p>
+<p>
+The Public Internet's default-free zone may well know a good route to Alice,
+but the datagrams that SG-B creates must be addressed to either SG-A or SG-D;
+they can not be addressed to Alice directly.
+
+</p>
+<p>
+SG-B may make a number of choices:
+
+<ol class="text">
+<li>It can ignore the problem and round robin among the tunnels. This
+ causes losses during times when one or the other security gateway is
+ unreachable. If this worries Alice, she can change the weights in her
+ TXT delegation records.
+</li>
+<li>It can send to the gateway from which it most recently received datagrams.
+ This assumes that routing and reachability are symmetrical.
+</li>
+<li>It can listen to BGP information from the Internet to decide which
+ system is currently up. This is clearly much more complicated, but if SG-B is already participating
+ in the BGP peering system to announce Bob, the results data may already
+ be available to it.
+</li>
+<li>It can refuse to negotiate the second tunnel. (It is unclear whether or
+not this is even an option.)
+</li>
+<li>It can silently replace the outgoing portion of the first tunnel with the
+second one while still retaining the incoming portions of both. SG-B can,
+thus, accept datagrams from either SG-A or SG-D, but
+send only to the gateway that most recently re-keyed with it.
+</li>
+</ol><p>
+</p>
+<p>
+Local policy determines which choice SG-B makes. Note that even if SG-B has perfect
+knowledge about the reachability of SG-A and SG-D, Alice may not be reachable
+from either of these security gateways because of internal reachability
+issues.
+
+</p>
+<p>
+FreeS/WAN implements option 5. Implementing a different option is
+being considered. The multi-homing aspects of OE are not well developed and may
+be the subject of a future document.
+
+</p>
+<a name="anchor48"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.9"></a><h3>9.&nbsp;Failure modes</h3>
+
+<a name="rfc.section.9.1"></a><h4><a name="anchor49">9.1</a>&nbsp;DNS failures</h4>
+
+<p>
+ If a DNS server fails to respond, local policy decides
+ whether or not to permit communication in the clear as embodied in
+ the connection classes in <a href="#initclasses">Keying state machine - initiator</a>.
+ It is easy to mount a denial of service attack on the DNS server
+ responsible for a particular network's reverse-map.
+ Such an attack may cause all communication with that network to go in
+ the clear if the policy is permissive, or fail completely
+ if the policy is paranoid. Please note that this is an active attack.
+
+</p>
+<p>
+ There are still many networks
+ that do not have properly configured reverse-maps. Further, if the policy is not to communicate,
+ the above denial of service attack isolates the target network. Therefore, the decision of whether
+or not to permit communication in the clear MUST be a matter of local policy.
+
+</p>
+<a name="rfc.section.9.2"></a><h4><a name="anchor50">9.2</a>&nbsp;DNS configured, IKE failures</h4>
+
+<p>
+ DNS records claim that opportunistic encryption should
+ occur, but the target gateway either does not respond on port 500, or
+ refuses the proposal. This may be because of a crash or reboot, a
+ faulty configuration, or a firewall filtering port 500.
+
+</p>
+<p>
+ The receipt of ICMP port, host or network unreachable
+ messages indicates a potential problem, but MUST NOT cause communication
+ to fail
+ immediately. ICMP messages are easily forged by attackers. If such a
+ forgery caused immediate failure, then an active attacker could easily
+ prevent any
+ encryption from ever occurring, possibly preventing all communication.
+
+</p>
+<p>
+ In these situations a clear log should be produced
+ and local policy should dictate if communication is then
+ permitted in the clear.
+
+</p>
+<a name="rfc.section.9.3"></a><h4><a name="anchor51">9.3</a>&nbsp;System reboots</h4>
+
+<p>
+Tunnels sometimes go down because the remote end crashes,
+disconnects, or has a network link break. In general there is no
+notification of this. Even in the event of a crash and successful reboot,
+other SGs don't hear about it unless the rebooted SG has specific
+reason to talk to them immediately. Over-quick response to temporary
+network outages is undesirable. Note that a tunnel can be torn
+down and then re-established without any effect visible to the user
+except a pause in traffic. On the other hand, if one end reboots,
+the other end can't get datagrams to it at all (except via
+IKE) until the situation is noticed. So a bias toward quick
+response is appropriate even at the cost of occasional
+false alarms.
+
+</p>
+<p>
+A mechanism for recovery after reboot is a topic of current research and is not specified in this
+document.
+
+</p>
+<p>
+A deliberate shutdown should include an attempt, using deletes, to notify all other SGs
+currently connected by phase 1 SAs that communication is
+about to fail. Again, a remote SG will assume this is a teardown. Attempts by the
+remote SGs to negotiate new tunnels as replacements should be ignored. When possible,
+SGs should attempt to preserve information about currently-connected SGs in non-volatile storage, so
+that after a crash, an Initial-Contact can be sent to previous partners to
+indicate loss of all previously established connections.
+
+</p>
+<a name="anchor52"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.10"></a><h3>10.&nbsp;Unresolved issues</h3>
+
+<a name="rfc.section.10.1"></a><h4><a name="anchor53">10.1</a>&nbsp;Control of reverse DNS</h4>
+
+<p>
+ The method of obtaining information by reverse DNS lookup causes
+ problems for people who cannot control their reverse DNS
+ bindings. This is an unresolved problem in this version, and is out
+ of scope.
+
+</p>
+<a name="anchor54"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.11"></a><h3>11.&nbsp;Examples</h3>
+
+<a name="rfc.section.11.1"></a><h4><a name="anchor55">11.1</a>&nbsp;Clear-text usage (permit policy)</h4>
+
+<p>
+Two example scenarios follow. In the first example GW-A
+(Gateway A) and GW-B (Gateway B) have always-clear-text policies, and in the second example they have an OE
+policy.
+
+</p><br><hr size="1" shade="0">
+<a name="regulartiming"></a>
+</font><pre>
+ Alice SG-A DNS SG-B Bob
+ (1)
+ ------(2)-------------->
+ &lt;-----(3)---------------
+ (4)----(5)----->
+ ----------(6)------>
+ ------(7)----->
+ &lt;------(8)------
+ &lt;----------(9)------
+ &lt;----(10)-----
+ (11)----------->
+ ----------(12)----->
+ -------------->
+ &lt;---------------
+ &lt;-------------------
+ &lt;-------------
+ </pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Timing of regular transaction&nbsp;</b></font><br></td></tr></table><hr size="1" shade="0">
+
+<p>
+Alice wants to communicate with Bob. Perhaps she wants to retrieve a
+web page from Bob's web server. In the absence of opportunistic
+encryptors, the following events occur:
+
+<blockquote class="text"><dl>
+<dt>(1)</dt>
+<dd>Human or application 'clicks' with a name.
+</dd>
+<dt>(2)</dt>
+<dd>Application looks up name in DNS to get IP address.
+</dd>
+<dt>(3)</dt>
+<dd>Resolver returns A record to application.
+</dd>
+<dt>(4)</dt>
+<dd>Application starts a TCP session or UDP session and OS sends datagram.
+</dd>
+<dt>(5)</dt>
+<dd>Datagram is seen at first gateway from Alice (SG-A). (SG-A
+makes a transition through Empty connection to always-clear connection and
+instantiates a pass-through policy at the forwarding plane.)
+</dd>
+<dt>(6)</dt>
+<dd>Datagram is seen at last gateway before Bob (SG-B).
+</dd>
+<dt>(7)</dt>
+<dd>First datagram from Alice is seen by Bob.
+</dd>
+<dt>(8)</dt>
+<dd>First return datagram is sent by Bob.
+</dd>
+<dt>(9)</dt>
+<dd>Datagram is seen at Bob's gateway. (SG-B makes a transition through
+Empty connection to always-clear connection and instantiates a pass-through
+policy at the forwarding plane.)
+</dd>
+<dt>(10)</dt>
+<dd>Datagram is seen at Alice's gateway.
+</dd>
+<dt>(11)</dt>
+<dd>OS hands datagram to application. Alice sends another datagram.
+</dd>
+<dt>(12)</dt>
+<dd>A second datagram traverses the Internet.
+</dd>
+</dl></blockquote><p>
+</p>
+<a name="rfc.section.11.2"></a><h4><a name="anchor56">11.2</a>&nbsp;Opportunistic encryption</h4>
+
+<p>
+In the presence of properly configured opportunistic encryptors, the
+event list is extended.
+
+<br><hr size="1" shade="0">
+<a name="opportunistictiming"></a>
+</p>
+</font><pre>
+ Alice SG-A DNS SG-B Bob
+ (1)
+ ------(2)-------------->
+ &lt;-----(3)---------------
+ (4)----(5)----->+
+ ----(5B)->
+ &lt;---(5C)--
+ ~~~~~~~~~~~~~(5D)~~~>
+ &lt;~~~~~~~~~~~~(5E1)~~~
+ ~~~~~~~~~~~~~(5E2)~~>
+ &lt;~~~~~~~~~~~~(5E3)~~~
+ #############(5E4)##>
+ &lt;############(5E5)###
+ &lt;----(5F1)--
+ -----(5F2)->
+ #############(5G1)##>
+ &lt;----(5H1)--
+ -----(5H2)->
+ &lt;############(5G2)###
+ #############(5G3)##>
+ ============(6)====>
+ ------(7)----->
+ &lt;------(8)------
+ &lt;==========(9)======
+ &lt;-----(10)----
+ (11)----------->
+ ==========(12)=====>
+ -------------->
+ &lt;---------------
+ &lt;===================
+ &lt;-------------
+ </pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<p>
+<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Timing of opportunistic encryption transaction&nbsp;</b></font><br></td></tr></table><hr size="1" shade="0">
+
+<blockquote class="text"><dl>
+<dt>(1)</dt>
+<dd>Human or application clicks with a name.
+</dd>
+<dt>(2)</dt>
+<dd>Application initiates DNS mapping.
+</dd>
+<dt>(3)</dt>
+<dd>Resolver returns A record to application.
+</dd>
+<dt>(4)</dt>
+<dd>Application starts a TCP session or UDP.
+</dd>
+<dt>(5)</dt>
+<dd>SG-A (host or SG) sees datagram to target, and buffers it.
+</dd>
+<dt>(5B)</dt>
+<dd>SG-A asks DNS for TXT record.
+</dd>
+<dt>(5C)</dt>
+<dd>DNS returns TXT record(s).
+</dd>
+<dt>(5D)</dt>
+<dd>Initial IKE Main Mode Packet goes out.
+</dd>
+<dt>(5E)</dt>
+<dd>IKE ISAKMP phase 1 succeeds.
+</dd>
+<dt>(5F)</dt>
+<dd>SG-B asks DNS for TXT record to prove SG-A is an agent for Alice.
+</dd>
+<dt>(5G)</dt>
+<dd>IKE phase 2 negotiation.
+</dd>
+<dt>(5H)</dt>
+<dd>DNS lookup by responder (SG-B).
+</dd>
+<dt>(6)</dt>
+<dd>Buffered datagram is sent by SG-A.
+</dd>
+<dt>(7)</dt>
+<dd>Datagram is received by SG-B, decrypted, and sent to Bob.
+</dd>
+<dt>(8)</dt>
+<dd>Bob replies, and datagram is seen by SG-B.
+</dd>
+<dt>(9)</dt>
+<dd>SG-B already has tunnel up with SG-A, and uses it.
+</dd>
+<dt>(10)</dt>
+<dd>SG-A decrypts datagram and gives it to Alice.
+</dd>
+<dt>(11)</dt>
+<dd>Alice receives datagram. Sends new packet to Bob.
+</dd>
+<dt>(12)</dt>
+<dd>SG-A gets second datagram, sees that tunnel is up, and uses it.
+</dd>
+</dl></blockquote><p>
+</p>
+<p>
+ For the purposes of this section, we will describe only the changes that
+ occur between <a href="#regulartiming">Timing of regular transaction</a> and
+ <a href="#opportunistictiming">Timing of opportunistic encryption transaction</a>. This corresponds to time points 5, 6, 7, 9 and 10 on the list above.
+
+</p>
+<a name="rfc.section.11.2.1"></a><h4><a name="anchor57">11.2.1</a>&nbsp;(5) IPsec datagram interception</h4>
+
+<p>
+ At point (5), SG-A intercepts the datagram because this source/destination pair lacks a policy
+(the non-existent policy state). SG-A creates a hold policy, and buffers the datagram. SG-A requests keys from the keying daemon.
+
+</p>
+<a name="rfc.section.11.2.2"></a><h4><a name="anchor58">11.2.2</a>&nbsp;(5B) DNS lookup for TXT record</h4>
+
+<p>
+ SG-A's IKE daemon, having looked up the source/destination pair in the connection
+ class list, creates a new Potential OE connection instance. SG-A starts DNS
+ queries.
+
+</p>
+<a name="rfc.section.11.2.3"></a><h4><a name="anchor59">11.2.3</a>&nbsp;(5C) DNS returns TXT record(s)</h4>
+
+<p>
+ DNS returns properly formed TXT delegation records, and SG-A's IKE daemon
+ causes this instance to make a transition from Potential OE connection to Pending OE
+ connection.
+
+</p>
+<p>
+ Using the example above, the returned record might contain:
+
+ <br><hr size="1" shade="0">
+<a name="txtexample"></a>
+</p>
+</font><pre>
+X-IPsec-Server(10)=192.1.1.5 AQMM...3s1Q==
+ </pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<p>
+<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Example of reverse delegation record for Bob&nbsp;</b></font><br></td></tr></table><hr size="1" shade="0">
+
+ with SG-B's IP address and public key listed.
+
+</p>
+<a name="rfc.section.11.2.4"></a><h4><a name="anchor60">11.2.4</a>&nbsp;(5D) Initial IKE main mode packet goes out</h4>
+
+<p>Upon entering Pending OE connection, SG-A sends the initial ISAKMP
+ message with proposals. See <a href="#phase1id">Phase 1 parameters</a>.
+
+</p>
+<a name="rfc.section.11.2.5"></a><h4><a name="anchor61">11.2.5</a>&nbsp;(5E1) Message 2 of phase 1 exchange</h4>
+
+<p>
+ SG-B receives the message. A new connection instance is created in the
+ unauthenticated OE peer state.
+
+</p>
+<a name="rfc.section.11.2.6"></a><h4><a name="anchor62">11.2.6</a>&nbsp;(5E2) Message 3 of phase 1 exchange</h4>
+
+<p>
+ SG-A sends a Diffie-Hellman exponent. This is an internal state of the
+ keying daemon.
+
+</p>
+<a name="rfc.section.11.2.7"></a><h4><a name="anchor63">11.2.7</a>&nbsp;(5E3) Message 4 of phase 1 exchange</h4>
+
+<p>
+ SG-B responds with a Diffie-Hellman exponent. This is an internal state of the
+ keying protocol.
+
+</p>
+<a name="rfc.section.11.2.8"></a><h4><a name="anchor64">11.2.8</a>&nbsp;(5E4) Message 5 of phase 1 exchange</h4>
+
+<p>
+ SG-A uses the phase 1 SA to send its identity under encryption.
+ The choice of identity is discussed in <a href="#phase1id">Phase 1 parameters</a>.
+ This is an internal state of the keying protocol.
+
+</p>
+<a name="rfc.section.11.2.9"></a><h4><a name="anchor65">11.2.9</a>&nbsp;(5F1) Responder lookup of initiator key</h4>
+
+<p>
+ SG-B asks DNS for the public key of the initiator.
+ DNS looks for a KEY record by IP address in the reverse-map.
+ That is, a KEY resource record is queried for 4.1.1.192.in-addr.arpa
+ (recall that SG-A's external address is 192.1.1.4).
+ SG-B uses the resulting public key to authenticate the initiator. See <a href="#KEY">Use of KEY record</a> for further details.
+
+</p>
+<a name="rfc.section.11.2.10"></a><h4><a name="anchor66">11.2.10</a>&nbsp;(5F2) DNS replies with public key of initiator</h4>
+
+<p>
+Upon successfully authenticating the peer, the connection instance makes a
+transition to authenticated OE peer on SG-B.
+
+</p>
+<p>
+The format of the TXT record returned is described in
+<a href="#TXT">Use of TXT delegation record</a>.
+
+</p>
+<a name="rfc.section.11.2.11"></a><h4><a name="anchor67">11.2.11</a>&nbsp;(5E5) Responder replies with ID and authentication</h4>
+
+<p>
+ SG-B sends its ID along with authentication material. This is an internal
+ state for the keying protocol.
+
+</p>
+<a name="rfc.section.11.2.12"></a><h4><a name="anchor68">11.2.12</a>&nbsp;(5G) IKE phase 2</h4>
+
+<a name="rfc.section.11.2.12.1"></a><h4><a name="anchor69">11.2.12.1</a>&nbsp;(5G1) Initiator proposes tunnel</h4>
+
+<p>
+ Having established mutually agreeable authentications (via KEY) and
+ authorizations (via TXT), SG-A proposes to create an IPsec tunnel for
+ datagrams transiting from Alice to Bob. This tunnel is established only for
+ the Alice/Bob combination, not for any subnets that may be behind SG-A and SG-B.
+
+</p>
+<a name="rfc.section.11.2.12.2"></a><h4><a name="anchor70">11.2.12.2</a>&nbsp;(5H1) Responder determines initiator's authority</h4>
+
+<p>
+ While the identity of SG-A has been established, its authority to
+ speak for Alice has not yet been confirmed. SG-B does a reverse
+ lookup on Alice's address for a TXT record.
+
+</p>
+<p>Upon receiving this specific proposal, SG-B's connection instance
+ makes a transition into the potential OE connection state. SG-B may already have an
+ instance, and the check is made as described above.
+</p>
+<a name="rfc.section.11.2.12.3"></a><h4><a name="anchor71">11.2.12.3</a>&nbsp;(5H2) DNS replies with TXT record(s)</h4>
+
+<p>
+ The returned key and IP address should match that of SG-A.
+
+</p>
+<a name="rfc.section.11.2.12.4"></a><h4><a name="anchor72">11.2.12.4</a>&nbsp;(5G2) Responder agrees to proposal</h4>
+
+<p>
+ Should additional communication occur between, for instance, Dave and Bob using
+ SG-A and SG-B, a new tunnel (phase 2 SA) would be established. The phase 1 SA
+ may be reusable.
+
+</p>
+<p>SG-A, having successfully keyed the tunnel, now makes a transition from
+ Pending OE connection to Keyed OE connection.
+
+</p>
+<p>The responder MUST setup the inbound IPsec SAs before sending its reply.
+</p>
+<a name="rfc.section.11.2.12.5"></a><h4><a name="anchor73">11.2.12.5</a>&nbsp;(5G3) Final acknowledgment from initiator</h4>
+
+<p>
+ The initiator agrees with the responder's choice and sets up the tunnel.
+ The initiator sets up the inbound and outbound IPsec SAs.
+
+</p>
+<p>
+ The proper authorization returned with keys prompts SG-B to make a transition
+ to the keyed OE connection state.
+
+</p>
+<p>Upon receipt of this message, the responder may now setup the outbound
+ IPsec SAs.
+</p>
+<a name="rfc.section.11.2.13"></a><h4><a name="anchor74">11.2.13</a>&nbsp;(6) IPsec succeeds, and sets up tunnel for communication between Alice and Bob</h4>
+
+<p>
+ SG-A sends the datagram saved at step (5) through the newly created
+ tunnel to SG-B, where it gets decrypted and forwarded.
+ Bob receives it at (7) and replies at (8).
+
+</p>
+<a name="rfc.section.11.2.14"></a><h4><a name="anchor75">11.2.14</a>&nbsp;(9) SG-B already has tunnel up with G1 and uses it</h4>
+
+<p>
+ At (9), SG-B has already established an SPD entry mapping Bob->Alice via a
+ tunnel, so this tunnel is simply applied. The datagram is encrypted to SG-A,
+ decrypted by SG-A and passed to Alice at (10).
+
+</p>
+<a name="securityconsiderations"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.12"></a><h3>12.&nbsp;Security considerations</h3>
+
+<a name="rfc.section.12.1"></a><h4><a name="anchor76">12.1</a>&nbsp;Configured vs opportunistic tunnels</h4>
+
+<p>
+ Configured tunnels are those which are setup using bilateral mechanisms: exchanging
+public keys (raw RSA, DSA, PKIX), pre-shared secrets, or by referencing keys that
+are in known places (distinguished name from LDAP, DNS). These keys are then used to
+configure a specific tunnel.
+
+</p>
+<p>
+A pre-configured tunnel may be on all the time, or may be keyed only when needed.
+The end points of the tunnel are not necessarily static: many mobile
+applications (road warrior) are considered to be configured tunnels.
+
+</p>
+<p>
+The primary characteristic is that configured tunnels are assigned specific
+security properties. They may be trusted in different ways relating to exceptions to
+firewall rules, exceptions to NAT processing, and to bandwidth or other quality of service restrictions.
+
+</p>
+<p>
+Opportunistic tunnels are not inherently trusted in any strong way. They are
+created without prior arrangement. As the two parties are strangers, there
+MUST be no confusion of datagrams that arrive from opportunistic peers and
+those that arrive from configured tunnels. A security gateway MUST take care
+that an opportunistic peer can not impersonate a configured peer.
+
+</p>
+<p>
+Ingress filtering MUST be used to make sure that only datagrams authorized by
+negotiation (and the concomitant authentication and authorization) are
+accepted from a tunnel. This is to prevent one peer from impersonating another.
+
+</p>
+<p>
+An implementation suggestion is to treat opportunistic tunnel
+datagrams as if they arrive on a logical interface distinct from other
+configured tunnels. As the number of opportunistic tunnels that may be
+created automatically on a system is potentially very high, careful attention
+to scaling should be taken into account.
+
+</p>
+<p>
+As with any IKE negotiation, opportunistic encryption cannot be secure
+without authentication. Opportunistic encryption relies on DNS for its
+authentication information and, therefore, cannot be fully secure without
+a secure DNS. Without secure DNS, opportunistic encryption can protect against passive
+eavesdropping but not against active man-in-the-middle attacks.
+
+</p>
+<a name="rfc.section.12.2"></a><h4><a name="anchor77">12.2</a>&nbsp;Firewalls versus Opportunistic Tunnels</h4>
+
+<p>
+ Typical usage of per datagram access control lists is to implement various
+kinds of security gateways. These are typically called "firewalls".
+
+</p>
+<p>
+ Typical usage of a virtual private network (VPN) within a firewall is to
+bypass all or part of the access controls between two networks. Additional
+trust (as outlined in the previous section) is given to datagrams that arrive
+in the VPN.
+
+</p>
+<p>
+ Datagrams that arrive via opportunistically configured tunnels MUST not be
+trusted. Any security policy that would apply to a datagram arriving in the
+clear SHOULD also be applied to datagrams arriving opportunistically.
+
+</p>
+<a name="rfc.section.12.3"></a><h4><a name="anchor78">12.3</a>&nbsp;Denial of service</h4>
+
+<p>
+ There are several different forms of denial of service that an implementor
+ should concern themselves with. Most of these problems are shared with
+ security gateways that have large numbers of mobile peers (road warriors).
+
+</p>
+<p>
+ The design of ISAKMP/IKE, and its use of cookies, defend against many kinds
+ of denial of service. Opportunism changes the assumption that if the phase 1 (ISAKMP)
+ SA is authenticated, that it was worthwhile creating. Because the gateway will communicate with any machine, it is
+ possible to form phase 1 SAs with any machine on the Internet.
+
+</p>
+<a name="anchor79"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.13"></a><h3>13.&nbsp;IANA Considerations</h3>
+
+<p>
+ There are no known numbers which IANA will need to manage.
+
+</p>
+<a name="anchor80"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.14"></a><h3>14.&nbsp;Acknowledgments</h3>
+
+<p>
+ Substantive portions of this document are based upon previous work by
+ Henry Spencer.
+
+</p>
+<p>
+ Thanks to Tero Kivinen, Sandy Harris, Wes Hardarker, Robert Moskowitz,
+ Jakob Schlyter, Bill Sommerfeld, John Gilmore and John Denker for their
+ comments and constructive criticism.
+
+</p>
+<p>
+ Sandra Hoffman and Bill Dickie did the detailed proof reading and editing.
+
+</p>
+<a name="rfc.references1"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<h3>Normative references</h3>
+<table width="99%" border="0">
+<tr><td class="author-text" valign="top"><b><a name="OEspec">[1]</a></b></td>
+<td class="author-text"><a href="mailto:hugh@mimosa.com">Redelmeier, D.</a> and <a href="mailto:henry@spsystems.net">H. Spencer</a>, "Opportunistic Encryption", paper http://www.freeswan.org/freeswan_trees/freeswan-1.91/doc/opportunism.spec, May 2001.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC0791">[2]</a></b></td>
+<td class="author-text">Defense Advanced Research Projects Agency (DARPA), Information Processing Techniques Office and University of Southern California (USC)/Information Sciences Institute, "<a href="ftp://ftp.isi.edu/in-notes/rfc791.txt">Internet Protocol</a>", STD 5, RFC 791, September 1981.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC1009">[3]</a></b></td>
+<td class="author-text"><a href="mailto:">Braden, R.</a> and <a href="mailto:">J. Postel</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1009.txt">Requirements for Internet gateways</a>", RFC 1009, June 1987.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC1984">[4]</a></b></td>
+<td class="author-text">IAB, IESG, <a href="mailto:brian@dxcoms.cern.ch">Carpenter, B.</a> and <a href="mailto:fred@cisco.com">F. Baker</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1984.txt">IAB and IESG Statement on Cryptographic Technology and the Internet</a>", RFC 1984, August 1996.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2119">[5]</a></b></td>
+<td class="author-text"><a href="mailto:-">Bradner, S.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2119.txt">Key words for use in RFCs to Indicate Requirement Levels</a>", BCP 14, RFC 2119, March 1997.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2367">[6]</a></b></td>
+<td class="author-text"><a href="mailto:danmcd@eng.sun.com">McDonald, D.</a>, <a href="mailto:cmetz@inner.net">Metz, C.</a> and <a href="mailto:phan@itd.nrl.navy.mil">B. Phan</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2367.txt">PF_KEY Key Management API, Version 2</a>", RFC 2367, July 1998.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2401">[7]</a></b></td>
+<td class="author-text"><a href="mailto:kent@bbn.com">Kent, S.</a> and <a href="mailto:rja@corp.home.net">R. Atkinson</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2401.txt">Security Architecture for the Internet Protocol</a>", RFC 2401, November 1998.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2407">[8]</a></b></td>
+<td class="author-text"><a href="mailto:ddp@network-alchemy.com">Piper, D.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2407.txt">The Internet IP Security Domain of Interpretation for ISAKMP</a>", RFC 2407, November 1998.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2408">[9]</a></b></td>
+<td class="author-text"><a href="mailto:wdm@tycho.ncsc.mil">Maughan, D.</a>, <a href="mailto:mss@tycho.ncsc.mil">Schneider, M.</a> and <a href="er@raba.com">M. Schertler</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2408.txt">Internet Security Association and Key Management Protocol (ISAKMP)</a>", RFC 2408, November 1998.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2409">[10]</a></b></td>
+<td class="author-text"><a href="mailto:dharkins@cisco.com">Harkins, D.</a> and <a href="mailto:carrel@ipsec.org">D. Carrel</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2409.txt">The Internet Key Exchange (IKE)</a>", RFC 2409, November 1998.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC3526">[11]</a></b></td>
+<td class="author-text"><a href="mailto:kivinen@ssh.fi">Kivinen, T.</a> and <a href="mailto:mrskojo@cc.helsinki.fi">M. Kojo</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc3526.txt">More MODP Diffie-Hellman groups for IKE</a>", RFC 3526, March 2003.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC1034">[12]</a></b></td>
+<td class="author-text">Mockapetris, P., "<a href="ftp://ftp.isi.edu/in-notes/rfc1034.txt">Domain names - concepts and facilities</a>", STD 13, RFC 1034, November 1987.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC1035">[13]</a></b></td>
+<td class="author-text"><a href="mailto:">Mockapetris, P.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1035.txt">Domain names - implementation and specification</a>", STD 13, RFC 1035, November 1987.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2671">[14]</a></b></td>
+<td class="author-text"><a href="mailto:vixie@isc.org">Vixie, P.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2671.txt">Extension Mechanisms for DNS (EDNS0)</a>", RFC 2671, August 1999.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC1464">[15]</a></b></td>
+<td class="author-text"><a href="mailto:rosenbaum@lkg.dec.com">Rosenbaum, R.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1464.txt">Using the Domain Name System To Store Arbitrary String Attributes</a>", RFC 1464, May 1993.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2535">[16]</a></b></td>
+<td class="author-text"><a href="mailto:dee3@us.ibm.com">Eastlake, D.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2535.txt">Domain Name System Security Extensions</a>", RFC 2535, March 1999.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC3110">[17]</a></b></td>
+<td class="author-text">Eastlake, D., "<a href="ftp://ftp.isi.edu/in-notes/rfc3110.txt">RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)</a>", RFC 3110, May 2001.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2538">[18]</a></b></td>
+<td class="author-text"><a href="mailto:dee3@us.ibm.com">Eastlake, D.</a> and <a href="mailto:ogud@tislabs.com">O. Gudmundsson</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2538.txt">Storing Certificates in the Domain Name System (DNS)</a>", RFC 2538, March 1999.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2748">[19]</a></b></td>
+<td class="author-text"><a href="mailto:David.Durham@intel.com">Durham, D.</a>, <a href="mailto:jboyle@Level3.net">Boyle, J.</a>, <a href="mailto:ronc@cisco.com">Cohen, R.</a>, <a href="mailto:herzog@iphighway.com">Herzog, S.</a>, <a href="mailto:rajan@research.att.com">Rajan, R.</a> and <a href="mailto:asastry@cisco.com">A. Sastry</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2748.txt">The COPS (Common Open Policy Service) Protocol</a>", RFC 2748, January 2000.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2663">[20]</a></b></td>
+<td class="author-text"><a href="mailto:srisuresh@lucent.com">Srisuresh, P.</a> and <a href="mailto:holdrege@lucent.com">M. Holdrege</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2663.txt">IP Network Address Translator (NAT) Terminology and Considerations</a>", RFC 2663, August 1999.</td></tr>
+</table>
+
+<a name="rfc.authors"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<h3>Authors' Addresses</h3>
+<table width="99%" border="0" cellpadding="0" cellspacing="0">
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">Michael C. Richardson</td></tr>
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">Sandelman Software Works</td></tr>
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">470 Dawson Avenue</td></tr>
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">Ottawa, ON K1Z 5V7</td></tr>
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">CA</td></tr>
+<tr><td class="author" align="right">EMail:&nbsp;</td>
+<td class="author-text"><a href="mailto:mcr@sandelman.ottawa.on.ca">mcr@sandelman.ottawa.on.ca</a></td></tr>
+<tr><td class="author" align="right">URI:&nbsp;</td>
+<td class="author-text"><a href="http://www.sandelman.ottawa.on.ca/">http://www.sandelman.ottawa.on.ca/</a></td></tr>
+<tr cellpadding="3"><td>&nbsp;</td><td>&nbsp;</td></tr>
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">D. Hugh Redelmeier</td></tr>
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">Mimosa</td></tr>
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">Toronto, ON</td></tr>
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">CA</td></tr>
+<tr><td class="author" align="right">EMail:&nbsp;</td>
+<td class="author-text"><a href="mailto:hugh@mimosa.com">hugh@mimosa.com</a></td></tr>
+</table>
+<a name="rfc.copyright"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<h3>Full Copyright Statement</h3>
+<p class='copyright'>
+Copyright (C) The Internet Society (2003). All Rights Reserved.</p>
+<p class='copyright'>
+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.</p>
+<p class='copyright'>
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.</p>
+<p class='copyright'>
+This document and the information contained herein is provided on an
+&quot;AS IS&quot; 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.</p>
+<h3>Acknowledgement</h3>
+<p class='copyright'>
+Funding for the RFC Editor function is currently provided by the
+Internet Society.</p>
+</font></body></html>
diff --git a/doc/src/draft-richardson-ipsec-opportunistic.xml b/doc/src/draft-richardson-ipsec-opportunistic.xml
new file mode 100644
index 000000000..d587df693
--- /dev/null
+++ b/doc/src/draft-richardson-ipsec-opportunistic.xml
@@ -0,0 +1,2519 @@
+<?xml version="1.0"?>
+<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
+<?rfc toc="yes"?>
+<?rfc tocdepth='2' ?>
+
+<rfc ipr="full2026" docName="draft-richardson-ipsec-opportunistic-12.txt">
+
+<front>
+ <area>Security</area>
+ <workgroup>Independent submission</workgroup>
+ <title abbrev="opportunistic">
+ Opportunistic Encryption using The Internet Key Exchange (IKE)
+ </title>
+
+ <author initials="M." surname="Richardson" fullname="Michael C. Richardson">
+ <organization abbrev="SSW">Sandelman Software Works</organization>
+ <address>
+ <postal>
+ <street>470 Dawson Avenue</street>
+ <city>Ottawa</city>
+ <region>ON</region>
+ <code>K1Z 5V7</code>
+ <country>CA</country>
+ </postal>
+ <email>mcr@sandelman.ottawa.on.ca</email>
+ <uri>http://www.sandelman.ottawa.on.ca/</uri>
+ </address>
+ </author>
+
+ <author initials="D.H." surname="Redelmeier"
+ fullname="D. Hugh Redelmeier">
+ <organization abbrev="Mimosa">Mimosa</organization>
+ <address>
+ <postal>
+ <city>Toronto</city>
+ <region>ON</region>
+ <country>CA</country>
+ </postal>
+ <email>hugh@mimosa.com</email>
+ </address>
+ </author>
+
+ <date month="June" year="2003"></date>
+
+<abstract>
+ <t>
+This document describes opportunistic encryption (OE) using the Internet Key
+Exchange (IKE) and IPsec.
+Each system administrator adds new
+resource records to his or her Domain Name System (DNS) to support
+opportunistic encryption. The objective is to allow encryption for secure communication without
+any pre-arrangement specific to the pair of systems involved.
+ </t>
+ <t>
+DNS is used to distribute the public keys of each
+system involved. This is resistant to passive attacks. The use of DNS
+Security (DNSSEC) secures this system against active attackers as well.
+ </t>
+ <t>
+As a result, the administrative overhead is reduced
+from the square of the number of systems to a linear dependence, and it becomes
+possible to make secure communication the default even
+when the partner is not known in advance.
+ </t>
+ <t>
+This document is offered up as an Informational RFC.
+ </t>
+</abstract>
+
+</front>
+
+<middle>
+
+<section title="Introduction">
+
+<section title="Motivation">
+
+<t>
+The objective of opportunistic encryption is to allow encryption without
+any pre-arrangement specific to the pair of systems involved. Each
+system administrator adds
+public key information to DNS records to support opportunistic
+encryption and then enables this feature in the nodes' IPsec stack.
+Once this is done, any two such nodes can communicate securely.
+</t>
+
+<t>
+This document describes opportunistic encryption as designed and
+implemented by the Linux FreeS/WAN project in revisions up and including 2.00.
+Note that 2.01 and beyond implements RFC3445, in a backward compatible way.
+For project information, see http://www.freeswan.org.
+</t>
+
+ <t>
+The Internet Architecture Board (IAB) and Internet Engineering
+Steering Group (IESG) have taken a strong stand that the Internet
+should use powerful encryption to provide security and
+privacy <xref target="RFC1984" />.
+The Linux FreeS/WAN project attempts to provide a practical means to implement this policy.
+ </t>
+
+ <t>
+The project uses the IPsec, ISAKMP/IKE, DNS and DNSSEC
+protocols because they are
+standardized, widely available and can often be deployed very easily
+without changing hardware or software or retraining users.
+ </t>
+
+ <t>
+The extensions to support opportunistic encryption are simple. No
+changes to any on-the-wire formats are needed. The only changes are to
+the policy decision making system. This means that opportunistic
+encryption can be implemented with very minimal changes to an existing
+IPsec implementation.
+ </t>
+
+ <t>
+Opportunistic encryption creates a "fax effect". The proliferation
+of the fax machine was possible because it did not require that everyone
+buy one overnight. Instead, as each person installed one, the value
+of having one increased - as there were more people that could receive faxes.
+Once opportunistic encryption is installed it
+automatically recognizes
+other boxes using opportunistic encryption, without any further configuration
+by the network
+administrator. So, as opportunistic encryption software is installed on more
+boxes, its value
+as a tool increases.
+</t>
+
+ <t>
+This document describes the infrastructure to permit deployment of
+Opportunistic Encryption.
+</t>
+
+ <t>
+The term S/WAN is a trademark of RSA Data Systems, and is used with permission
+by this project.
+ </t>
+
+</section>
+
+<section title="Types of network traffic">
+ <t>
+ To aid in understanding the relationship between security processing and IPsec
+ we divide network traffic into four categories:
+ <list style="hanging">
+ <t hangText="* Deny:"> networks to which traffic is always forbidden.</t>
+ <t hangText="* Permit:"> networks to which traffic in the clear is permitted.</t>
+ <t hangText="* Opportunistic tunnel:"> networks to which traffic is encrypted if possible, but otherwise is in the clear
+ or fails depending on the default policy in place.
+ </t>
+ <t hangText="* Configured tunnel:"> networks to which traffic
+must be encrypted, and traffic in the clear is never permitted.
+A Virtual Private Network (VPN) is a form of configured tunnel.
+</t>
+ </list>
+ </t>
+
+<t>
+Traditional firewall devices handle the first two categories.
+No authentication is required.
+The permit policy is currently the default on the Internet.
+</t>
+
+<t>
+This document describes the third category - opportunistic tunnel, which is
+proposed as the new default for the Internet.
+</t>
+
+<t>
+ Category four, encrypt traffic or drop it, requires authentication of the
+ end points. As the number of end points is typically bounded and is typically
+ under a single authority, arranging for distribution of
+ authentication material, while difficult, does not require any new
+ technology. The mechanism described here provides an additional way to
+ distribute the authentication materials, that of a public key method that does not
+ require deployment of an X.509 based infrastructure.
+</t>
+<t>
+Current Virtual Private Networks can often be replaced by an "OE paranoid"
+policy as described herein.
+</t>
+</section>
+
+<section title="Peer authentication in opportunistic encryption">
+
+ <t>
+ Opportunistic encryption creates tunnels between nodes that
+ are essentially strangers. This is done without any prior bilateral
+ arrangement.
+ There is, therefore, the difficult question of how one knows to whom one is
+ talking.
+ </t>
+
+ <t>
+ One possible answer is that since no useful
+ authentication can be done, none should be tried. This mode of operation is
+ named "anonymous encryption". An active man-in-the-middle attack can be
+ used to thwart the privacy of this type of communication.
+ Without peer authentication, there is no way to prevent this kind of attack.
+ </t>
+
+ <t>
+Although a useful mode, anonymous encryption is not the goal of this
+project. Simpler methods are available that can achieve anonymous
+encryption only, but authentication of the peer is a desireable goal.
+The latter is achieved through key distribution in DNS, leveraging upon
+the authentication of the DNS in DNSSEC.
+</t>
+
+ <t>
+ Peers are, therefore, authenticated with DNSSEC when available. Local policy
+determines how much trust to extend when DNSSEC is not available.
+ </t>
+
+ <t>
+ However, an essential premise of building private connections with
+ strangers is that datagrams received through opportunistic tunnels
+ are no more special than datagrams that arrive in the clear.
+ Unlike in a VPN, these datagrams should not be given any special
+ exceptions when it comes to auditing, further authentication or
+ firewalling.
+ </t>
+
+ <t>
+ When initiating outbound opportunistic encryption, local
+ configuration determines what happens if tunnel setup fails. It may be that
+ the packet goes out in the clear, or it may be dropped.
+ </t>
+
+ </section>
+
+<section title="Use of RFC2119 terms">
+<t>
+ 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 <xref target="RFC2119" />
+</t>
+</section>
+
+</section>
+
+<section title="Overview">
+
+ <section title="Reference diagram">
+
+ <figure anchor="networkdiagram" title="Reference Network Diagram">
+ <preamble>The following network diagram is used in the rest of
+ this document as the canonical diagram:</preamble>
+ <artwork>
+ [Q] [R]
+ . . AS2
+ [A]----+----[SG-A].......+....+.......[SG-B]-------[B]
+ | ......
+ AS1 | ..PI..
+ | ......
+ [D]----+----[SG-D].......+....+.......[C] AS3
+
+
+ </artwork>
+ <postamble></postamble>
+
+ </figure>
+
+ <t>
+ In this diagram, there are four end-nodes: A, B, C and D.
+ There are three security gateways, SG-A, SG-B, SG-D. A, D, SG-A and
+ SG-D are part
+ of the same administrative authority, AS1. SG-A and SG-D are on two
+ different exit
+ paths from organization 1. SG-B/B is an independent organization, AS2.
+ Nodes Q and R are nodes on the Internet. PI is the Public
+ Internet ("The Wild").
+ </t>
+
+ </section>
+
+ <section title="Terminology">
+
+ <t>
+ The following terminology is used in this document:
+ </t>
+
+ <list style="hanging">
+ <t hangText="Security gateway (or simply gateway):"> a system that performs IPsec tunnel
+ mode encapsulation/decapsulation. [SG-x] in the diagram.</t>
+ <t hangText="Alice:"> node [A] in the diagram. When an IP address is needed, this is 192.1.0.65.</t>
+ <t hangText="Bob:"> node [B] in the diagram. When an IP address is needed, this is 192.2.0.66.</t>
+ <t hangText="Carol:"> node [C] in the diagram. When an IP address is needed, this is 192.1.1.67.</t>
+ <t hangText="Dave:"> node [D] in the diagram. When an IP address is needed, this is 192.3.0.68.</t>
+ <t hangText="SG-A:"> Alice's security gateway. Internally it is 192.1.0.1, externally it is 192.1.1.4.</t>
+ <t hangText="SG-B:"> Bob's security gateway. Internally it is 192.2.0.1, externally it is 192.1.1.5.</t>
+ <t hangText="SG-D:"> Dave's security gateway. Also Alice's backup security gateway. Internally it is 192.3.0.1, externally it is 192.1.1.6.</t>
+ <t hangText="."> A period represents an untrusted network of unknown
+ type.</t>
+ <t hangText="Configured tunnel:"> a tunnel that
+ is directly and deliberately hand configured on participating gateways.
+ Configured tunnels are typically given a higher level of
+ trust than opportunistic tunnels.</t>
+
+ <t hangText="Road warrior tunnel:"> a configured tunnel connecting one
+ node with a fixed IP address and one node with a variable IP address.
+ A road warrior (RW) connection must be initiated by the
+ variable node, since the fixed node cannot know the
+ current address for the road warrior. </t>
+
+ <t hangText="Anonymous encryption:">
+ the process of encrypting a session without any knowledge of who the
+ other parties are. No authentication of identities is done.</t>
+
+ <t hangText="Opportunistic encryption:">
+ the process of encrypting a session with authenticated knowledge of
+ who the other party is.</t>
+
+ <t hangText="Lifetime:">
+ the period in seconds (bytes or datagrams) for which a security
+ association will remain alive before needing to be re-keyed.</t>
+
+ <t hangText="Lifespan:">
+ the effective time for which a security association remains useful. A
+ security association with a lifespan shorter than its lifetime would
+ be removed when no longer needed. A security association with a
+ lifespan longer than its lifetime would need to be re-keyed one or
+ more times.</t>
+
+ <t hangText="Phase 1 SA:"> an ISAKMP/IKE security association sometimes
+ referred to as a keying channel.</t>
+
+ <t hangText="Phase 2 SA:"> an IPsec security association.</t>
+
+ <t hangText="Tunnel:"> another term for a set of phase 2 SA (one in each direction).</t>
+
+ <t hangText="NAT:"> Network Address Translation
+ (see <xref target="RFC2663" />).</t>
+
+ <t hangText="NAPT:"> Network Address and Port Translation
+ (see <xref target="RFC2663" />).</t>
+
+ <t hangText="AS:"> an autonomous system </t>
+
+ <t hangText="FQDN:"> Fully-Qualified Domain Name </t>
+
+ <t hangText="Default-free zone:">
+ a set of routers that maintain a complete set of routes to
+ all currently reachable destinations. Having such a list, these routers
+ never make use of a default route. A datagram with a destination address
+ not matching any route will be dropped by such a router.
+ </t>
+
+ </list>
+ </section>
+
+<section title="Model of operation">
+
+<t>
+The opportunistic encryption security gateway (OE gateway) is a regular
+gateway node as described in <xref target="RFC0791" /> section 2.4 and
+<xref target="RFC1009" /> with the additional capabilities described here and
+in <xref target="RFC2401" />.
+The algorithm described here provides a way to determine, for each datagram,
+whether or not to encrypt and tunnel the datagram. Two important things
+that must be determined are whether or not to encrypt and tunnel and, if
+so, the destination address or name of the tunnel end point which should be used.
+</t>
+
+<section title="Tunnel authorization">
+<t>
+The OE gateway determines whether or not to create a tunnel based on
+the destination address of each packet. Upon receiving a packet with a destination
+address not recently seen, the OE gateway performs a lookup in DNS for an
+authorization resource record (see <xref target="TXT"/>). The record is located using
+the IP address to perform a search in the in-addr.arpa (IPv4) or ip6.arpa
+(IPv6) maps. If an authorization record is found, the OE gateway
+interprets this as a request for a tunnel to be formed.
+</t>
+</section>
+
+<section title="Tunnel end-point discovery">
+
+<t>
+The authorization resource record also provides the address or name of the tunnel
+end point which should be used.
+</t>
+<t>
+The record may also provide the public RSA key of the tunnel end point
+itself. This is provided for efficiency only. If the public RSA key is not
+present, the OE gateway performs a second lookup to find a KEY
+resource record for the end point address or name.
+</t>
+<t>
+Origin and integrity protection of the resource records is provided by
+DNSSEC (<xref target="RFC2535"/>). <xref target="nodnssec"/>
+documents an optional restriction on the tunnel end point if DNSSEC signatures
+are not available for the relevant records.
+</t>
+
+</section>
+
+<section title="Caching of authorization results">
+<t>
+The OE gateway maintains a cache, in the forwarding plane, of
+source/destination pairs for which opportunistic encryption has been
+attempted. This cache maintains a record of whether or not OE was
+successful so that subsequent datagrams can be forwarded properly
+without additional delay.
+</t>
+
+<t>
+Successful negotiation of OE instantiates a new security association.
+Failure to negotiate OE results in creation of a
+forwarding policy entry either to drop or transmit in the clear future
+datagrams. This negative cache is necessary to avoid the possibly lengthy process of repeatedly looking
+up the same information.
+</t>
+
+<t>
+The cache is timed out periodically, as described in <xref target="teardown" />.
+This removes entries that are no longer
+being used and permits the discovery of changes in authorization policy.
+</t>
+</section>
+
+</section> <!-- "Model of operation" -->
+
+</section> <!-- "Overview" -->
+
+<section title="Protocol Specification">
+
+<t>
+The OE gateway is modeled to have a forwarding plane and a control
+plane. A control channel, such as PF_KEY, connects the two planes.
+(See <xref target="RFC2367" />.)
+The forwarding plane performs per datagram operations. The control plane
+contains a keying daemon, such as ISAKMP/IKE, and performs all
+authorization, peer authentication and key derivation functions.
+</t>
+
+<section title="Forwarding plane state machine">
+
+<t>
+Let the OE gateway maintain a collection of objects -- a superset of the
+security policy database (SPD) specified in <xref target="RFC2401" />. For
+each combination of source and destination address, an SPD
+object exists in one of five following states.
+Prior to forwarding each datagram, the responder uses the source and
+destination addresses to pick an entry from the SPD.
+The SPD then determines if and how the packet is forwarded.
+</t>
+
+<!-- from file forwardingstate.txt -->
+<artwork><![CDATA[
+ .--------------.
+ | non-existant |
+ | policy |
+ `--------------'
+ |
+ | PF_ACQUIRE
+ |
+ |<---------.
+ V | new packet
+ .--------------. | (maybe resend PF_ACQUIRE)
+ | hold policy |--'
+ | |--.
+ `--------------' \ pass
+ | | \ msg .---------.
+ | | \ V | forward
+ | | .-------------. | packet
+ create | | | pass policy |--'
+ IPsec | | `-------------'
+ SA | |
+ | \
+ | \
+ V \ deny
+ .---------. \ msg
+ | encrypt | \
+ | policy | \ ,---------.
+ `---------' \ | | discard
+ \ V | packet
+ .-------------. |
+ | deny policy |--'
+ '-------------'
+]]></artwork>
+
+
+<section title="Non-existent policy">
+<t>
+If the gateway does not find an entry, then this policy applies.
+The gateway creates an entry with an initial state of "hold policy" and requests
+keying material from the keying daemon. The gateway does not forward the datagram,
+rather it SHOULD attach the datagram to the SPD entry as the "first" datagram and retain it
+for eventual transmission in a new state.
+
+</t>
+</section>
+
+<section title="Hold policy">
+<t>
+The gateway requests keying material. If the interface to the keying
+system is lossy (PF_KEY, for instance, can be), the implementation
+SHOULD include a mechanism to retransmit the
+keying request at a rate limited to less than 1 request per second.
+The gateway does not forward the datagram. The gateway SHOULD attach the
+datagram to the SPD entry as the "last" datagram where it is retained
+for eventual transmission.
+If there is a datagram already so stored, then that already stored datagram is discarded.
+</t>
+<t>
+The rational behind saving the the "first" and "last" datagrams are as follows:
+The "first" datagram is probably a TCP SYN packet. Once there is keying
+established, the gateway will release this datagram, avoiding the need to
+for the end-point to retransmit the datagram. In the case where the connection
+was not a TCP connection, buyt was instead a streaming protocol or a DNS request,
+the "last" datagram that was retained is likely the most recent data. The difference
+between "first" and "last" may also help the end-points determine
+which data awas dropped while negotiation took place.
+</t>
+</section>
+
+<section title="Pass-through policy">
+<t>
+The gateway forwards the datagram using the normal forwarding table.
+The gateway enters this state only by command from the keying daemon,
+and upon entering this state, also forwards the "first" and "last" datagrams.
+</t>
+</section>
+
+<section title="Deny policy">
+<t>
+The gateway discards the datagram. The gateway enters this state only by
+command
+from the keying daemon, and upon entering this state, discards the "first"
+and "last" datagrams.
+An implementation MAY provide the administator with a control to determine
+if further datagrams cause ICMP messages
+to be generated (i.e. ICMP Destination Unreachable, Communication
+Administratively Prohibited. type=3, code=13).
+</t>
+</section>
+
+<section title="Encrypt policy">
+<t>
+The gateway encrypts the datagram using the indicated security association database
+(SAD) entry. The gateway enters this state only by command from the keying daemon, and upon entering
+this state, releases and forwards the "first" and "last" datagrams using the
+new encrypt policy.
+</t>
+<t>
+If the associated SAD entry expires because of byte, packet or time limits, then
+the entry returns to the Hold policy, and an expire message is sent to the keying daemon.
+</t>
+</section>
+
+<t>
+All states may be created directly by the keying daemon while acting as a
+gateway.
+</t>
+
+</section> <!-- "Datagram state machine" -->
+
+
+<section anchor="initclasses" title="Keying Daemon -- initiator">
+<t>
+Let the keying daemon maintain a collection of objects. Let them be
+called "connections" or "conn"s. There are two categories of
+connection objects: classes and instances. A class represents an
+abstract policy - what could be. An instance represents an actual connection -
+what is implemented at the time.
+</t>
+
+<t>
+Let there be two further subtypes of connections: keying channels (Phase
+1 SAs) and data channels (Phase 2 SAs). Each data channel object may have
+a corresponding SPD and SAD entry maintained by the datagram state machine.
+</t>
+
+<t>
+For the purposes of opportunistic encryption, there MUST, at least, be
+connection classes known as "deny", "always-clear-text", "OE-permissive", and
+"OE-paranoid".
+The latter two connection classes define a set of source and/or destination
+addresses for which opportunistic encryption will be attempted.
+The administrator MAY set policy options in a number of additional places.
+An implementation MAY create additional connection classes to further refine
+these policies.
+</t>
+
+<t>
+The simplest system may need only the "OE-permissive" connection, and would
+list its own (single) IP address as the source address of this policy and
+the wild-card address 0.0.0.0/0 as the destination IPv4 address. That is, the
+simplest policy is to try opportunistic encryption with all destinations.
+</t>
+
+<t>
+The distinction between permissive and paranoid OE use will become clear
+in the state transition differences. In general a permissive OE will, on
+failure, install a pass-through policy, while a paranoid OE will, on failure,
+install a drop policy.
+</t>
+
+<t>
+In this description of the keying machine's state transitions, the states
+associated with the keying system itself are omitted because they are best documented in the keying system
+(<xref target="RFC2407" />,
+<xref target="RFC2408" /> and <xref target="RFC2409" /> for ISAKMP/IKE),
+and the details are keying system specific. Opportunistic encryption is not
+dependent upon any specific keying protocol, but this document does provide
+requirements for those using ISAKMP/IKE to assure that implementations inter-operate.
+</t>
+<t>
+The state transitions that may be involved in communicating with the
+forwarding plane are omitted. PF_KEY and similar protocols have their own
+set of states required for message sends and completion notifications.
+</t>
+<t>
+Finally, the retransmits and recursive lookups that are normal for DNS are
+not included in this description of the state machine.
+</t>
+
+<!-- from file initiatorstate.txt -->
+<artwork><![CDATA[
+
+ |
+ | PF_ACQUIRE
+ |
+ V
+ .---------------.
+ | non-existant |
+ | connection |
+ `---------------'
+ | | |
+ send , | \
+expired pass / | \ send
+conn. msg / | \ deny
+ ^ / | \ msg
+ | V | do \
+.---------------. | DNS \ .---------------.
+| clear-text | | lookup `->| deny |---> expired
+| connection | | for | connection | connection
+`---------------' | destination `---------------'
+ ^ ^ | ^
+ | | no record | |
+ | | OE-permissive V | no record
+ | | .---------------. | OE-paranoid
+ | `------------| potential OE |---------'
+ | | connection | ^
+ | `---------------' |
+ | | |
+ | | got TXT record | DNSSEC failure
+ | | reply |
+ | V | wrong
+ | .---------------. | failure
+ | | authenticate |---------'
+ | | & parse TXT RR| ^
+ | repeated `---------------' |
+ | ICMP | |
+ | failures | initiate IKE to |
+ | (short-timeout) | responder |
+ | V |
+ | phase-2 .---------------. | failure
+ | failure | pending |---------'
+ | (normal | OE | ^
+ | timeout) | |invalid | phase-2 failure (short-timeout)
+ | | |<--.SPI | ICMP failures (normal timeout)
+ | | | | |
+ | | +=======+ |---' |
+ | | | IKE | | ^ |
+ `--------------| | states|---------------'
+ | +=======+ | |
+ `---------------' |
+ | IPsec SA | invalid SPI
+ | established |
+ V | rekey time
+ .--------------. |
+ | keyed |<---|-------------------------------.
+ | connection |----' |
+ `--------------' |
+ | timer |
+ | |
+ V |
+ .--------------. connection still active |
+ clear-text----->| expired |------------------------------------'
+ deny----->| connection |
+ `--------------'
+ | dead connected - deleted
+ V
+]]></artwork>
+
+
+<section title="Nonexistent connection">
+<t>
+There is no connection instance for a given source/destination address pair.
+Upon receipt of a request for keying material for this
+source/destination pair, the initiator searches through the connection classes to
+determine the most appropriate policy. Upon determining an appropriate
+connection class, an instance object is created of that type.
+Both of the OE types result in a potential OE connection.
+</t>
+<t>Failure to find an appropriate connection class results in an
+administrator defined default.
+</t>
+<t>
+In each case, when the initiator finds an appropriate class for the new flow,
+an instance connection is made of the class which matched.
+</t>
+</section>
+
+<section title="Clear-text connection">
+<t>
+The non-existent connection makes a transition to this state when an
+always-clear-text class is instantiated, or when an OE-permissive
+connection fails. During the transition, the initiator creates a pass-through
+policy object in the forwarding plane for the appropriate flow.
+</t>
+<t>
+Timing out is the only way to leave this state
+(see <xref target="expiring" />).
+</t>
+</section>
+
+<section title="Deny connection">
+<t>
+The empty connection makes a transition to this state when a
+deny class is instantiated, or when an OE-paranoid connection fails.
+During the transition, the initiator creates a deny policy object in the forwarding plane
+for the appropriate flow.
+</t>
+<t>
+Timing out is the only way to leave this state
+(see <xref target="expiring" />).
+</t>
+</section>
+
+<section title="Potential OE connection">
+<t>
+The empty connection makes a transition to this state when one of either OE class is instantiated.
+During the transition to this state, the initiator creates a hold policy object in the
+forwarding plane for the appropriate flow.
+</t>
+<t>
+In addition, when making a transition into this state, DNS lookup is done in
+the reverse-map for a TXT delegation resource record (see <xref target="TXT" />).
+The lookup key is the destination address of the flow.
+</t>
+<t>
+There are three ways to exit this state:
+<list style="numbers">
+<t>DNS lookup finds a TXT delegation resource record.</t>
+<t>DNS lookup does not find a TXT delegation resource record.</t>
+<t>DNS lookup times out.</t>
+</list>
+</t>
+
+<t>
+Based upon the results of the DNS lookup, the potential OE connection makes a
+transition to the pending OE connection state. The conditions for a
+successful DNS look are:
+<list style="numbers">
+<t>DNS finds an appropriate resource record</t>
+<t>It is properly formatted according to <xref target="TXT" /></t>
+<t> if DNSSEC is enabled, then the signature has been vouched for.</t>
+</list>
+
+Note that if the initiator does not find the public key
+present in the TXT delegation record, then the public key must
+be looked up as a sub-state. Only successful completion of all the
+DNS lookups is considered a success.
+</t>
+<t>
+If DNS lookup does not find a resource record or DNS times out, then the
+initiator considers the receiver not OE capable. If this is an OE-paranoid instance,
+then the potential OE connection makes a transition to the deny connection state.
+If this is an OE-permissive instance, then the potential OE connection makes a transition to the
+clear-text connection state.
+</t>
+<t>
+If the initiator finds a resource record but it is not properly formatted, or
+if DNSSEC is
+enabled and reports a failure to authenticate, then the potential OE
+connection makes a
+transition to the deny connection state. This action SHOULD be logged. If the
+administrator wishes to override this transition between states, then an
+always-clear class can be installed for this flow. An implementation MAY make
+this situation a new class.
+</t>
+
+<section anchor="nodnssec" title="Restriction on unauthenticated TXT delegation records">
+<t>
+An implementation SHOULD also provide an additional administrative control
+on delegation records and DNSSEC. This control would apply to delegation
+records (the TXT records in the reverse-map) that are not protected by
+DNSSEC.
+Records of this type are only permitted to delegate to their own address as
+a gateway. When this option is enabled, an active attack on DNS will be
+unable to redirect packets to other than the original destination.
+<!-- This was asked for by Bill Sommerfeld -->
+</t>
+</section>
+</section>
+
+<section title="Pending OE connection">
+<t>
+The potential OE connection makes a transition to this state when
+the initiator determines that all the information required from the DNS lookup is present.
+Upon entering this state, the initiator attempts to initiate keying to the gateway
+provided.
+</t>
+<t>
+Exit from this state occurs either with a successfully created IPsec SA, or
+with a failure of some kind. Successful SA creation results in a transition
+to the key connection state.
+</t>
+<t>
+Three failures have caused significant problems. They are clearly not the
+only possible failures from keying.
+</t>
+<t>
+Note that if there are multiple gateways available in the TXT delegation
+records, then a failure can only be declared after all have been
+tried. Further, creation of a phase 1 SA does not constitute success. A set
+of phase 2 SAs (a tunnel) is considered success.
+</t>
+<t>
+The first failure occurs when an ICMP port unreachable is consistently received
+without any other communication, or when there is silence from the remote
+end. This usually means that either the gateway is not alive, or the
+keying daemon is not functional. For an OE-permissive connection, the initiator makes a transition
+to the clear-text connection but with a low lifespan. For an OE-pessimistic connection,
+the initiator makes a transition to the deny connection again with a low lifespan. The
+lifespan in both
+cases is kept low because the remote gateway may
+be in the process of rebooting or be otherwise temporarily unavailable.
+</t>
+<t>
+The length of time to wait for the remote keying daemon to wake up is
+a matter of some debate. If there is a routing failure, 5 minutes is usually long
+enough for the network to
+re-converge. Many systems can reboot in that amount of
+time as well. However, 5 minutes is far too long for most users to wait to
+hear that they can not connect using OE. Implementations SHOULD make this a
+tunable parameter.
+</t>
+<t>
+The second failure occurs after a phase 1 SA has been created, but there is
+either no response to the phase 2 proposal, or the initiator receives a
+negative notify (the notify must be
+authenticated). The remote gateway is not prepared to do OE at this time.
+As before, the initiator makes a transition to the clear-text or the deny
+connection based upon connection class, but this
+time with a normal lifespan.
+</t>
+<t>
+The third failure occurs when there is signature failure while authenticating
+the remote gateway. This can occur when there has been a
+key roll-over, but DNS has not caught up. In this case again, the initiator makes a
+transition to the clear-text or the deny connection based
+upon the connection class. However, the lifespan depends upon the remaining
+time to live in the DNS. (Note that DNSSEC signed resource records have a different
+expiry time than non-signed records.)
+<!-- dig @gateway would also work here -->
+</t>
+
+</section>
+
+<section anchor="keyed" title="Keyed connection">
+<t>
+The pending OE connection makes a transition to this state when
+session keying material (the phase 2 SAs) is derived. The initiator creates an encrypt
+policy in the forwarding plane for this flow.
+</t>
+<t>
+There are three ways to exit this state. The first is by receipt of an
+authenticated delete message (via the keying channel) from the peer. This is
+normal teardown and results in a transition to the expired connection state.
+</t>
+<t>
+The second exit is by expiry of the forwarding plane keying material. This
+starts a re-key operation with a transition back to pending OE
+connection. In general, the soft expiry occurs with sufficient time left
+to continue to use the keys. A re-key can fail, which may
+result in the connection failing to clear-text or deny as
+appropriate. In the event of a failure, the forwarding plane
+policy does not change until the phase 2 SA (IPsec SA) reaches its
+hard expiry.
+</t>
+<t>
+The third exit is in response to a negotiation from a remote
+gateway. If the forwarding plane signals the control plane that it has received an
+unknown SPI from the remote gateway, or an ICMP is received from the remote gateway
+indicating an unknown SPI, the initiator should consider that
+the remote gateway has rebooted or restarted. Since these
+indications are easily forged, the implementation must
+exercise care. The initiator should make a cautious
+(rate-limited) attempt to re-key the connection.
+</t>
+</section>
+
+<section anchor="expiring" title="Expiring connection">
+<t>
+The initiator will periodically place each of the deny, clear-text, and keyed
+connections into this
+sub-state. See <xref target="teardown" /> for more details of how often this
+occurs.
+The initiator queries the forwarding plane for last use time of the
+appropriate
+policy. If the last use time is relatively recent, then the connection
+returns to the
+previous deny, clear-text or keyed connection state. If not, then the
+connection enters
+the expired connection state.
+</t>
+<t>
+The DNS query and answer that lead to the expiring connection state are also
+examined. The DNS query may become stale. (A negative, i.e. no such record, answer
+is valid for the period of time given by the MINIMUM field in an attached SOA
+record. See <xref target="RFC1034" /> section 4.3.4.)
+If the DNS query is stale, then a new query is made. If the results change, then the connection
+makes a transition to a new state as described in potential OE connection state.
+</t>
+<t>
+Note that when considering how stale a connection is, both outgoing SPD and
+incoming SAD must be queried as some flows may be unidirectional for some time.
+</t>
+<t>
+Also note that the policy at the forwarding plane is not updated unless there
+is a conclusion that there should be a change.
+</t>
+
+</section>
+<section title="Expired connection">
+<t>
+Entry to this state occurs when no datagrams have been forwarded recently via the
+appropriate SPD and SAD objects. The objects in the forwarding plane are
+removed (logging any final byte and packet counts if appropriate) and the
+connection instance in the keying plane is deleted.
+</t>
+<t>
+The initiator sends an ISAKMP/IKE delete to clean up the phase 2 SAs as described in
+<xref target="teardown" />.
+</t>
+<t>
+Whether or not to delete the phase 1 SAs
+at this time is left as a local implementation issue. Implementations
+that do delete the phase 1 SAs MUST send authenticated delete messages to
+indicate that they are doing so. There is an advantage to keeping
+the phase 1 SAs until they expire - they may prove useful again in the
+near future.
+</t>
+</section>
+
+</section> <!-- "Keying state machine - initiator" -->
+
+<section title="Keying Daemon - responder">
+<t>
+The responder has a set of objects identical to those of the initiator.
+</t>
+<t>
+The responder receives an invitation to create a keying channel from an initiator.
+</t>
+
+<!-- from file responderstate.txt -->
+<artwork><![CDATA[
+ |
+ | IKE main mode
+ | phase 1
+ V
+ .-----------------.
+ | unauthenticated |
+ | OE peer |
+ `-----------------'
+ |
+ | lookup KEY RR in in-addr.arpa
+ | (if ID_IPV4_ADDR)
+ | lookup KEY RR in forward
+ | (if ID_FQDN)
+ V
+ .-----------------. RR not found
+ | received DNS |---------------> log failure
+ | reply |
+ `----+--------+---'
+ phase 2 | \ misformatted
+ proposal | `------------------> log failure
+ V
+ .----------------.
+ | authenticated | identical initiator
+ | OE peer |--------------------> initiator
+ `----------------' connection found state machine
+ |
+ | look for TXT record for initiator
+ |
+ V
+ .---------------.
+ | authorized |---------------------> log failure
+ | OE peer |
+ `---------------'
+ |
+ |
+ V
+ potential OE
+ connection in
+ initiator state
+ machine
+
+
+$Id: draft-richardson-ipsec-opportunistic.xml,v 1.1 2004/03/15 20:35:24 as Exp $
+]]></artwork>
+
+
+<section title="Unauthenticated OE peer">
+<t>
+Upon entering this state, the responder starts a DNS lookup for a KEY record for the
+initiator.
+The responder looks in the reverse-map for a KEY record for the initiator if the
+initiator has offered an ID_IPV4_ADDR, and in the forward map if the
+initiator has offered an ID_FQDN type. (See <xref target="RFC2407" /> section
+4.6.2.1.)
+</t>
+<t>
+The responder exits this state upon successful receipt of a KEY from DNS, and use of the key
+to verify the signature of the initiator.
+</t>
+
+<!--
+<t>
+The public key that is retrieved should be stored in stable storage for an
+administratively defined period of time, (typically several months if
+possible). If a key has previously been stored on disk, then the returned key
+should be compared to what has been received, and the key considered valid
+only if they match.
+</t>
+-->
+
+<t>
+Successful authentication of the peer results in a transition to the
+authenticated OE Peer state.
+</t>
+<t>
+Note that the unauthenticated OE peer state generally occurs in the middle of the key negotiation
+protocol. It is really a form of pseudo-state.
+</t>
+</section>
+
+<section title="Authenticated OE Peer">
+<t>
+The peer will eventually propose one or more phase 2 SAs. The responder uses the source and
+destination address in the proposal to
+finish instantiating the connection state
+using the connection class table.
+The responder MUST search for an identical connection object at this point.
+</t>
+<t>
+If an identical connection is found, then the responder deletes the old instance,
+and the new object makes a transition to the pending OE connection state. This means
+that new ISAKMP connections with a given peer will always use the latest
+instance, which is the correct one if the peer has rebooted in the interim.
+</t>
+<t>
+If an identical connection is not found, then the responder makes the transition according to the
+rules given for the initiator.
+</t>
+<t>
+Note that if the initiator is in OE-paranoid mode and the responder is in
+either always-clear-text or deny, then no communication is possible according
+to policy. An implementation is permitted to create new types of policies
+such as "accept OE but do not initiate it". This is a local matter.
+ </t>
+</section>
+
+</section> <!-- "Keying state machine - responder" -->
+
+<section anchor="teardown" title="Renewal and teardown">
+ <section title="Aging">
+<t>
+A potentially unlimited number of tunnels may exist. In practice, only a few
+tunnels are used during a period of time. Unused tunnels MUST, therefore, be
+torn down. Detecting when tunnels are no longer in use is the subject of this section.
+</t>
+
+<t>
+There are two methods for removing tunnels: explicit deletion or expiry.
+</t>
+
+<t>
+Explicit deletion requires an IKE delete message. As the deletes
+MUST be authenticated, both ends of the tunnel must maintain the
+key channel (phase 1 ISAKMP SA). An implementation which refuses to either maintain or
+recreate the keying channel SA will be unable to use this method.
+</t>
+
+<t>
+The tunnel expiry method simply allows the IKE daemon to
+expire normally without attempting to re-key it.
+</t>
+
+<t>
+Regardless of which method is used to remove tunnels, the implementation MUST
+a method to determine if the tunnel is still in use. The specifics are a
+local matter, but the FreeS/WAN project uses the following criteria. These
+criteria are currently implemented in the key management daemon, but could
+also be implemented at the SPD layer using an idle timer.
+</t>
+
+<t>
+Set a short initial (soft) lifespan of 1 minute since many net flows last
+only a few seconds.
+</t>
+
+<t>
+At the end of the lifespan, check to see if the tunnel was used by
+traffic in either direction during the last 30 seconds. If so, assign a
+longer tentative lifespan of 20 minutes after which, look again. If the
+tunnel is not in use, then close the tunnel.
+</t>
+
+<t>
+The expiring state in the key management
+system (see <xref target="expiring" />) implements these timeouts.
+The timer above may be in the forwarding plane,
+but then it must be re-settable.
+</t>
+
+<t>
+The tentative lifespan is independent of re-keying; it is just the time when
+the tunnel's future is next considered.
+(The term lifespan is used here rather than lifetime for this reason.)
+Unlike re-keying, this tunnel use check is not costly and should happen
+reasonably frequently.
+</t>
+
+<t>
+A multi-step back-off algorithm is not considered worth the effort here.
+</t>
+
+<t>
+If the security gateway and the client host are the
+same and not a Bump-in-the-Stack or Bump-in-the-Wire implementation, tunnel
+teardown decisions MAY pay attention to TCP connection status as reported
+by the local TCP layer. A still-open TCP connection is almost a guarantee that more traffic is
+expected. Closing of the only TCP connection through a tunnel is a
+strong hint that no more traffic is expected.
+</t>
+
+</section> <!-- "Aging" -->
+
+<section title="Teardown and cleanup">
+
+<t>
+Teardown should always be coordinated between the two ends of the tunnel by
+interpreting and sending delete notifications. There is a
+detailed sub-state in the expired connection state of the key manager that
+relates to retransmits of the delete notifications, but this is considered to
+be a keying system detail.
+</t>
+
+<t>
+On receiving a delete for the outbound SAs of a tunnel (or some subset of
+them), tear down the inbound ones also and notify the remote end with a
+delete. If the local system receives a delete for a tunnel which is no longer in
+existence, then two delete messages have crossed paths. Ignore the delete.
+The operation has already been completed. Do not generate any messages in this
+situation.
+</t>
+<t>
+Tunnels are to be considered as bidirectional entities, even though the
+low-level protocols don't treat them this way.
+</t>
+
+<t>
+When the deletion is initiated locally, rather than as a
+response to a received delete, send a delete for (all) the
+inbound SAs of a tunnel. If the local system does not receive a responding delete
+for the outbound SAs, try re-sending the original
+delete. Three tries spaced 10 seconds apart seems a reasonable
+level of effort. A failure of the other end to respond after 3 attempts,
+indicates that the possibility of further communication is unlikely. Remove the outgoing SAs.
+(The remote system may be a mobile node that is no longer present or powered on.)
+</t>
+
+<t>
+After re-keying, transmission should switch to using the new
+outgoing SAs (ISAKMP or IPsec) immediately, and the old leftover
+outgoing SAs should be cleared out promptly (delete should be sent
+for the outgoing SAs) rather than waiting for them to expire. This
+reduces clutter and minimizes confusion for the operator doing diagnostics.
+</t>
+
+</section>
+
+</section>
+
+</section> <!-- "Specification" -->
+
+<section title="Impacts on IKE">
+
+ <section title="ISAKMP/IKE protocol">
+ <t>
+ The IKE wire protocol needs no modifications. The major changes are
+ implementation issues relating to how the proposals are interpreted, and from
+ whom they may come.
+ </t>
+ <t>
+ As opportunistic encryption is designed to be useful between peers without
+ prior operator configuration, an IKE daemon must be prepared to negotiate
+ phase 1 SAs with any node. This may require a large amount of resources to
+ maintain cookie state, as well as large amounts of entropy for nonces,
+ cookies and so on.
+ </t>
+ <t>
+ The major changes to support opportunistic encryption are at the IKE daemon
+ level. These changes relate to handling of key acquisition requests, lookup
+ of public keys and TXT records, and interactions with firewalls and other
+ security facilities that may be co-resident on the same gateway.
+ </t>
+ </section>
+
+ <section title="Gateway discovery process">
+ <t>
+ In a typical configured tunnel, the address of SG-B is provided
+ via configuration. Furthermore, the mapping of an SPD entry to a gateway is
+ typically a 1:1 mapping. When the 0.0.0.0/0 SPD entry technique is used, then
+ the mapping to a gateway is determined by the reverse DNS records.
+ </t>
+ <t>
+ The need to do a DNS lookup and wait for a reply will typically introduce a
+ new state and a new event source (DNS replies) to IKE. Although a
+synchronous DNS request can be implemented for proof of concept, experience
+is that it can cause very high latencies when a queue of queries must
+all timeout in series.
+ </t>
+ <t>
+ Use of an asynchronous DNS lookup will also permit overlap of DNS lookups with
+ some of the protocol steps.
+ </t>
+ </section>
+
+ <section title="Self identification">
+ <t>
+ SG-A will have to establish its identity. Use an
+ IPv4 ID in phase 1.
+ </t>
+ <t> There are many situations where the administrator of SG-A may not be
+ able to control the reverse DNS records for SG-A's public IP address.
+ Typical situations include dialup connections and most residential-type broadband Internet access
+ (ADSL, cable-modem) connections. In these situations, a fully qualified domain
+ name that is under the control of SG-A's administrator may be used
+ when acting as an initiator only.
+ The FQDN ID should be used in phase 1. See <xref target="fqdn" />
+ for more details and restrictions.
+ </t>
+ </section>
+
+ <section title="Public key retrieval process">
+ <t>
+ Upon receipt of a phase 1 SA proposal with either an IPv4 (IPv6) ID or
+ an FQDN ID, an IKE daemon needs to examine local caches and
+ configuration files to determine if this is part of a configured tunnel.
+ If no configured tunnels are found, then the implementation should attempt to retrieve
+ a KEY record from the reverse DNS in the case of an IPv4/IPv6 ID, or
+ from the forward DNS in the case of FQDN ID.
+ </t>
+ <t>
+ It is reasonable that if other non-local sources of policy are used
+ (COPS, LDAP), they be consulted concurrently but some
+ clear ordering of policy be provided. Note that due to variances in
+ latency, implementations must wait for positive or negative replies from all sources
+ of policy before making any decisions.
+ </t>
+ </section>
+
+ <section title="Interactions with DNSSEC">
+ <t>
+ The implementation described (1.98) neither uses DNSSEC directly to
+ explicitly verify the authenticity of zone information, nor uses the NXT
+ records to provide authentication of the absence of a TXT or KEY
+ record. Rather, this implementation uses a trusted path to a DNSSEC
+ capable caching resolver.
+ </t>
+ <t>
+ To distinguish between an authenticated and an unauthenticated DNS
+ resource record, a stub resolver capable of returning DNSSEC
+ information MUST be used.
+ </t>
+
+ </section>
+
+<!--
+ <section title="Interactions with COPS">
+ <t>
+ At this time there is no experience with implementations that interact
+ with COPS Policy Decision Points (PDP) <xref target="RFC2748" />. It is
+ suggested that it may be
+ appropriate for many of
+ the policy and discovery mechanisms outlined here to be done by a PDP.
+ In this context, the IKE daemon present in the Policy Enforcement Point
+ (PEP) may not need any modifications.
+ </t>
+ </section>
+-->
+
+ <section title="Required proposal types">
+
+ <section anchor="phase1id" title="Phase 1 parameters">
+ <t>
+ Main mode MUST be used.
+ </t>
+ <t>
+ The initiator MUST offer at least one proposal using some combination
+ of: 3DES, HMAC-MD5 or HMAC-SHA1, DH group 2 or 5. Group 5 SHOULD be
+ proposed first.
+ <xref target="RFC3526" />
+ </t>
+ <t>
+ The initiator MAY offer additional proposals, but the cipher MUST not
+ be weaker than 3DES. The initiator SHOULD limit the number of proposals
+ such that the IKE datagrams do not need to be fragmented.
+ </t>
+ <t>
+ The responder MUST accept one of the proposals. If any configuration
+ of the responder is required then the responder is not acting in an
+ opportunistic way.
+ </t>
+ <t>
+ The initiator SHOULD use an ID_IPV4_ADDR (ID_IPV6_ADDR for IPv6) of the external
+ interface of the initiator for phase 1. (There is an exception, see <xref
+ target="fqdn" />.) The authentication method MUST be RSA public key signatures.
+ The RSA key for the initiator SHOULD be placed into a DNS KEY record in
+ the reverse space of the initiator (i.e. using in-addr.arpa or
+ ip6.arpa).
+ </t>
+ </section>
+
+ <section anchor="phase2id" title="Phase 2 parameters">
+ <t>
+ The initiator MUST propose a tunnel between the ultimate
+ sender ("Alice" or "A") and ultimate recipient ("Bob" or "B")
+ using 3DES-CBC
+ mode, MD5 or SHA1 authentication. Perfect Forward Secrecy MUST be specified.
+ </t>
+ <t>
+ Tunnel mode MUST be used.
+ </t>
+ <t>
+ Identities MUST be ID_IPV4_ADDR_SUBNET with the mask being /32.
+ </t>
+ <t>
+ Authorization for the initiator to act on Alice's behalf is determined by
+ looking for a TXT record in the reverse-map at Alice's IP address.
+ </t>
+ <t>
+ Compression SHOULD NOT be mandatory. It MAY be offered as an option.
+ </t>
+ </section>
+ </section>
+
+</section>
+
+<section title="DNS issues">
+ <section anchor="KEY" title="Use of KEY record">
+ <t>
+ In order to establish their own identities, security gateways SHOULD publish
+ their public keys in their reverse DNS via
+ DNSSEC's KEY record.
+ See section 3 of <xref target="RFC2535">RFC 2535</xref>.
+ </t>
+ <t>
+ <preamble>For example:</preamble>
+ <artwork><![CDATA[
+KEY 0x4200 4 1 AQNJjkKlIk9...nYyUkKK8
+]]></artwork>
+
+ <list style="hanging">
+ <t hangText="0x4200:"> The flag bits, indicating that this key is prohibited
+ for confidentiality use (it authenticates the peer only, a separate
+ Diffie-Hellman exchange is used for
+ confidentiality), and that this key is associated with the non-zone entity
+ whose name is the RR owner name. No other flags are set.</t>
+ <t hangText="4:">This indicates that this key is for use by IPsec.</t>
+ <t hangText="1:">An RSA key is present.</t>
+ <t hangText="AQNJjkKlIk9...nYyUkKK8:">The public key of the host as described in <xref target="RFC3110" />.</t>
+ </list>
+ </t>
+ <t>Use of several KEY records allows for key rollover. The SIG Payload in
+ IKE phase 1 SHOULD be accepted if the public key given by any KEY RR
+ validates it.
+ </t>
+ </section>
+
+ <section anchor="TXT" title="Use of TXT delegation record">
+ <t>
+If, for example, machine Alice wishes SG-A to act on her behalf, then
+she publishes a TXT record to provide authorization for SG-A to act on
+Alice's behalf. Similarly for Bob and SG-B.
+</t>
+
+<t>
+These records are located in the reverse DNS (in-addr.arpa or ip6.arpa) for their
+respective IP addresses. The reverse DNS SHOULD be secured by DNSSEC.
+DNSSEC is required to defend against active attacks.
+ </t>
+ <t>
+ If Alice's address is P.Q.R.S, then she can authorize another node to
+ act on her behalf by publishing records at:
+ <artwork><![CDATA[
+S.R.Q.P.in-addr.arpa
+ ]]></artwork>
+ </t>
+
+ <t>
+ The contents of the resource record are expected to be a string that
+ uses the following syntax, as suggested in <xref target="RFC1464">RFC1464</xref>.
+ (Note that the reply to query may include other TXT resource
+ records used by other applications.)
+
+ <figure anchor="txtformat" title="Format of reverse delegation record">
+ <artwork><![CDATA[
+X-IPsec-Server(P)=A.B.C.D KEY
+ ]]></artwork>
+ </figure>
+ </t>
+
+ where the record is formed by the following fields:
+
+ <list style="hanging">
+ <t hangText="P:"> Specifies a precedence for this record. This is
+ similar to MX record preferences. Lower numbers have stronger
+ preference.
+ </t>
+
+ <t hangText="A.B.C.D:"> Specifies the IP address of the Security Gateway
+ for this client machine.
+ </t>
+
+ <t hangText="KEY:"> Is the encoded RSA Public key of the Security
+ Gateway. The key is provided here to avoid a second DNS lookup. If this
+ field is absent, then a KEY resource record should be looked up in the
+ reverse-map of A.B.C.D. The key is transmitted in base64 format.
+ </t>
+ </list>
+
+ <t>
+ The fields of the record MUST be separated by whitespace. This
+ MAY be: space, tab, newline, or carriage return. A space is preferred.
+ </t>
+
+ <t>
+ In the case where Alice is located at a public address behind a
+ security gateway that has no fixed address (or no control over its
+ reverse-map), then Alice may delegate to a public key by domain name.
+
+ <figure anchor="txtfqdnformat"
+ title="Format of reverse delegation record (FQDN version)">
+ <artwork><![CDATA[
+X-IPsec-Server(P)=@FQDN KEY
+ ]]></artwork>
+ </figure>
+ </t>
+
+ <list style="hanging">
+ <t hangText="P:"> Is as above.
+ </t>
+
+ <t hangText="FQDN:"> Specifies the FQDN that the Security Gateway
+ will identify itself with.
+ </t>
+
+ <t hangText="KEY:"> Is the encoded RSA Public key of the Security
+ Gateway. </t>
+ </list>
+
+ <t>
+ If there is more than one such TXT record with strongest (lowest
+ numbered) precedence, one Security Gateway is picked arbitrarily from
+ those specified in the strongest-preference records.
+ </t>
+
+ <section title="Long TXT records">
+ <t>
+ When packed into transport format, TXT records which are longer than 255
+ characters are divided into smaller &lt;character-strings&gt;.
+ (See <xref target="RFC1035" /> section 3.3 and 3.3.14.) These MUST
+ be reassembled into a single string for processing.
+ Whitespace characters in the base64 encoding are to be ignored.
+ </t>
+ </section>
+
+ <section title="Choice of TXT record">
+ <t>
+ It has been suggested to use the KEY, OPT, CERT, or KX records
+ instead of a TXT record. None is satisfactory.
+ </t>
+ <t> The KEY RR has a protocol field which could be used to indicate a new protocol,
+and an algorithm field which could be used to
+ indicate different contents in the key data. However, the KEY record
+ is clearly not intended for storing what are really authorizations,
+ it is just for identities. Other uses have been discouraged.
+ </t>
+ <t> OPT resource records, as defined in <xref target="RFC2671" /> are not
+ intended to be used for storage of information. They are not to be loaded,
+ cached or forwarded. They are, therefore, inappropriate for use here.
+ </t>
+ <t>
+ CERT records <xref target="RFC2538" /> can encode almost any set of
+ information. A custom type code could be used permitting any suitable
+ encoding to be stored, not just X.509. According to
+ the RFC, the certificate RRs are to be signed internally which may add undesirable
+and unnecessary bulk. Larger DNS records may require TCP instead of UDP transfers.
+ </t>
+ <t>
+ At the time of protocol design, the CERT RR was not widely deployed and
+ could not be counted upon. Use of CERT records will be investigated,
+ and may be proposed in a future revision of this document.
+ </t>
+ <t>
+ KX records are ideally suited for use instead of TXT records, but had not been deployed at
+ the time of implementation.
+<!-- Jakob Schlyter <j@crt.se> confirmed -->
+ </t>
+ </section>
+ </section>
+
+ <section anchor="fqdn" title="Use of FQDN IDs">
+ <t>
+ Unfortunately, not every administrator has control over the contents
+ of the reverse-map. Where the initiator (SG-A) has no suitable reverse-map, the
+ authorization record present in the reverse-map of Alice may refer to a
+ FQDN instead of an IP address.
+ </t>
+ <t>
+ In this case, the client's TXT record gives the fully qualified domain
+ name (FQDN) in place of its security gateway's IP address.
+ The initiator should use the ID_FQDN ID-payload in phase 1.
+ A forward lookup for a KEY record on the FQDN must yield the
+ initiator's public key.
+ </t>
+ <t>
+ This method can also be used when the external address of SG-A is
+ dynamic.
+ </t>
+ <t>
+ If SG-A is acting on behalf of Alice, then Alice must still delegate
+ authority for SG-A to do so in her reverse-map. When Alice and SG-A
+ are one and the same (i.e. Alice is acting as an end-node) then there
+ is no need for this when initiating only. </t>
+ <t>However, Alice must still delegate to herself if she wishes others to
+ initiate OE to her. See <xref target="txtfqdnformat" />.
+ </t>
+ <
+ </section>
+
+<section title="Key roll-over">
+<t>
+Good cryptographic hygiene says that one should replace public/private key pairs
+periodically. Some administrators may wish to do this as often as daily. Typical DNS
+propagation delays are determined by the SOA Resource Record MINIMUM
+parameter, which controls how long DNS replies may be cached. For reasonable
+operation of DNS servers, administrators usually want this value to be at least several
+hours, sometimes as a long as a day. This presents a problem - a new key MUST
+not be used prior to it propagating through DNS.
+</t>
+<t>
+This problem is dealt with by having the Security Gateway generate a new
+public/private key pair at least MINIMUM seconds in advance of using it. It
+then adds this key to the DNS (both as a second KEY record and in additional TXT
+delegation records) at key generation time. Note: only one key is allowed in
+each TXT record.
+</t>
+<t>
+When authenticating, all gateways MUST have available all public keys
+that are found in DNS for this entity. This permits the authenticating end
+to check both the key for "today" and the key for "tomorrow". Note that it is
+the end which is creating the signature (possesses the private key) that
+determines which key is to be used.
+</t>
+
+ </section>
+</section>
+
+
+<section title="Network address translation interaction">
+ <t>
+ There are no fundamentally new issues for implementing opportunistic encryption
+ in the presence of network address translation. Rather there are
+ only the regular IPsec issues with NAT traversal.
+ </t>
+ <t>
+ There are several situations to consider for NAT.
+ </t>
+ <section title="Co-located NAT/NAPT">
+ <t>
+ If a security gateway is also performing network address translation on
+ behalf of an end-system, then the packet should be translated prior to
+ being subjected to opportunistic encryption. This is in contrast to
+ typically configured tunnels which often exist to bridge islands of
+ private network address space. The security gateway will use the translated source
+ address for phase 2, and so the responding security gateway will look up that address to
+ confirm SG-A's authorization.
+ </t>
+ <t> In the case of NAT (1:1), the address space into which the
+ translation is done MUST be globally unique, and control over the
+ reverse-map is assumed.
+ Placing of TXT records is possible.
+ </t>
+ <t> In the case of NAPT (m:1), the address will be the security
+ gateway itself. The ability to get
+ KEY and TXT records in place will again depend upon whether or not
+ there is administrative control over the reverse-map. This is
+ identical to situations involving a single host acting on behalf of
+ itself.
+
+ FQDN style can be used to get around a lack of a reverse-map for
+ initiators only.
+ </t>
+ </section>
+
+ <section title="Security Gateway behind NAT/NAPT">
+ <t>
+ If there is a NAT or NAPT between the security gateways, then normal IPsec
+ NAT traversal problems occur. In addition to the transport problem
+ which may be solved by other mechanisms, there is the issue of
+ what phase 1 and phase 2 IDs to use. While FQDN could
+ be used during phase 1 for the security gateway, there is no appropriate ID for phase 2.
+ Due to the NAT, the end systems live in different IP address spaces.
+ </t>
+ </section>
+
+ <section title="End System is behind a NAT/NAPT">
+ <t>
+ If the end system is behind a NAT (perhaps SG-B), then there is, in fact, no way for
+ another end system to address a packet to this end system.
+ Not only is opportunistic encryption
+ impossible, but it is also impossible for any communication to
+ be initiate to the end system. It may be possible for this end
+ system to initiate in such communication. This creates an asymmetry, but this is common for
+ NAPT.
+ </t>
+ </section>
+</section>
+
+<section title="Host implementations">
+<t>
+ When Alice and SG-A are components of the same system, they are
+ considered to be a host implementation. The packet sequence scenario remains unchanged.
+</t>
+<t>
+ Components marked Alice are the upper layers (TCP, UDP, the
+ application), and SG-A is the IP layer.
+</t>
+<t>
+ Note that tunnel mode is still required.
+</t>
+<t>
+ As Alice and SG-A are acting on behalf of themselves, no TXT based delegation
+ record is necessary for Alice to initiate. She can rely on FQDN in a
+ forward map. This is particularly attractive to mobile nodes such as
+ notebook computers at conferences.
+ To respond, Alice/SG-A will still need an entry in Alice's reverse-map.
+</t>
+</section>
+
+<section title="Multi-homing">
+<t>
+If there are multiple paths between Alice and Bob (as illustrated in
+the diagram with SG-D), then additional DNS records are required to establish
+authorization.
+</t>
+<t>
+In <xref target="networkdiagram" />, Alice has two ways to
+exit her network: SG-A and SG-D. Previously SG-D has been ignored. Postulate
+that there are routers between Alice and her set of security gateways
+(denoted by the + signs and the marking of an autonomous system number for
+Alice's network). Datagrams may, therefore, travel to either SG-A or SG-D en
+route to Bob.
+</t>
+<t>
+As long as all network connections are in good order, it does not matter how
+datagrams exit Alice's network. When they reach either security gateway, the
+security gateway will find the TXT delegation record in Bob's reverse-map,
+and establish an SA with SG-B.
+</t>
+<t>
+SG-B has no problem establishing that either of SG-A or SG-D may speak for
+Alice, because Alice has published two equally weighted TXT delegation records:
+ <figure anchor="txtmultiexample"
+ title="Multiple gateway delegation example for Alice">
+ <artwork><![CDATA[
+X-IPsec-Server(10)=192.1.1.5 AQMM...3s1Q==
+X-IPsec-Server(10)=192.1.1.6 AAJN...j8r9==
+ ]]></artwork>
+ </figure>
+</t>
+<t>
+Alice's routers can now do any kind of load sharing needed. Both SG-A and SG-D send datagrams addressed to Bob through
+their tunnel to SG-B.
+</t>
+<t>
+Alice's use of non-equal weight delegation records to show preference of one gateway over another, has relevance only when SG-B
+is initiating to Alice.
+</t>
+<t>
+If the precedences are the same, then SG-B has a more difficult time. It
+must decide which of the two tunnels to use. SG-B has no information about
+which link is less loaded, nor which security gateway has more cryptographic
+resources available. SG-B, in fact, has no knowledge of whether both gateways
+are even reachable.
+</t>
+<t>
+The Public Internet's default-free zone may well know a good route to Alice,
+but the datagrams that SG-B creates must be addressed to either SG-A or SG-D;
+they can not be addressed to Alice directly.
+</t>
+<t>
+SG-B may make a number of choices:
+<list style="numbers">
+<t>It can ignore the problem and round robin among the tunnels. This
+ causes losses during times when one or the other security gateway is
+ unreachable. If this worries Alice, she can change the weights in her
+ TXT delegation records.</t>
+
+<t>It can send to the gateway from which it most recently received datagrams.
+ This assumes that routing and reachability are symmetrical.</t>
+
+<t>It can listen to BGP information from the Internet to decide which
+ system is currently up. This is clearly much more complicated, but if SG-B is already participating
+ in the BGP peering system to announce Bob, the results data may already
+ be available to it. </t>
+
+<t>It can refuse to negotiate the second tunnel. (It is unclear whether or
+not this is even an option.)</t>
+
+<t>It can silently replace the outgoing portion of the first tunnel with the
+second one while still retaining the incoming portions of both. SG-B can,
+thus, accept datagrams from either SG-A or SG-D, but
+send only to the gateway that most recently re-keyed with it.</t>
+</list>
+</t>
+
+<t>
+Local policy determines which choice SG-B makes. Note that even if SG-B has perfect
+knowledge about the reachability of SG-A and SG-D, Alice may not be reachable
+from either of these security gateways because of internal reachability
+issues.
+</t>
+
+<t>
+FreeS/WAN implements option 5. Implementing a different option is
+being considered. The multi-homing aspects of OE are not well developed and may
+be the subject of a future document.
+</t>
+
+</section>
+
+<section title="Failure modes">
+ <section title="DNS failures">
+ <t>
+ If a DNS server fails to respond, local policy decides
+ whether or not to permit communication in the clear as embodied in
+ the connection classes in <xref target="initclasses" />.
+ It is easy to mount a denial of service attack on the DNS server
+ responsible for a particular network's reverse-map.
+ Such an attack may cause all communication with that network to go in
+ the clear if the policy is permissive, or fail completely
+ if the policy is paranoid. Please note that this is an active attack.
+ </t>
+ <t>
+ There are still many networks
+ that do not have properly configured reverse-maps. Further, if the policy is not to communicate,
+ the above denial of service attack isolates the target network. Therefore, the decision of whether
+or not to permit communication in the clear MUST be a matter of local policy.
+ </t>
+ </section>
+
+ <section title="DNS configured, IKE failures">
+ <t>
+ DNS records claim that opportunistic encryption should
+ occur, but the target gateway either does not respond on port 500, or
+ refuses the proposal. This may be because of a crash or reboot, a
+ faulty configuration, or a firewall filtering port 500.
+ </t>
+ <t>
+ The receipt of ICMP port, host or network unreachable
+ messages indicates a potential problem, but MUST NOT cause communication
+ to fail
+ immediately. ICMP messages are easily forged by attackers. If such a
+ forgery caused immediate failure, then an active attacker could easily
+ prevent any
+ encryption from ever occurring, possibly preventing all communication.
+ </t>
+ <t>
+ In these situations a clear log should be produced
+ and local policy should dictate if communication is then
+ permitted in the clear.
+ </t>
+ </section>
+
+ <section title="System reboots">
+<t>
+Tunnels sometimes go down because the remote end crashes,
+disconnects, or has a network link break. In general there is no
+notification of this. Even in the event of a crash and successful reboot,
+other SGs don't hear about it unless the rebooted SG has specific
+reason to talk to them immediately. Over-quick response to temporary
+network outages is undesirable. Note that a tunnel can be torn
+down and then re-established without any effect visible to the user
+except a pause in traffic. On the other hand, if one end reboots,
+the other end can't get datagrams to it at all (except via
+IKE) until the situation is noticed. So a bias toward quick
+response is appropriate even at the cost of occasional
+false alarms.
+</t>
+
+<t>
+A mechanism for recovery after reboot is a topic of current research and is not specified in this
+document.
+</t>
+
+<t>
+A deliberate shutdown should include an attempt, using deletes, to notify all other SGs
+currently connected by phase 1 SAs that communication is
+about to fail. Again, a remote SG will assume this is a teardown. Attempts by the
+remote SGs to negotiate new tunnels as replacements should be ignored. When possible,
+SGs should attempt to preserve information about currently-connected SGs in non-volatile storage, so
+that after a crash, an Initial-Contact can be sent to previous partners to
+indicate loss of all previously established connections.
+</t>
+
+ </section>
+</section>
+
+<!--
+<section title="Performance experiences">
+
+ Claudia> Is it useful to point out (or to clarify for our own discussion) any of the
+ Claudia> following:
+
+ Claudia> * how much time this is likely to take on typical current hardware?
+ Claudia> * what steps are likely to be time consuming
+ Claudia> * how any added time could affect a typical transaction, such as hitting
+ Claudia> a web site
+ Claudia> * any ways to minimize such time delays
+
+ <section title="Introduced latency">
+ </section>
+
+ <section title="Cryptographic performance">
+ </section>
+
+ <section title="Phase 1 SA performance">
+ </section>
+
+</section>
+-->
+
+<section title="Unresolved issues">
+ <section title="Control of reverse DNS">
+ <t>
+ The method of obtaining information by reverse DNS lookup causes
+ problems for people who cannot control their reverse DNS
+ bindings. This is an unresolved problem in this version, and is out
+ of scope.
+ </t>
+ </section>
+</section>
+
+<section title="Examples">
+
+<section title="Clear-text usage (permit policy)">
+
+<t>
+Two example scenarios follow. In the first example GW-A
+(Gateway A) and GW-B (Gateway B) have always-clear-text policies, and in the second example they have an OE
+policy. The clear-text policy serves as a reference for what occurs in
+TCP/IP in the absence of Opportunistic Encryption.
+
+<t>
+Alice wants to communicate with Bob. Perhaps she wants to retrieve a
+web page from Bob's web server. In the absence of opportunistic
+encryptors, the following events occur:
+</t>
+
+ <figure anchor="regulartiming" title="Timing of regular transaction">
+ <artwork><![CDATA[
+ Alice SG-A DNS SG-B Bob
+ Human or application
+ 'clicks' with a name.
+ (1)
+
+ ------(2)-------------->
+ Application looks up
+ name in DNS to get
+ IP address.
+
+ <-----(3)---------------
+ Resolver returns "A" RR
+ to application with IP
+ address.
+
+ (4)
+ Application starts a TCP session
+ or UDP session and OS sends
+ first datagram
+
+ ----(5)----->
+ Datagram is seen at first gateway
+ from Alice (SG-A).
+
+ ----------(6)------>
+ Datagram traverses
+ network.
+
+ ------(7)----->
+ Datagram arrives
+ at Bob, is provided
+ to TCP.
+
+ <------(8)------
+ A reply is sent.
+
+ <----------(9)------
+ Datagram traverses
+ network.
+ <----(10)-----
+ Alice receives
+ answer.
+
+ (11)----------->
+ A second exchange
+ occurs.
+ ----------(12)----->
+ -------------->
+ <---------------
+ <-------------------
+ <-------------
+ ]]></artwork>
+</figure>
+
+</t>
+</section>
+
+<section title="Opportunistic encryption">
+
+<t>
+In the presence of properly configured opportunistic encryptors, the
+event list is extended. Only changes are annotated.
+</t>
+
+<t>The following symbols are used in the time-sequence diagram</t>
+
+<t>
+<list style="hanging">
+ <t hangText="-"> A single dash represents clear-text datagrams.</t>
+ <t hangText="="> An equals sign represents phase 2 (IPsec) cipher-text
+ datagrams.</t>
+ <t hangText="~"> A single tilde represents clear-text phase 1 datagrams.</t>
+ <t hangText="#"> A hash sign represents phase 1 (IKE) cipher-text
+ datagrams.</t>
+</list>
+</t>
+
+<t>
+<figure anchor="opportunistictiming" title="Timing of opportunistic encryption transaction">
+ <artwork><![CDATA[
+ Alice SG-A DNS SG-B Bob
+ (1)
+ ------(2)-------------->
+ <-----(3)---------------
+ (4)----(5)----->+
+ SG-A sees datagram
+ to new target and
+ saves it as "first"
+
+ ----(5B)->
+ SG-A asks DNS
+ for TXT RR.
+
+ <---(5C)--
+ DNS returns TXT RR.
+
+ ~~~~~~~~~~~~~(5D)~~~>
+ initial IKE main mode
+ packet is sent.
+
+ <~~~~~~~~~~~~(5E1)~~~
+ ~~~~~~~~~~~~~(5E2)~~>
+ <~~~~~~~~~~~~(5E3)~~~
+ IKE phase 1 - privacy.
+
+ #############(5E4)##>
+ SG-A sends ID to SG-B
+ <----(5F1)--
+ SG-B asks DNS
+ for SG-A's public
+ KEY
+ -----(5F2)->
+ DNS provides KEY RR.
+ SG-B authenticates SG-A
+
+ <############(5E5)###
+ IKE phase 1 - complete
+
+ #############(5G1)##>
+ IKE phase 2 - Alice<->Bob
+ tunnel is proposed.
+
+ <----(5H1)--
+ SG-B asks DNS for
+ Alice's TXT record.
+ -----(5H2)->
+ DNS replies with TXT
+ record. SG-B checks
+ SG-A's authorization.
+
+ <############(5G2)###
+ SG-B accepts proposal.
+
+ #############(5G3)##>
+ SG-A confirms.
+
+ ============(6)====>
+ SG-A sends "first"
+ packet in new IPsec
+ SA.
+ ------(7)----->
+ packet is decrypted
+ and forward to Bob.
+ <------(8)------
+ <==========(9)======
+ return packet also
+ encrypted.
+ <-----(10)----
+
+ (11)----------->
+ a second packet
+ is sent by Alice
+ ==========(12)=====>
+ existing tunnel is used
+ -------------->
+ <---------------
+ <===================
+ <-------------
+ ]]></artwork>
+</figure>
+
+</t>
+
+ <t>
+ For the purposes of this section, we will describe only the changes that
+ occur between <xref target="regulartiming" /> and
+ <xref target="opportunistictiming" />. This corresponds to time points 5, 6, 7, 9 and 10 on the list above.
+ </t>
+
+<list style="symbols">
+ <t>
+ At point (5), SG-A intercepts the datagram because this source/destination pair lacks a policy
+(the non-existent policy state). SG-A creates a hold policy, and buffers the datagram. SG-A requests keys from the keying daemon.
+ </t>
+
+ <t>
+ SG-A's IKE daemon, having looked up the source/destination pair in the connection
+ class list, creates a new Potential OE connection instance. SG-A starts DNS
+ queries.
+ </t>
+ </section>
+
+ <section title="(5C) DNS returns TXT record(s)">
+
+ <t>
+ DNS returns properly formed TXT delegation records, and SG-A's IKE daemon
+ causes this instance to make a transition from Potential OE connection to Pending OE
+ connection.
+ </t>
+
+ <t>
+ Using the example above, the returned record might contain:
+
+ <figure anchor="txtexample"
+ title="Example of reverse delegation record for Bob">
+ <artwork><![CDATA[
+X-IPsec-Server(10)=192.1.1.5 AQMM...3s1Q==
+ ]]></artwork>
+ </figure>
+ with SG-B's IP address and public key listed.
+ </t>
+
+ </section>
+
+ <section title="(5D) Initial IKE main mode packet goes out">
+ <t>Upon entering Pending OE connection, SG-A sends the initial ISAKMP
+ message with proposals. See <xref target="phase1id" />.
+ </t>
+ </section>
+
+ <section title="(5E1) Message 2 of phase 1 exchange">
+ <t>
+ SG-B receives the message. A new connection instance is created in the
+ unauthenticated OE peer state.
+ </t>
+ </section>
+
+ <section title="(5E2) Message 3 of phase 1 exchange">
+ <t>
+ SG-A sends a Diffie-Hellman exponent. This is an internal state of the
+ keying daemon.
+ </t>
+ </section>
+
+ <section title="(5E3) Message 4 of phase 1 exchange">
+ <t>
+ SG-B responds with a Diffie-Hellman exponent. This is an internal state of the
+ keying protocol.
+ </t>
+ </section>
+
+ <section title="(5E4) Message 5 of phase 1 exchange">
+ <t>
+ SG-A uses the phase 1 SA to send its identity under encryption.
+ The choice of identity is discussed in <xref target="phase1id" />.
+ This is an internal state of the keying protocol.
+ </t>
+ </section>
+
+ <section title="(5F1) Responder lookup of initiator key">
+ <t>
+ SG-B asks DNS for the public key of the initiator.
+ DNS looks for a KEY record by IP address in the reverse-map.
+ That is, a KEY resource record is queried for 4.1.1.192.in-addr.arpa
+ (recall that SG-A's external address is 192.1.1.4).
+ SG-B uses the resulting public key to authenticate the initiator. See <xref
+ target="KEY" /> for further details.
+ </t>
+ </section>
+
+<section title="(5F2) DNS replies with public key of initiator">
+<t>
+Upon successfully authenticating the peer, the connection instance makes a
+transition to authenticated OE peer on SG-B.
+</t>
+<t>
+The format of the TXT record returned is described in
+<xref target="TXT" />.
+</t>
+</section>
+
+ <section title="(5E5) Responder replies with ID and authentication">
+ <t>
+ SG-B sends its ID along with authentication material. This is an internal
+ state for the keying protocol.
+ </t>
+ </section>
+
+ <section title="(5G) IKE phase 2">
+ <section title="(5G1) Initiator proposes tunnel">
+ <t>
+ Having established mutually agreeable authentications (via KEY) and
+ authorizations (via TXT), SG-A proposes to create an IPsec tunnel for
+ datagrams transiting from Alice to Bob. This tunnel is established only for
+ the Alice/Bob combination, not for any subnets that may be behind SG-A and SG-B.
+ </t>
+ </section>
+
+ <section title="(5H1) Responder determines initiator's authority">
+ <t>
+ While the identity of SG-A has been established, its authority to
+ speak for Alice has not yet been confirmed. SG-B does a reverse
+ lookup on Alice's address for a TXT record.
+ </t>
+ <t>Upon receiving this specific proposal, SG-B's connection instance
+ makes a transition into the potential OE connection state. SG-B may already have an
+ instance, and the check is made as described above.</t>
+ </section>
+
+ <section title="(5H2) DNS replies with TXT record(s)">
+ <t>
+ The returned key and IP address should match that of SG-A.
+ </t>
+ </section>
+
+ <section title="(5G2) Responder agrees to proposal">
+ <t>
+ Should additional communication occur between, for instance, Dave and Bob using
+ SG-A and SG-B, a new tunnel (phase 2 SA) would be established. The phase 1 SA
+ may be reusable.
+ </t>
+ <t>SG-A, having successfully keyed the tunnel, now makes a transition from
+ Pending OE connection to Keyed OE connection.
+ </t>
+ <t>The responder MUST setup the inbound IPsec SAs before sending its reply.</t>
+ </section>
+
+ <section title="(5G3) Final acknowledgment from initiator">
+ <t>
+ The initiator agrees with the responder's choice and sets up the tunnel.
+ The initiator sets up the inbound and outbound IPsec SAs.
+ </t>
+ <t>
+ The proper authorization returned with keys prompts SG-B to make a transition
+ to the keyed OE connection state.
+ </t>
+ <t>Upon receipt of this message, the responder may now setup the outbound
+ IPsec SAs.</t>
+ </section>
+ </section>
+
+ <section title="(6) IPsec succeeds, and sets up tunnel for communication between Alice and Bob">
+ <t>
+ SG-A sends the datagram saved at step (5) through the newly created
+ tunnel to SG-B, where it gets decrypted and forwarded.
+ Bob receives it at (7) and replies at (8).
+ </t>
+ </section>
+
+ <section title="(9) SG-B already has tunnel up with G1 and uses it">
+ <t>
+ At (9), SG-B has already established an SPD entry mapping Bob->Alice via a
+ tunnel, so this tunnel is simply applied. The datagram is encrypted to SG-A,
+ decrypted by SG-A and passed to Alice at (10).
+ </t>
+
+ </section>
+</section> <!-- OE example -->
+
+</section> <!-- Examples -->
+
+<section anchor="securityconsiderations" title="Security considerations">
+
+ <section title="Configured vs opportunistic tunnels">
+<t>
+ Configured tunnels are those which are setup using bilateral mechanisms: exchanging
+public keys (raw RSA, DSA, PKIX), pre-shared secrets, or by referencing keys that
+are in known places (distinguished name from LDAP, DNS). These keys are then used to
+configure a specific tunnel.
+</t>
+<t>
+A pre-configured tunnel may be on all the time, or may be keyed only when needed.
+The end points of the tunnel are not necessarily static: many mobile
+applications (road warrior) are considered to be configured tunnels.
+</t>
+<t>
+The primary characteristic is that configured tunnels are assigned specific
+security properties. They may be trusted in different ways relating to exceptions to
+firewall rules, exceptions to NAT processing, and to bandwidth or other quality of service restrictions.
+</t>
+<t>
+Opportunistic tunnels are not inherently trusted in any strong way. They are
+created without prior arrangement. As the two parties are strangers, there
+MUST be no confusion of datagrams that arrive from opportunistic peers and
+those that arrive from configured tunnels. A security gateway MUST take care
+that an opportunistic peer can not impersonate a configured peer.
+</t>
+<t>
+Ingress filtering MUST be used to make sure that only datagrams authorized by
+negotiation (and the concomitant authentication and authorization) are
+accepted from a tunnel. This is to prevent one peer from impersonating another.
+</t>
+<t>
+An implementation suggestion is to treat opportunistic tunnel
+datagrams as if they arrive on a logical interface distinct from other
+configured tunnels. As the number of opportunistic tunnels that may be
+created automatically on a system is potentially very high, careful attention
+to scaling should be taken into account.
+</t>
+<t>
+As with any IKE negotiation, opportunistic encryption cannot be secure
+without authentication. Opportunistic encryption relies on DNS for its
+authentication information and, therefore, cannot be fully secure without
+a secure DNS. Without secure DNS, opportunistic encryption can protect against passive
+eavesdropping but not against active man-in-the-middle attacks.
+</t>
+ </section>
+
+ <section title="Firewalls versus Opportunistic Tunnels">
+<t>
+ Typical usage of per datagram access control lists is to implement various
+kinds of security gateways. These are typically called "firewalls".
+</t>
+<t>
+ Typical usage of a virtual private network (VPN) within a firewall is to
+bypass all or part of the access controls between two networks. Additional
+trust (as outlined in the previous section) is given to datagrams that arrive
+in the VPN.
+</t>
+<t>
+ Datagrams that arrive via opportunistically configured tunnels MUST not be
+trusted. Any security policy that would apply to a datagram arriving in the
+clear SHOULD also be applied to datagrams arriving opportunistically.
+</t>
+ </section>
+
+ <section title="Denial of service">
+<t>
+ There are several different forms of denial of service that an implementor
+ should concern themselves with. Most of these problems are shared with
+ security gateways that have large numbers of mobile peers (road warriors).
+</t>
+<t>
+ The design of ISAKMP/IKE, and its use of cookies, defend against many kinds
+ of denial of service. Opportunism changes the assumption that if the phase 1 (ISAKMP)
+ SA is authenticated, that it was worthwhile creating. Because the gateway will communicate with any machine, it is
+ possible to form phase 1 SAs with any machine on the Internet.
+</t>
+
+</section>
+</section>
+
+<section title="IANA Considerations">
+<t>
+ There are no known numbers which IANA will need to manage.
+</t>
+</section>
+
+<section title="Acknowledgments">
+<t>
+ Substantive portions of this document are based upon previous work by
+ Henry Spencer.
+</t>
+<t>
+ Thanks to Tero Kivinen, Sandy Harris, Wes Hardarker, Robert Moskowitz,
+ Jakob Schlyter, Bill Sommerfeld, John Gilmore and John Denker for their
+ comments and constructive criticism.
+</t>
+<t>
+ Sandra Hoffman and Bill Dickie did the detailed proof reading and editing.
+</t>
+</section>
+
+</middle>
+
+<back>
+<references title="Normative references">
+<?rfc include="reference.OEspec" ?>
+<!-- renumber according to reference order -->
+<?rfc include="reference.RFC.0791" ?>
+<?rfc include="reference.RFC.1009" ?>
+<?rfc include="reference.RFC.1984" ?>
+<?rfc include="reference.RFC.2119" ?>
+<!-- IPsec -->
+<?rfc include="reference.RFC.2367" ?>
+<?rfc include="reference.RFC.2401" ?>
+<?rfc include="reference.RFC.2407" ?>
+<?rfc include="reference.RFC.2408" ?>
+<?rfc include="reference.RFC.2409" ?>
+<!-- MODPGROUPS -->
+<?rfc include="reference.RFC.3526" ?>
+<!-- DNSSEC -->
+<?rfc include="reference.RFC.1034" ?>
+<?rfc include="reference.RFC.1035" ?>
+<?rfc include="reference.RFC.2671" ?>
+<?rfc include="reference.RFC.1464" ?>
+<?rfc include="reference.RFC.2535" ?>
+<?rfc include="reference.RFC.3110" ?>
+<?rfc include="reference.RFC.2538" ?>
+<!-- COPS -->
+<?rfc include="reference.RFC.2748" ?>
+<!-- NAT -->
+<?rfc include="reference.RFC.2663" ?>
+</references>
+<!-- <references title="Non-normative references"> -->
+<!-- ESPUDP -->
+<!-- <?rfc include="reference.ESPUDP" ?> -->
+<!-- </references> -->
+</back>
+</rfc>
+<!--
+ $Id: draft-richardson-ipsec-opportunistic.xml,v 1.1 2004/03/15 20:35:24 as Exp $
+
+ $Log: draft-richardson-ipsec-opportunistic.xml,v $
+ Revision 1.1 2004/03/15 20:35:24 as
+ added files from freeswan-2.04-x509-1.5.3
+
+ Revision 1.33 2003/06/30 03:19:59 mcr
+ timing-diagram with inline explanation.
+
+ Revision 1.32 2003/06/30 01:57:44 mcr
+ initial edits per-Bob Braden.
+
+ Revision 1.31 2003/05/26 19:31:23 mcr
+ updates to drafts - IPSEC RR - SC versions, and RFC3526
+ reference in OE draft.
+
+ Revision 1.30 2003/05/21 15:42:34 mcr
+ updates due to publication of RFC 3526.
+
+ Revision 1.29 2003/01/17 16:22:55 mcr
+ rev 11 of OE draft.
+
+ Revision 1.28 2002/07/25 19:27:31 mcr
+ added DHR's minor edits.
+
+ Revision 1.27 2002/07/21 16:26:26 mcr
+ slides from presentation at OLS
+ draft-10 of OE draft.
+
+ Revision 1.26 2002/07/16 03:46:53 mcr
+ second edits from Sandra.
+
+ Revision 1.25 2002/07/16 03:36:14 mcr
+ removed HS from authors list
+ updated reference inclusion to use <?rfc-include directive.
+ Revision 1.24 2002/07/11 02:08:21 mcr
+ updated XML file from Sandra
+
+ Revision 1.23 2002/06/06 17:18:53 mcr
+ spellcheck.
+
+ Revision 1.22 2002/06/06 17:14:19 mcr
+ results of hand-editing session from May 28th.
+ This is FINAL OE draft.
+
+ Revision 1.21 2002/06/06 02:25:44 mcr
+ results of hand-editing session from May 28th.
+ This is FINAL OE draft.
+
+ Revision 1.20 2002/05/24 03:28:37 mcr
+ changes as requested by RFC editor.
+
+ Revision 1.19 2002/04/09 16:01:05 mcr
+ comments from PHB.
+
+ Revision 1.18 2002/04/08 02:14:34 mcr
+ RGBs changes to rev6.
+
+ Revision 1.17 2002/03/12 21:23:55 mcr
+ adjusted definition of default-free zone.
+ moved text on key rollover from format description to new
+ section.
+
+ Revision 1.16 2002/02/22 01:23:21 mcr
+ revisions from MCR (2002/2/18) and net.
+
+ Revision 1.15 2002/02/21 20:44:12 mcr
+ extensive from DHR.
+
+ Revision 1.14 2002/02/10 16:20:39 mcr
+ -05 draft. Many revisions to do "OE system in world of OE systems"
+ view of the universe.
+
+ Revision 1.13 2001/12/20 04:35:22 mcr
+ fixed reference to rfc1984.
+
+ Revision 1.12 2001/12/20 03:35:19 mcr
+ comments from Henry, Tero, and Sandy.
+
+ Revision 1.11 2001/12/19 07:26:22 mcr
+ added comment about KX records.
+
+ Revision 1.10 2001/11/09 04:28:10 mcr
+ fixed some typos with XML, and one s/SG-B/SG-D/.
+
+ Revision 1.9 2001/11/09 04:07:13 mcr
+ expanded section 10: multihoming, with an example.
+
+ Revision 1.8 2001/11/09 02:16:51 mcr
+ added lifetime/lifespan definitions.
+ moved example from 5B to 5C.
+ added reference to phase 1 IDs to 5D.
+ cleared up text in aging section.
+ added text about delegation of DNSSEC activity to a DNS server.
+ spelt out DH group names.
+ added text about ignoring TXT records unless DNSSEC is deployed (somerfeld)
+ added example of TXT delegation using FQDN.
+ clarified some text in NAT interaction section.
+ clarified absense of TXT record need for host implementation
+
+ Revision 1.7 2001/11/08 23:09:37 mcr
+ changed revision of draft to 03.
+
+ Revision 1.6 2001/11/08 19:37:14 mcr
+ fixed some formatting of Aging section.
+
+ Revision 1.5 2001/11/08 19:19:30 mcr
+ fixed address for DHR, updated address for MCR,
+ added reference to original HS/DHR OE specification paper.
+
+ Revision 1.4 2001/11/08 19:08:24 mcr
+ section 10, "Renewal and Teardown" added moved between 4/5, and
+ slightly rewritten.
+
+ Revision 1.3 2001/11/08 18:56:34 mcr
+ sections 4.2, 5.6, 5.7.1 and 6.2 edited as per HS.
+ section 10, "Renewal and Teardown" added.
+ section 11, "Failure modes" completed.
+
+ Revision 1.2 2001/11/05 20:31:31 mcr
+ added section from OE spec on aging and teardown.
+
+ Revision 1.1 2001/11/05 04:27:58 mcr
+ OE draft added to documentation.
+
+ Revision 1.12 2001/10/10 01:12:31 mcr
+ removed impact on DNS servers section.
+ removed nested comments.
+ adjusted data of issue
+
+ Revision 1.11 2001/09/17 02:55:50 mcr
+ outline is now stable.
+
+ Revision 1.5 2001/08/19 02:53:32 mcr
+ version 00d formatted.
+
+ Revision 1.10 2001/08/19 02:34:04 mcr
+ version 00d formatted.
+
+ Revision 1.9 2001/08/19 02:21:54 mcr
+ version 00d
+
+ Revision 1.8 2001/07/20 19:07:06 mcr
+ commented out section 1.1
+
+ Revision 1.7 2001/07/20 14:14:22 mcr
+ HS and HD comments.
+
+ Revision 1.6 2001/07/19 00:56:50 mcr
+ version 00b.
+
+ Revision 1.5 2001/07/12 23:57:07 mcr
+ OE ID, 00.
+
+
+!>
diff --git a/doc/src/draft-richardson-ipsec-rr.html b/doc/src/draft-richardson-ipsec-rr.html
new file mode 100644
index 000000000..08473104f
--- /dev/null
+++ b/doc/src/draft-richardson-ipsec-rr.html
@@ -0,0 +1,659 @@
+<html><head><title>A method for storing IPsec keying material in DNS.</title>
+<STYLE type='text/css'>
+ .title { color: #990000; font-size: 22px; line-height: 22px; font-weight: bold; text-align: right;
+ font-family: helvetica, arial, sans-serif }
+ .filename { color: #666666; font-size: 18px; line-height: 28px; font-weight: bold; text-align: right;
+ font-family: helvetica, arial, sans-serif }
+ p.copyright { color: #000000; font-size: 10px;
+ font-family: verdana, charcoal, helvetica, arial, sans-serif }
+ p { margin-left: 2em; margin-right: 2em; }
+ li { margin-left: 3em; }
+ ol { margin-left: 2em; margin-right: 2em; }
+ ul.text { margin-left: 2em; margin-right: 2em; }
+ pre { margin-left: 3em; color: #333333 }
+ ul.toc { color: #000000; line-height: 16px;
+ font-family: verdana, charcoal, helvetica, arial, sans-serif }
+ H3 { color: #333333; font-size: 16px; line-height: 16px; font-family: helvetica, arial, sans-serif }
+ H4 { color: #000000; font-size: 14px; font-family: helvetica, arial, sans-serif }
+ TD.header { color: #ffffff; font-size: 10px; font-family: arial, helvetica, san-serif; valign: top }
+ TD.author-text { color: #000000; font-size: 10px;
+ font-family: verdana, charcoal, helvetica, arial, sans-serif }
+ TD.author { color: #000000; font-weight: bold; margin-left: 4em; font-size: 10px; font-family: verdana, charcoal, helvetica, arial, sans-serif }
+ A:link { color: #990000; font-weight: bold;
+ font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif }
+ A:visited { color: #333333; font-weight: bold;
+ font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif }
+ A:name { color: #333333; font-weight: bold;
+ font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif }
+ .link2 { color:#ffffff; font-weight: bold; text-decoration: none;
+ font-family: monaco, charcoal, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif;
+ font-size: 9px }
+ .RFC { color:#666666; font-weight: bold; text-decoration: none;
+ font-family: monaco, charcoal, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif;
+ font-size: 9px }
+ .hotText { color:#ffffff; font-weight: normal; text-decoration: none;
+ font-family: charcoal, monaco, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif;
+ font-size: 9px }
+</style>
+</head>
+<body bgcolor="#ffffff" text="#000000" alink="#000000" vlink="#666666" link="#990000">
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<table width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table width="100%" border="0" cellpadding="2" cellspacing="1">
+<tr valign="top"><td width="33%" bgcolor="#666666" class="header">IPSECKEY WG</td><td width="33%" bgcolor="#666666" class="header">M. Richardson</td></tr>
+<tr valign="top"><td width="33%" bgcolor="#666666" class="header">Internet-Draft</td><td width="33%" bgcolor="#666666" class="header">SSW</td></tr>
+<tr valign="top"><td width="33%" bgcolor="#666666" class="header">Expires: March 4, 2004</td><td width="33%" bgcolor="#666666" class="header">September 4, 2003</td></tr>
+</table></td></tr></table>
+<div align="right"><font face="monaco, MS Sans Serif" color="#990000" size="+3"><b><br><span class="title">A method for storing IPsec keying material in DNS.</span></b></font></div>
+<div align="right"><font face="monaco, MS Sans Serif" color="#666666" size="+2"><b><span class="filename">draft-ietf-ipseckey-rr-07.txt</span></b></font></div>
+<font face="verdana, helvetica, arial, sans-serif" size="2">
+
+<h3>Status of this Memo</h3>
+<p>
+This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026.</p>
+<p>
+Internet-Drafts are working documents of the Internet Engineering
+Task Force (IETF), its areas, and its working groups.
+Note that other groups may also distribute working documents as
+Internet-Drafts.</p>
+<p>
+Internet-Drafts are draft documents valid for a maximum of six months
+and may be updated, replaced, or obsoleted by other documents at any time.
+It is inappropriate to use Internet-Drafts as reference material or to cite
+them other than as "work in progress."</p>
+<p>
+The list of current Internet-Drafts can be accessed at
+<a href='http://www.ietf.org/ietf/1id-abstracts.txt'>http://www.ietf.org/ietf/1id-abstracts.txt</a>.</p>
+<p>
+The list of Internet-Draft Shadow Directories can be accessed at
+<a href='http://www.ietf.org/shadow.html'>http://www.ietf.org/shadow.html</a>.</p>
+<p>
+This Internet-Draft will expire on March 4, 2004.</p>
+
+<h3>Copyright Notice</h3>
+<p>
+Copyright (C) The Internet Society (2003). All Rights Reserved.</p>
+
+<h3>Abstract</h3>
+
+<p>
+This document describes a new resource record for DNS. This record may be
+used to store public keys for use in IPsec systems.
+
+</p>
+<p>
+This record replaces the functionality of the sub-type #1 of the KEY Resource
+Record, which has been obsoleted by RFC3445.
+
+</p><a name="toc"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<h3>Table of Contents</h3>
+<ul compact class="toc">
+<b><a href="#anchor1">1.</a>&nbsp;
+Introduction<br></b>
+<b><a href="#anchor2">1.1</a>&nbsp;
+Overview<br></b>
+<b><a href="#anchor3">1.2</a>&nbsp;
+Usage Criteria<br></b>
+<b><a href="#anchor4">2.</a>&nbsp;
+Storage formats<br></b>
+<b><a href="#anchor5">2.1</a>&nbsp;
+IPSECKEY RDATA format<br></b>
+<b><a href="#anchor6">2.2</a>&nbsp;
+RDATA format - precedence<br></b>
+<b><a href="#algotype">2.3</a>&nbsp;
+RDATA format - algorithm type<br></b>
+<b><a href="#gatewaytype">2.4</a>&nbsp;
+RDATA format - gateway type<br></b>
+<b><a href="#anchor7">2.5</a>&nbsp;
+RDATA format - gateway<br></b>
+<b><a href="#anchor8">2.6</a>&nbsp;
+RDATA format - public keys<br></b>
+<b><a href="#anchor9">3.</a>&nbsp;
+Presentation formats<br></b>
+<b><a href="#anchor10">3.1</a>&nbsp;
+Representation of IPSECKEY RRs<br></b>
+<b><a href="#anchor11">3.2</a>&nbsp;
+Examples<br></b>
+<b><a href="#anchor12">4.</a>&nbsp;
+Security Considerations<br></b>
+<b><a href="#anchor13">4.1</a>&nbsp;
+Active attacks against unsecured IPSECKEY resource records<br></b>
+<b><a href="#anchor14">5.</a>&nbsp;
+IANA Considerations<br></b>
+<b><a href="#anchor15">6.</a>&nbsp;
+Acknowledgments<br></b>
+<b><a href="#rfc.references1">&#167;</a>&nbsp;
+Normative references<br></b>
+<b><a href="#rfc.references2">&#167;</a>&nbsp;
+Non-normative references<br></b>
+<b><a href="#rfc.authors">&#167;</a>&nbsp;
+Author's Address<br></b>
+<b><a href="#rfc.copyright">&#167;</a>&nbsp;
+Full Copyright Statement<br></b>
+</ul>
+<br clear="all">
+
+<a name="anchor1"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.1"></a><h3>1.&nbsp;Introduction</h3>
+
+<p>
+ The type number for the IPSECKEY RR is TBD.
+
+</p>
+<a name="rfc.section.1.1"></a><h4><a name="anchor2">1.1</a>&nbsp;Overview</h4>
+
+<p>
+ The IPSECKEY resource record (RR) is used to publish a public key that is
+ to be associated with a Domain Name System (DNS) name for use with the
+ IPsec protocol suite. This can be the public key of a host,
+ network, or application (in the case of per-port keying).
+
+</p>
+<p>
+ 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
+ RFC2119 <a href="#RFC2119">[8]</a>.
+
+</p>
+<a name="rfc.section.1.2"></a><h4><a name="anchor3">1.2</a>&nbsp;Usage Criteria</h4>
+
+<p>
+ An IPSECKEY resource record SHOULD be used in combination with DNSSEC
+unless some other means of authenticating the IPSECKEY resource record
+is available.
+
+</p>
+<p>
+ It is expected that there will often be multiple IPSECKEY resource
+ records at the same name. This will be due to the presence
+ of multiple gateways and the need to rollover keys.
+
+
+</p>
+<p>
+ This resource record is class independent.
+
+</p>
+<a name="anchor4"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.2"></a><h3>2.&nbsp;Storage formats</h3>
+
+<a name="rfc.section.2.1"></a><h4><a name="anchor5">2.1</a>&nbsp;IPSECKEY RDATA format</h4>
+
+<p>
+ The RDATA for an IPSECKEY RR consists of a precedence value, a public key,
+ algorithm type, and an optional gateway address.
+
+</p></font><pre>
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | precedence | gateway type | algorithm | gateway |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------+ +
+ ~ gateway ~
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | /
+ / public key /
+ / /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
+</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+
+<a name="rfc.section.2.2"></a><h4><a name="anchor6">2.2</a>&nbsp;RDATA format - precedence</h4>
+
+<p>
+This is an 8-bit precedence for this record. This is interpreted in
+the same way as the PREFERENCE field described in section
+3.3.9 of RFC1035 <a href="#RFC1035">[2]</a>.
+
+</p>
+<p>
+Gateways listed in IPSECKEY records with lower precedence are
+to be attempted first. Where there is a tie in precedence, the order
+should be non-deterministic.
+
+</p>
+<a name="rfc.section.2.3"></a><h4><a name="algotype">2.3</a>&nbsp;RDATA format - algorithm type</h4>
+
+<p>
+The algorithm type field identifies the public key's cryptographic
+algorithm and determines the format of the public key field.
+
+</p>
+<p>
+A value of 0 indicates that no key is present.
+
+</p>
+<p>
+The following values are defined:
+
+<blockquote class="text"><dl>
+<dt>1</dt>
+<dd>A DSA key is present, in the format defined in RFC2536 <a href="#RFC2536">[11]</a>
+</dd>
+<dt>2</dt>
+<dd>A RSA key is present, in the format defined in RFC3110 <a href="#RFC3110">[12]</a>
+</dd>
+</dl></blockquote><p>
+</p>
+<a name="rfc.section.2.4"></a><h4><a name="gatewaytype">2.4</a>&nbsp;RDATA format - gateway type</h4>
+
+<p>
+The gateway type field indicates the format of the information that
+is stored in the gateway field.
+
+</p>
+<p>
+The following values are defined:
+
+<blockquote class="text"><dl>
+<dt>0</dt>
+<dd>No gateway is present
+</dd>
+<dt>1</dt>
+<dd>A 4-byte IPv4 address is present
+</dd>
+<dt>2</dt>
+<dd>A 16-byte IPv6 address is present
+</dd>
+<dt>3</dt>
+<dd>A wire-encoded domain name is present. The wire-encoded
+format is self-describing, so the length is implicit. The domain name
+MUST NOT be compressed.
+</dd>
+</dl></blockquote><p>
+</p>
+<a name="rfc.section.2.5"></a><h4><a name="anchor7">2.5</a>&nbsp;RDATA format - gateway</h4>
+
+<p>
+The gateway field indicates a gateway to which an IPsec tunnel may be
+created in order to reach the entity named by this resource record.
+
+</p>
+<p>
+There are three formats:
+
+</p>
+<p>
+A 32-bit IPv4 address is present in the gateway field. The data
+portion is an IPv4 address as described in section 3.4.1 of
+<a href="#RFC1035">RFC1035</a>[2]. This is a 32-bit number in network byte order.
+
+</p>
+<p>A 128-bit IPv6 address is present in the gateway field.
+The data portion is an IPv6 address as described in section 2.2 of
+<a href="#RFC1886">RFC1886</a>[7]. This is a 128-bit number in network byte order.
+
+</p>
+<p>
+The gateway field is a normal wire-encoded domain name, as described
+in section 3.3 of RFC1035 <a href="#RFC1035">[2]</a>. Compression MUST NOT be used.
+
+</p>
+<a name="rfc.section.2.6"></a><h4><a name="anchor8">2.6</a>&nbsp;RDATA format - public keys</h4>
+
+<p>
+Both of the public key types defined in this document (RSA and DSA)
+inherit their public key formats from the corresponding KEY RR formats.
+Specifically, the public key field contains the algorithm-specific
+portion of the KEY RR RDATA, which is all of the KEY RR DATA after the
+first four octets. This is the same portion of the KEY RR that must be
+specified by documents that define a DNSSEC algorithm.
+Those documents also specify a message digest to be used for generation
+of SIG RRs; that specification is not relevant for IPSECKEY RR.
+
+</p>
+<p>
+Future algorithms, if they are to be used by both DNSSEC (in the KEY
+RR) and IPSECKEY, are likely to use the same public key encodings in
+both records. Unless otherwise specified, the IPSECKEY public key
+field will contain the algorithm-specific portion of the KEY RR RDATA
+for the corresponding algorithm. The algorithm must still be
+designated for use by IPSECKEY, and an IPSECKEY algorithm type number
+(which might be different than the DNSSEC algorithm number) must be
+assigned to it.
+
+</p>
+<p>The DSA key format is defined in RFC2536 <a href="#RFC2536">[11]</a>
+</p>
+<p>The RSA key format is defined in RFC3110 <a href="#RFC3110">[12]</a>,
+with the following changes:
+</p>
+<p>
+The earlier definition of RSA/MD5 in RFC2065 limited the exponent and
+modulus to 2552 bits in length. RFC3110 extended that limit to 4096
+bits for RSA/SHA1 keys. The IPSECKEY RR imposes no length limit on
+RSA public keys, other than the 65535 octet limit imposed by the
+two-octet length encoding. This length extension is applicable only
+to IPSECKEY and not to KEY RRs.
+
+</p>
+<a name="anchor9"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.3"></a><h3>3.&nbsp;Presentation formats</h3>
+
+<a name="rfc.section.3.1"></a><h4><a name="anchor10">3.1</a>&nbsp;Representation of IPSECKEY RRs</h4>
+
+<p>
+ IPSECKEY RRs may appear in a zone data master file.
+ The precedence, gateway type and algorithm and gateway fields are REQUIRED.
+ The base64 encoded public key block is OPTIONAL; if not present,
+ then the public key field of the resource record MUST be construed
+ as being zero octets in length.
+
+</p>
+<p>
+ The algorithm field is an unsigned integer. No mnemonics are defined.
+
+</p>
+<p>
+ If no gateway is to be indicated, then the gateway type field MUST
+ be zero, and the gateway field MUST be "."
+
+</p>
+<p>
+ The Public Key field is represented as a Base64 encoding of the
+ Public Key. Whitespace is allowed within the Base64 text. For a
+ definition of Base64 encoding, see
+<a href="#RFC1521">RFC1521</a>[3] Section 5.2.
+
+</p>
+<p>
+ The general presentation for the record as as follows:
+</p>
+</font><pre>
+IN IPSECKEY ( precedence gateway-type algorithm
+ gateway base64-encoded-public-key )
+</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<p>
+
+</p>
+<a name="rfc.section.3.2"></a><h4><a name="anchor11">3.2</a>&nbsp;Examples</h4>
+
+<p>
+An example of a node 192.0.2.38 that will accept IPsec tunnels on its
+own behalf.
+</p>
+</font><pre>
+38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2
+ 192.0.2.38
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<p>
+
+</p>
+<p>
+An example of a node, 192.0.2.38 that has published its key only.
+</p>
+</font><pre>
+38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 0 2
+ .
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<p>
+
+</p>
+<p>
+An example of a node, 192.0.2.38 that has delegated authority to the node
+192.0.2.3.
+</p>
+</font><pre>
+38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2
+ 192.0.2.3
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<p>
+
+</p>
+<p>
+An example of a node, 192.0.1.38 that has delegated authority to the node
+with the identity "mygateway.example.com".
+</p>
+</font><pre>
+38.1.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 3 2
+ mygateway.example.com.
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<p>
+
+</p>
+<p>
+An example of a node, 2001:0DB8:0200:1:210:f3ff:fe03:4d0 that has
+delegated authority to the node 2001:0DB8:c000:0200:2::1
+</p>
+</font><pre>
+$ORIGIN 1.0.0.0.0.0.2.8.B.D.0.1.0.0.2.ip6.int.
+0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0 7200 IN IPSECKEY ( 10 2 2
+ 2001:0DB8:0:8002::2000:1
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
+<p>
+
+</p>
+<a name="anchor12"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.4"></a><h3>4.&nbsp;Security Considerations</h3>
+
+<p>
+ This entire memo pertains to the provision of public keying material
+ for use by key management protocols such as ISAKMP/IKE (RFC2407)
+ <a href="#RFC2407">[9]</a>.
+
+</p>
+<p>
+The IPSECKEY resource record contains information that SHOULD be
+communicated to the end client in an integral fashion - i.e. free from
+modification. The form of this channel is up to the consumer of the
+data - there must be a trust relationship between the end consumer of this
+resource record and the server. This relationship may be end-to-end
+DNSSEC validation, a TSIG or SIG(0) channel to another secure source,
+a secure local channel on the host, or some combination of the above.
+
+</p>
+<p>
+The keying material provided by the IPSECKEY resource record is not
+sensitive to passive attacks. The keying material may be freely
+disclosed to any party without any impact on the security properties
+of the resulting IPsec session: IPsec and IKE provide for defense
+against both active and passive attacks.
+
+</p>
+<p>
+ Any user of this resource record MUST carefully document their trust
+ model, and why the trust model of DNSSEC is appropriate, if that is
+ the secure channel used.
+
+</p>
+<a name="rfc.section.4.1"></a><h4><a name="anchor13">4.1</a>&nbsp;Active attacks against unsecured IPSECKEY resource records</h4>
+
+<p>
+This section deals with active attacks against the DNS. These attacks
+require that DNS requests and responses be intercepted and changed.
+DNSSEC is designed to defend against attacks of this kind.
+
+</p>
+<p>
+The first kind of active attack is when the attacker replaces the
+keying material with either a key under its control or with garbage.
+
+</p>
+<p>
+If the attacker is not able to mount a subsequent
+man-in-the-middle attack on the IKE negotiation after replacing the
+public key, then this will result in a denial of service, as the
+authenticator used by IKE would fail.
+
+</p>
+<p>
+If the attacker is able to both to mount active attacks against DNS
+and is also in a position to perform a man-in-the-middle attack on IKE and
+IPsec negotiations, then the attacker will be in a position to compromise
+the resulting IPsec channel. Note that an attacker must be able to
+perform active DNS attacks on both sides of the IKE negotiation in
+order for this to succeed.
+
+</p>
+<p>
+The second kind of active attack is one in which the attacker replaces
+the the gateway address to point to a node under the attacker's
+control. The attacker can then either replace the public key or remove
+it, thus providing an IPSECKEY record of its own to match the
+gateway address.
+
+</p>
+<p>
+This later form creates a simple man-in-the-middle since the attacker
+can then create a second tunnel to the real destination. Note that, as before,
+this requires that the attacker also mount an active attack against
+the responder.
+
+</p>
+<p>
+Note that the man-in-the-middle can not just forward cleartext
+packets to the original destination. While the destination may be
+willing to speak in the clear, replying to the original sender,
+the sender will have already created a policy expecting ciphertext.
+Thus, the attacker will need to intercept traffic from both sides. In some
+cases, the attacker may be able to accomplish the full intercept by use
+of Network Addresss/Port Translation (NAT/NAPT) technology.
+
+</p>
+<p>
+Note that the danger here only applies to cases where the gateway
+field of the IPSECKEY RR indicates a different entity than the owner
+name of the IPSECKEY RR. In cases where the end-to-end integrity of
+the IPSECKEY RR is suspect, the end client MUST restrict its use
+of the IPSECKEY RR to cases where the RR owner name matches the
+content of the gateway field.
+
+</p>
+<a name="anchor14"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.5"></a><h3>5.&nbsp;IANA Considerations</h3>
+
+<p>
+This document updates the IANA Registry for DNS Resource Record Types
+by assigning type X to the IPSECKEY record.
+
+</p>
+<p>
+This document creates an IANA registry for the algorithm type field.
+
+</p>
+<p>
+Values 0, 1 and 2 are defined in <a href="#algotype">RDATA format - algorithm type</a>. Algorithm numbers
+3 through 255 can be assigned by IETF Consensus (<a href="#RFC2434">see RFC2434</a>[6]).
+
+</p>
+<p>
+This document creates an IANA registry for the gateway type field.
+
+</p>
+<p>
+Values 0, 1, 2 and 3 are defined in <a href="#gatewaytype">RDATA format - gateway type</a>.
+Algorithm numbers 4 through 255 can be assigned by
+Standards Action (<a href="#RFC2434">see RFC2434</a>[6]).
+
+</p>
+<a name="anchor15"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<a name="rfc.section.6"></a><h3>6.&nbsp;Acknowledgments</h3>
+
+<p>
+My thanks to Paul Hoffman, Sam Weiler, Jean-Jacques Puig, Rob Austein,
+and Olafur Gurmundsson who reviewed this document carefully.
+Additional thanks to Olafur Gurmundsson for a reference implementation.
+
+</p>
+<a name="rfc.references1"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<h3>Normative references</h3>
+<table width="99%" border="0">
+<tr><td class="author-text" valign="top"><b><a name="RFC1034">[1]</a></b></td>
+<td class="author-text">Mockapetris, P., "<a href="ftp://ftp.isi.edu/in-notes/rfc1034.txt">Domain names - concepts and facilities</a>", STD 13, RFC 1034, November 1987.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC1035">[2]</a></b></td>
+<td class="author-text"><a href="mailto:">Mockapetris, P.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1035.txt">Domain names - implementation and specification</a>", STD 13, RFC 1035, November 1987.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC1521">[3]</a></b></td>
+<td class="author-text"><a href="mailto:nsb@bellcore.com">Borenstein, N.</a> and <a href="mailto:">N. Freed</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1521.txt">MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies</a>", RFC 1521, September 1993.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2026">[4]</a></b></td>
+<td class="author-text"><a href="mailto:sob@harvard.edu">Bradner, S.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2026.txt">The Internet Standards Process -- Revision 3</a>", BCP 9, RFC 2026, October 1996.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2065">[5]</a></b></td>
+<td class="author-text"><a href="mailto:dee@cybercash.com">Eastlake, D.</a> and <a href="mailto:charlie_kaufman@iris.com">C. Kaufman</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2065.txt">Domain Name System Security Extensions</a>", RFC 2065, January 1997.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2434">[6]</a></b></td>
+<td class="author-text"><a href="mailto:narten@raleigh.ibm.com">Narten, T.</a> and <a href="mailto:Harald@Alvestrand.no">H. Alvestrand</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2434.txt">Guidelines for Writing an IANA Considerations Section in RFCs</a>", BCP 26, RFC 2434, October 1998.</td></tr>
+</table>
+
+<a name="rfc.references2"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<h3>Non-normative references</h3>
+<table width="99%" border="0">
+<tr><td class="author-text" valign="top"><b><a name="RFC1886">[7]</a></b></td>
+<td class="author-text"><a href="mailto:set@thumper.bellcore.com">Thomson, S.</a> and <a href="mailto:Christian.Huitema@MIRSA.INRIA.FR">C. Huitema</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc1886.txt">DNS Extensions to support IP version 6</a>", RFC 1886, December 1995.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2119">[8]</a></b></td>
+<td class="author-text"><a href="mailto:-">Bradner, S.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2119.txt">Key words for use in RFCs to Indicate Requirement Levels</a>", BCP 14, RFC 2119, March 1997.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2407">[9]</a></b></td>
+<td class="author-text"><a href="mailto:ddp@network-alchemy.com">Piper, D.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2407.txt">The Internet IP Security Domain of Interpretation for ISAKMP</a>", RFC 2407, November 1998.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2535">[10]</a></b></td>
+<td class="author-text"><a href="mailto:dee3@us.ibm.com">Eastlake, D.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2535.txt">Domain Name System Security Extensions</a>", RFC 2535, March 1999.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC2536">[11]</a></b></td>
+<td class="author-text"><a href="mailto:dee3@us.ibm.com">Eastlake, D.</a>, "<a href="ftp://ftp.isi.edu/in-notes/rfc2536.txt">DSA KEYs and SIGs in the Domain Name System (DNS)</a>", RFC 2536, March 1999.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC3110">[12]</a></b></td>
+<td class="author-text">Eastlake, D., "<a href="ftp://ftp.isi.edu/in-notes/rfc3110.txt">RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)</a>", RFC 3110, May 2001.</td></tr>
+<tr><td class="author-text" valign="top"><b><a name="RFC3445">[13]</a></b></td>
+<td class="author-text">Massey, D. and S. Rose, "<a href="ftp://ftp.isi.edu/in-notes/rfc3445.txt">Limiting the Scope of the KEY Resource Record (RR)</a>", RFC 3445, December 2002.</td></tr>
+</table>
+
+<a name="rfc.authors"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<h3>Author's Address</h3>
+<table width="99%" border="0" cellpadding="0" cellspacing="0">
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">Michael C. Richardson</td></tr>
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">Sandelman Software Works</td></tr>
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">470 Dawson Avenue</td></tr>
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">Ottawa, ON K1Z 5V7</td></tr>
+<tr><td class="author-text">&nbsp;</td>
+<td class="author-text">CA</td></tr>
+<tr><td class="author" align="right">EMail:&nbsp;</td>
+<td class="author-text"><a href="mailto:mcr@sandelman.ottawa.on.ca">mcr@sandelman.ottawa.on.ca</a></td></tr>
+<tr><td class="author" align="right">URI:&nbsp;</td>
+<td class="author-text"><a href="http://www.sandelman.ottawa.on.ca/">http://www.sandelman.ottawa.on.ca/</a></td></tr>
+</table>
+<a name="rfc.copyright"><br><hr size="1" shade="0"></a>
+<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
+<h3>Full Copyright Statement</h3>
+<p class='copyright'>
+Copyright (C) The Internet Society (2003). All Rights Reserved.</p>
+<p class='copyright'>
+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.</p>
+<p class='copyright'>
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.</p>
+<p class='copyright'>
+This document and the information contained herein is provided on an
+&quot;AS IS&quot; 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.</p>
+<h3>Acknowledgement</h3>
+<p class='copyright'>
+Funding for the RFC Editor function is currently provided by the
+Internet Society.</p>
+</font></body></html>
diff --git a/doc/src/draft-richardson-ipsec-rr.xml b/doc/src/draft-richardson-ipsec-rr.xml
new file mode 100644
index 000000000..e51b32615
--- /dev/null
+++ b/doc/src/draft-richardson-ipsec-rr.xml
@@ -0,0 +1,560 @@
+<?xml version="1.0"?>
+<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
+<?rfc toc="yes"?>
+
+<rfc ipr="full2026" docName="draft-ietf-ipseckey-rr-07.txt">
+
+<front>
+ <area>Security</area>
+ <workgroup>IPSECKEY WG</workgroup>
+ <title abbrev="ipsecrr">
+ A method for storing IPsec keying material in DNS.
+ </title>
+
+ <author initials="M." surname="Richardson" fullname="Michael C. Richardson">
+ <organization abbrev="SSW">Sandelman Software Works</organization>
+ <address>
+ <postal>
+ <street>470 Dawson Avenue</street>
+ <city>Ottawa</city>
+ <region>ON</region>
+ <code>K1Z 5V7</code>
+ <country>CA</country>
+ </postal>
+ <email>mcr@sandelman.ottawa.on.ca</email>
+ <uri>http://www.sandelman.ottawa.on.ca/</uri>
+ </address>
+ </author>
+
+ <date month="September" year="2003" />
+
+<abstract>
+ <t>
+This document describes a new resource record for DNS. This record may be
+used to store public keys for use in IPsec systems.
+</t>
+
+<t>
+This record replaces the functionality of the sub-type #1 of the KEY Resource
+Record, which has been obsoleted by RFC3445.
+</t>
+</abstract>
+
+</front>
+
+<middle>
+
+<section title="Introduction">
+<t>
+ The type number for the IPSECKEY RR is TBD.
+</t>
+
+<section title="Overview">
+<t>
+ The IPSECKEY resource record (RR) is used to publish a public key that is
+ to be associated with a Domain Name System (DNS) name for use with the
+ IPsec protocol suite. This can be the public key of a host,
+ network, or application (in the case of per-port keying).
+</t>
+
+<t>
+ 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
+ RFC2119 <xref target="RFC2119" />.
+</t>
+</section>
+
+<section title="Usage Criteria">
+<t>
+ An IPSECKEY resource record SHOULD be used in combination with DNSSEC
+unless some other means of authenticating the IPSECKEY resource record
+is available.
+</t>
+
+<t>
+ It is expected that there will often be multiple IPSECKEY resource
+ records at the same name. This will be due to the presence
+ of multiple gateways and the need to rollover keys.
+
+</t>
+
+<t>
+ This resource record is class independent.
+</t>
+</section>
+</section>
+
+<section title="Storage formats">
+
+<section title="IPSECKEY RDATA format">
+
+<t>
+ The RDATA for an IPSECKEY RR consists of a precedence value, a public key,
+ algorithm type, and an optional gateway address.
+</t>
+
+<artwork><![CDATA[
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | precedence | gateway type | algorithm | gateway |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------+ +
+ ~ gateway ~
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | /
+ / public key /
+ / /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
+]]></artwork>
+</section>
+
+<section title="RDATA format - precedence">
+<t>
+This is an 8-bit precedence for this record. This is interpreted in
+the same way as the PREFERENCE field described in section
+3.3.9 of RFC1035 <xref target="RFC1035" />.
+</t>
+<t>
+Gateways listed in IPSECKEY records with lower precedence are
+to be attempted first. Where there is a tie in precedence, the order
+should be non-deterministic.
+</t>
+</section>
+
+<section anchor="algotype" title="RDATA format - algorithm type">
+<t>
+The algorithm type field identifies the public key's cryptographic
+algorithm and determines the format of the public key field.
+</t>
+
+<t>
+A value of 0 indicates that no key is present.
+</t>
+
+<t>
+The following values are defined:
+ <list style="hanging">
+ <t hangText="1">A DSA key is present, in the format defined in RFC2536 <xref target="RFC2536" /></t>
+ <t hangText="2">A RSA key is present, in the format defined in RFC3110 <xref target="RFC3110" /></t>
+ </list>
+</t>
+
+</section>
+
+<section anchor="gatewaytype" title="RDATA format - gateway type">
+<t>
+The gateway type field indicates the format of the information that
+is stored in the gateway field.
+</t>
+
+<t>
+The following values are defined:
+ <list style="hanging">
+ <t hangText="0">No gateway is present</t>
+ <t hangText="1">A 4-byte IPv4 address is present</t>
+ <t hangText="2">A 16-byte IPv6 address is present</t>
+ <t hangText="3">A wire-encoded domain name is present. The wire-encoded
+format is self-describing, so the length is implicit. The domain name
+MUST NOT be compressed.</t>
+ </list>
+</t>
+
+</section>
+
+<section title="RDATA format - gateway">
+<t>
+The gateway field indicates a gateway to which an IPsec tunnel may be
+created in order to reach the entity named by this resource record.
+</t>
+<t>
+There are three formats:
+</t>
+
+<t>
+A 32-bit IPv4 address is present in the gateway field. The data
+portion is an IPv4 address as described in section 3.4.1 of
+<xref target="RFC1035">RFC1035</xref>. This is a 32-bit number in network byte order.
+</t>
+
+<t>A 128-bit IPv6 address is present in the gateway field.
+The data portion is an IPv6 address as described in section 2.2 of
+<xref target="RFC1886">RFC1886</xref>. This is a 128-bit number in network byte order.
+</t>
+
+<t>
+The gateway field is a normal wire-encoded domain name, as described
+in section 3.3 of RFC1035 <xref target="RFC1035" />. Compression MUST NOT be used.
+</t>
+
+</section>
+
+<section title="RDATA format - public keys">
+<t>
+Both of the public key types defined in this document (RSA and DSA)
+inherit their public key formats from the corresponding KEY RR formats.
+Specifically, the public key field contains the algorithm-specific
+portion of the KEY RR RDATA, which is all of the KEY RR DATA after the
+first four octets. This is the same portion of the KEY RR that must be
+specified by documents that define a DNSSEC algorithm.
+Those documents also specify a message digest to be used for generation
+of SIG RRs; that specification is not relevant for IPSECKEY RR.
+</t>
+
+<t>
+Future algorithms, if they are to be used by both DNSSEC (in the KEY
+RR) and IPSECKEY, are likely to use the same public key encodings in
+both records. Unless otherwise specified, the IPSECKEY public key
+field will contain the algorithm-specific portion of the KEY RR RDATA
+for the corresponding algorithm. The algorithm must still be
+designated for use by IPSECKEY, and an IPSECKEY algorithm type number
+(which might be different than the DNSSEC algorithm number) must be
+assigned to it.
+</t>
+
+<t>The DSA key format is defined in RFC2536 <xref target="RFC2536" /></t>.
+
+<t>The RSA key format is defined in RFC3110 <xref target="RFC3110" />,
+with the following changes:</t>
+
+<t>
+The earlier definition of RSA/MD5 in RFC2065 limited the exponent and
+modulus to 2552 bits in length. RFC3110 extended that limit to 4096
+bits for RSA/SHA1 keys. The IPSECKEY RR imposes no length limit on
+RSA public keys, other than the 65535 octet limit imposed by the
+two-octet length encoding. This length extension is applicable only
+to IPSECKEY and not to KEY RRs.
+</t>
+
+</section>
+
+</section>
+
+
+
+<section title="Presentation formats">
+
+<section title="Representation of IPSECKEY RRs">
+<t>
+ IPSECKEY RRs may appear in a zone data master file.
+ The precedence, gateway type and algorithm and gateway fields are REQUIRED.
+ The base64 encoded public key block is OPTIONAL; if not present,
+ then the public key field of the resource record MUST be construed
+ as being zero octets in length.
+</t>
+<t>
+ The algorithm field is an unsigned integer. No mnemonics are defined.
+</t>
+<t>
+ If no gateway is to be indicated, then the gateway type field MUST
+ be zero, and the gateway field MUST be "."
+</t>
+
+<t>
+ The Public Key field is represented as a Base64 encoding of the
+ Public Key. Whitespace is allowed within the Base64 text. For a
+ definition of Base64 encoding, see
+<xref target="RFC1521">RFC1521</xref> Section 5.2.
+</t>
+
+
+<t>
+ The general presentation for the record as as follows:
+<artwork><![CDATA[
+IN IPSECKEY ( precedence gateway-type algorithm
+ gateway base64-encoded-public-key )
+]]></artwork>
+</t>
+</section>
+
+
+<section title="Examples">
+<t>
+An example of a node 192.0.2.38 that will accept IPsec tunnels on its
+own behalf.
+<artwork><![CDATA[
+38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2
+ 192.0.2.38
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+]]></artwork>
+</t>
+
+<t>
+An example of a node, 192.0.2.38 that has published its key only.
+<artwork><![CDATA[
+38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 0 2
+ .
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+]]></artwork>
+</t>
+
+<t>
+An example of a node, 192.0.2.38 that has delegated authority to the node
+192.0.2.3.
+<artwork><![CDATA[
+38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2
+ 192.0.2.3
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+]]></artwork>
+</t>
+
+<t>
+An example of a node, 192.0.1.38 that has delegated authority to the node
+with the identity "mygateway.example.com".
+<artwork><![CDATA[
+38.1.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 3 2
+ mygateway.example.com.
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+]]></artwork>
+</t>
+
+<t>
+An example of a node, 2001:0DB8:0200:1:210:f3ff:fe03:4d0 that has
+delegated authority to the node 2001:0DB8:c000:0200:2::1
+<artwork><![CDATA[
+$ORIGIN 1.0.0.0.0.0.2.8.B.D.0.1.0.0.2.ip6.int.
+0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0 7200 IN IPSECKEY ( 10 2 2
+ 2001:0DB8:0:8002::2000:1
+ AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )
+]]></artwork>
+</t>
+
+</section>
+</section>
+
+<section title="Security Considerations">
+<t>
+ This entire memo pertains to the provision of public keying material
+ for use by key management protocols such as ISAKMP/IKE (RFC2407)
+ <xref target="RFC2407" />.
+</t>
+
+<t>
+The IPSECKEY resource record contains information that SHOULD be
+communicated to the end client in an integral fashion - i.e. free from
+modification. The form of this channel is up to the consumer of the
+data - there must be a trust relationship between the end consumer of this
+resource record and the server. This relationship may be end-to-end
+DNSSEC validation, a TSIG or SIG(0) channel to another secure source,
+a secure local channel on the host, or some combination of the above.
+</t>
+
+<t>
+The keying material provided by the IPSECKEY resource record is not
+sensitive to passive attacks. The keying material may be freely
+disclosed to any party without any impact on the security properties
+of the resulting IPsec session: IPsec and IKE provide for defense
+against both active and passive attacks.
+</t>
+
+<t>
+ Any user of this resource record MUST carefully document their trust
+ model, and why the trust model of DNSSEC is appropriate, if that is
+ the secure channel used.
+</t>
+
+<section title="Active attacks against unsecured IPSECKEY resource records">
+<t>
+This section deals with active attacks against the DNS. These attacks
+require that DNS requests and responses be intercepted and changed.
+DNSSEC is designed to defend against attacks of this kind.
+</t>
+
+<t>
+The first kind of active attack is when the attacker replaces the
+keying material with either a key under its control or with garbage.
+</t>
+
+<t>
+If the attacker is not able to mount a subsequent
+man-in-the-middle attack on the IKE negotiation after replacing the
+public key, then this will result in a denial of service, as the
+authenticator used by IKE would fail.
+</t>
+
+<t>
+If the attacker is able to both to mount active attacks against DNS
+and is also in a position to perform a man-in-the-middle attack on IKE and
+IPsec negotiations, then the attacker will be in a position to compromise
+the resulting IPsec channel. Note that an attacker must be able to
+perform active DNS attacks on both sides of the IKE negotiation in
+order for this to succeed.
+</t>
+
+<t>
+The second kind of active attack is one in which the attacker replaces
+the the gateway address to point to a node under the attacker's
+control. The attacker can then either replace the public key or remove
+it, thus providing an IPSECKEY record of its own to match the
+gateway address.
+</t>
+
+<t>
+This later form creates a simple man-in-the-middle since the attacker
+can then create a second tunnel to the real destination. Note that, as before,
+this requires that the attacker also mount an active attack against
+the responder.
+</t>
+
+<t>
+Note that the man-in-the-middle can not just forward cleartext
+packets to the original destination. While the destination may be
+willing to speak in the clear, replying to the original sender,
+the sender will have already created a policy expecting ciphertext.
+Thus, the attacker will need to intercept traffic from both sides. In some
+cases, the attacker may be able to accomplish the full intercept by use
+of Network Addresss/Port Translation (NAT/NAPT) technology.
+</t>
+
+<t>
+Note that the danger here only applies to cases where the gateway
+field of the IPSECKEY RR indicates a different entity than the owner
+name of the IPSECKEY RR. In cases where the end-to-end integrity of
+the IPSECKEY RR is suspect, the end client MUST restrict its use
+of the IPSECKEY RR to cases where the RR owner name matches the
+content of the gateway field.
+</t>
+</section>
+
+</section>
+
+<section title="IANA Considerations">
+<t>
+This document updates the IANA Registry for DNS Resource Record Types
+by assigning type X to the IPSECKEY record.
+</t>
+
+<t>
+This document creates an IANA registry for the algorithm type field.
+</t>
+<t>
+Values 0, 1 and 2 are defined in <xref target="algotype" />. Algorithm numbers
+3 through 255 can be assigned by IETF Consensus (<xref target="RFC2434">see RFC2434</xref>).
+</t>
+
+<t>
+This document creates an IANA registry for the gateway type field.
+</t>
+<t>
+Values 0, 1, 2 and 3 are defined in <xref target="gatewaytype" />.
+Algorithm numbers 4 through 255 can be assigned by
+Standards Action (<xref target="RFC2434">see RFC2434</xref>).
+</t>
+
+
+
+</section>
+
+<section title="Acknowledgments">
+<t>
+My thanks to Paul Hoffman, Sam Weiler, Jean-Jacques Puig, Rob Austein,
+and Olafur Gurmundsson who reviewed this document carefully.
+Additional thanks to Olafur Gurmundsson for a reference implementation.
+</t>
+</section>
+
+</middle>
+
+<back>
+<references title="Normative references">
+<!-- DNSSEC -->
+<?rfc include="reference.RFC.1034" ?>
+<?rfc include="reference.RFC.1035" ?>
+<?rfc include="reference.RFC.1521" ?>
+<?rfc include="reference.RFC.2026" ?>
+<?rfc include="reference.RFC.2065" ?>
+<?rfc include="reference.RFC.2434" ?>
+</references>
+
+<references title="Non-normative references">
+<?rfc include="reference.RFC.1886" ?>
+<?rfc include="reference.RFC.2119" ?>
+<?rfc include="reference.RFC.2407" ?>
+<?rfc include="reference.RFC.2535" ?>
+<?rfc include="reference.RFC.2536" ?>
+<?rfc include="reference.RFC.3110" ?>
+<?rfc include="reference.RFC.3445" ?>
+</references>
+</back>
+</rfc>
+<!--
+ $Id: draft-richardson-ipsec-rr.xml,v 1.1 2004/03/15 20:35:24 as Exp $
+
+ $Log: draft-richardson-ipsec-rr.xml,v $
+ Revision 1.1 2004/03/15 20:35:24 as
+ added files from freeswan-2.04-x509-1.5.3
+
+ Revision 1.23 2003/09/04 23:26:09 mcr
+ more nits.
+
+ Revision 1.22 2003/08/16 15:55:35 mcr
+ fixed version to -06.
+
+ Revision 1.21 2003/08/16 15:52:32 mcr
+ Sam's comments on IANA considerations.
+
+ Revision 1.20 2003/07/27 22:57:54 mcr
+ updated document with new text about a seperate registry
+ for the algorithm type.
+
+ Revision 1.19 2003/06/30 01:51:50 mcr
+ minor typo fixes.
+
+ Revision 1.18 2003/06/16 17:45:00 mcr
+ adjusted date on rev-04.
+
+ Revision 1.17 2003/06/16 17:41:30 mcr
+ revision -04
+
+ Revision 1.16 2003/06/16 17:39:20 mcr
+ adjusted typos, and adjusted IANA considerations.
+
+ Revision 1.15 2003/05/26 19:31:23 mcr
+ updates to drafts - IPSEC RR - SC versions, and RFC3526
+ reference in OE draft.
+
+ Revision 1.14 2003/05/23 13:57:40 mcr
+ updated draft ##.
+
+ Revision 1.13 2003/05/23 13:54:45 mcr
+ updated month on draft.
+
+ Revision 1.12 2003/05/21 15:42:49 mcr
+ new SC section with comments from Rob Austein.
+
+ Revision 1.11 2003/05/20 20:52:22 mcr
+ new security considerations section.
+
+ Revision 1.10 2003/05/20 19:07:47 mcr
+ rewrote Security Considerations.
+
+ Revision 1.9 2003/05/20 18:17:09 mcr
+ nits from Rob Austein.
+
+ Revision 1.8 2003/04/29 00:44:59 mcr
+ updates according to WG consensus: restored three-way
+ gateway field type.
+
+ Revision 1.7 2003/03/30 17:00:29 mcr
+ updates according to community feedback.
+
+ Revision 1.6 2003/03/19 02:20:24 mcr
+ updated draft based upon comments from working group
+
+ Revision 1.5 2003/02/23 22:39:22 mcr
+ updates to IPSECKEY draft.
+
+ Revision 1.4 2003/02/21 04:39:04 mcr
+ updated drafts, and added crosscompile.html
+
+ Revision 1.3 2003/01/17 16:26:34 mcr
+ updated IPSEC KEY draft with restrictions.
+
+ Revision 1.2 2002/08/26 18:20:54 mcr
+ updated documents
+
+ Revision 1.1 2002/08/10 20:05:33 mcr
+ document proposing IPSECKEY Resource Record
+
+
+!>
diff --git a/doc/utils/cleanhtml.sed b/doc/utils/cleanhtml.sed
deleted file mode 100644
index 59d3866b8..000000000
--- a/doc/utils/cleanhtml.sed
+++ /dev/null
@@ -1 +0,0 @@
-/<STYLE>/,/<\/STYLE>/d
diff --git a/doc/utils/cleanhtml.sh b/doc/utils/cleanhtml.sh
deleted file mode 100755
index a3ea2afac..000000000
--- a/doc/utils/cleanhtml.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-# script to clean up HTML files
-# removes formatting added by htmldoc
-#
-# first argument is sedscript to use
-f=$1
-shift
-# remaining args are files to process
-for i
-do
- sed -f $f $i > tmp
- mv tmp $i
-done
diff --git a/doc/utils/contents.awk b/doc/utils/contents.awk
deleted file mode 100644
index 5cc07f246..000000000
--- a/doc/utils/contents.awk
+++ /dev/null
@@ -1,109 +0,0 @@
-# table-of-contents extractor
-# Copyright (C) 1999 Sandy Harris.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: contents.awk,v 1.1 2004/03/15 20:35:24 as Exp $
-BEGIN {
- # initialise indent counter
- indent = 0
- # define variables for section breaks
- b0 = "==================================================="
- b1 = "---------------------------------------------------"
- b2 = "\t------------------------------------------"
- # TURN OFF HTML formatting
- print "<html>"
- print "<body>"
- print "<pre>"
- # print a header
- blurb()
- print "Section headings printed, indentation shows structure"
-}
-# start of new file
-FNR == 1 {
- print b0
- print "HTML file: " "<a href=\"" FILENAME "\">" FILENAME "</a>"
- print b1
-}
-# print header lines
-# actual printing is done by tagged() function
-# which adds tag if last line was <a name=...>
-$0 ~/<h1>/ {
- text = $0
- tabs = ""
- gsub(/.*<h1>/, "", text)
- gsub(/<\/h1>/, "", text)
- tagged( text )
-}
-$0 ~/<h2>/ {
- text = $0
- tabs = "\t"
- gsub(/.*<h2>/, "", text)
- gsub(/<\/h2>/, "", text)
- tagged(text)
-}
-$0 ~/<h3>/ {
- text = $0
- tabs = "\t\t"
- gsub(/.*<h3>/, "", text)
- gsub(/<\/h3>/, "", text)
- tagged(text)
-}
-$0 ~/<h4>/ {
- text = $0
- tabs = "\t\t\t"
- gsub(/.*<h4>/, "", text)
- gsub(/<\/h4>/, "", text)
- tagged( text )
-}
-# if current line is not header
-# and we have stored tag from <a name=..> line
-# make link to that tag
-$0 !~ /<h[1-4]/ {
- if( length(name) )
- print "[ <a href=\"" FILENAME "#" name "\">" name "</a>" " ]"
- name = ""
-}
-# for <a name=whatever> lines
-# save name in a variable
-# not printed until we see next line
-$0 ~ /<a name=.*>/ {
- name = $0
- # strip anything before or after name tag
- gsub(/.*<a name=/, "", name)
- gsub(/>.*/, "", name)
- # strip quotes off name
- gsub(/^"/, "", name)
- gsub(/"$/, "", name)
-}
-END {
- print b0
- blurb()
- print "Docs & script by Sandy Harris"
- print "</pre>"
- print "</body>"
- print "</html>"
-}
-
-function tagged(text) { # print header with tag if available
- if( length(name) ) # > 0 if previous line was a name
- print tabs "<a href=\"" FILENAME "#" name "\">" text "</a>"
- else
- print tabs text
- name = ""
-}
-
-function blurb() {
- print "Linux FreeSWAN HTML documents"
- print "Automatically generated Table of Contents"
- print "Bug reports to the mailing list: linux-ipsec@clinet.fi"
- print "<p>"
-}
diff --git a/doc/utils/four2perm.1 b/doc/utils/four2perm.1
deleted file mode 100644
index 1e5263b5b..000000000
--- a/doc/utils/four2perm.1
+++ /dev/null
@@ -1,20 +0,0 @@
-.TH FOUR2PERM 1 "August 1999"
-.\" RCSID $Id: four2perm.1,v 1.1 2004/03/15 20:35:24 as Exp $
-.SH NAME
-four2perm - generate permuted index from four-field lines
-.SH SYNOPSIS
-.B four2perm
-.SH DESCRIPTION
-.I four2perm
-expects input lines with four tab-separated fields, such as that
-created from HTML files by html2four(1). Given that, it does most
-of the work of generating a permuted index, gets things close
-enough that a simple pipeline through sort(1) and awk(1) can
-finish the job.
-.SH SEE ALSO
-.hy 0
-html2four(1)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.xs4all.nl/~freeswan/>
-by Sandy Harris.
diff --git a/doc/utils/four2perm.c b/doc/utils/four2perm.c
deleted file mode 100644
index 5b575c1b5..000000000
--- a/doc/utils/four2perm.c
+++ /dev/null
@@ -1,140 +0,0 @@
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#define MAX_LINE 512
-
-void die( char * ) ;
-
-char buffer[MAX_LINE+1] ;
-char *prog_name ;
-
-void die( char *message )
-{
- fflush(stdout) ;
- fprintf(stderr, "%s: %s\n", prog_name, message) ;
- exit(1) ;
-}
-
-int main(int argc, char* argv[])
-{
- int errors ;
- prog_name = *argv ;
- if( argc != 1 )
- die("pure filter, takes no arguments") ;
- errors = 0 ;
- while( fgets(buffer, MAX_LINE, stdin))
- errors += do_line(buffer) ;
- exit(errors ? 1 : 0 ) ;
-}
-
-int do_line(char *data)
-{
- char *p, *q, *r, *end, *before, *after ;
- // expecting two tab-separated fields
- // point r to 2nd, null terminate 1st
- for( r = data ; *r && *r != '\t' ; r++ )
- ;
- if( *r != '\t' )
- return(1) ;
- end = r++ ;
- *end = '\0' ;
- for( q = r ; *q ; q++ )
- if( *q == '\n' )
- *q = '\0' ;
- if( !strlen(r) )
- return(1) ;
- // within 1st, parse as space-separated
- // p will point to current word, q past its end
- // before & after point to rest of text
- // spaces converted to nulls & back as req'd
- before = "" ;
- for( p = data ; p < end ; p = q + 1 ) {
- if( p > data ) {
- before = data ;
- p[-1] = '\0' ;
- }
- // find end of word
- for( q = p ; *q && *q != ' ' ; q++ )
- ;
- if( q == end )
- after = "" ;
- else if( q < end ) {
- after = q + 1 ;
- *q = '\0' ;
- }
- else assert(0) ;
- print_line(before, p, after, r) ;
- if( q < end )
- *q = ' ' ;
- if( p > data )
- p[-1] = ' ' ;
- }
- return(0) ;
-}
-
-// print formatted line for permuted index
-// two tab-separated fields
-// 1st is sort key
-// 2nd is printable line
-// pipe it through something like
-// sort -F | awk -F '\t' '{print $2}'
-// to get final output
-
-print_line( char *before, char *word, char *after, char *tag)
-{
- int i , x, y, z ;
-/*
- printf("%s\t%s\t%s\t%s\n", before, word, after, tag) ;
-*/
- if( list_word(word) )
- return ;
- x = strlen(before) ;
- y = strlen(word) ;
- z = strlen(after) ;
- // put in sortable field
- // strip out with awk after sorting
- printf("%s %s\t", word, after) ;
- // shorten before string to fit field
- for( ; x > 30 ; x-- )
- before++ ;
- printf("%30s", before) ;
- // print keyword, html tagged
- printf(" %s%s</a> ", tag, word) ;
- // padding, outside tag
- for( ; y < 18 ; y++ )
- putchar(' ') ;
- if( z )
- printf("%s", after) ;
- printf("\n") ;
-}
-
-// avoid indexing on common English words
-
-char *list[] = {
- "the", "of", "a", "an", "to", "and", "or", "if", "for", "at",
- "am", "is", "are", "was", "were", "have", "has", "had", "be", "been",
- "on", "some", "with", "any", "into", "as", "by", "in", "out",
- "that", "then", "this", "that", "than", "these", "those",
- "he", "his", "him", "she", "her", "hers", "it", "its",
- "&", "", "+", "-", "=", "--", "<", ">", "<=", ">=",
- "!", "?", "#", "$", "%", "/", "\\", "\"", "\'",
- NULL
- } ;
-// interrogative words like "how" and "where" deliberately left out of
-// above list because users might want to search for "how to..." etc.
-
-// return 1 if word in list, else 0
-// case-insensitive comparison
-
-list_word( char *p )
-{
- char **z ;
- for( z = list ; *z != NULL ; z++ )
- if( ! strcasecmp( p, *z ) )
- return 1 ;
- return 0 ;
-}
-
diff --git a/doc/utils/html2four.1 b/doc/utils/html2four.1
deleted file mode 100644
index 456ac5e98..000000000
--- a/doc/utils/html2four.1
+++ /dev/null
@@ -1,26 +0,0 @@
-.TH HTML2FOUR 1 "August 1999"
-.\" RCSID $Id: html2four.1,v 1.1 2004/03/15 20:35:24 as Exp $
-.SH NAME
-html2four - extract headers from HTML files into four-field lines
-.SH SYNOPSIS
-.B html2four
-[-digit] file*
-command [ argument ...]
-.SH DESCRIPTION
-.I html2four
-extracts information from HTML files and writes it out with four
-tab-separated fields: filename, last label (<a name=> tag) seen,
-header tag type (H[0-9]), and header text. This is an intermediate
-format convenient for generating a permuted index with four2perm(1)
-or a table of contents with a simple awkscript.
-
-The only option is a digit to limit the header levels extracted.
-For example, with -3 only h1, h2, h3 tags are taken. By default,
-it takes h[0-9], though HTML only defines levels 1 to 6.
-.SH SEE ALSO
-.hy 0
-four2perm(1)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.xs4all.nl/~freeswan/>
-by Sandy Harris.
diff --git a/doc/utils/html2four.c b/doc/utils/html2four.c
deleted file mode 100644
index fc1100d01..000000000
--- a/doc/utils/html2four.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- extract headers from HTML files
- in format suitable for turning into permuted index
-*/
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-/*
- maximum sizes for input line and for name in <a> tag
-*/
-#define MAX_LINE 512
-#define MAX_NAME 64
-
-/*
- functions
- all return 0 for OK, 1 for errors
-*/
-int do_file( char *, FILE * ) ;
-int parse_line( char * ) ;
-int print_line( char *, char *) ;
-int print_header_problem( char * ) ;
-int sanity() ;
-
-void die( char * ) ;
-
-char *prog_name ;
-int max_level ;
-char *current_file ;
-
-int main(int argc, char* argv[])
-{
- char *p ;
- int temp, done, status ;
- FILE *fp ;
-
- prog_name = *argv ;
- argc--,argv++ ;
-
- max_level = 9 ;
- if(argc && *argv ) {
- p = *argv ;
- if( p[0] == '-' ) {
- if( isdigit(p[1]) && p[2] == '\0' ) {
- max_level = p[1] - 0 ;
- argc-- ;
- argv++ ;
- }
- else die("unknown option") ;
- } }
-
- status = done = 0 ;
- if( argc == 0) {
- if( (status = do_file("STDIN", stdin)) == 0 )
- done++ ;
- }
- else {
-/*
- printf("ARGC = %d\n", argc ) ;
-*/
- while( argc-- ) {
- p = *argv++ ;
-/*
- printf("ARGV P %s %s\n", *argv, p) ;
-*/
- if( p == NULL ) {
- fprintf(stderr, "%s: null filename pointer\n", prog_name) ;
- status++ ;
- }
- else if( (fp = fopen(p,"r")) == NULL ) {
- fprintf(stderr, "%s: cannot open file %s\n", prog_name, p) ;
- status++ ;
- }
- else {
- if( (temp = do_file(p, fp)) != 0 )
- status++ ;
- done++ ;
- fclose(fp) ;
- }
- fflush(stderr) ;
- fflush(stdout) ;
- }
- }
-/*
- printf("%s: %d files processed, %d with errors\n", prog_name, done, status) ;
-*/
- return( status ? 1 : 0 ) ;
-}
-
-void die( char *message )
-{
- fflush(stdout) ;
- fprintf(stderr, "%s: %s\n", prog_name, message) ;
- exit(1) ;
-}
-
-int header_flags[10] ;
-int in_header ;
-
-char buffer[MAX_LINE+1] ;
-char label[MAX_NAME+1] ;
-
-int do_file( char *file, FILE *fp )
-{
- int i, status, x, y ;
- char *base, *p ;
-
- status = 0 ;
- in_header = 0 ;
- label[0] = '\0' ;
- for( i = 0 ; i < 10 ; i++ )
- header_flags[i] = 0 ;
- current_file = file ;
-
- while( base = fgets(buffer, MAX_LINE, fp) ) {
- // count < and > characters in line
- for( x = y = 0, p = base ; *p ; p++ )
- switch( *p ) {
- case '<':
- x++ ;
- break ;
- case '>':
- y++ ;
- break ;
- default:
- break ;
- }
- // skip line if no < or >
- if( x == 0 && y == 0 )
- continue ;
- // report error for unequal count
- else if( x != y ) {
- if( strncmp( base, "<!--", 4) && strncmp(base, "-->", 3) ) {
- fflush(stdout) ;
- fprintf(stderr, "%s in file %s: unequal < > counts %d %d\n",
- prog_name, file, x, y ) ;
- fprintf(stderr, "%s: %s\n", prog_name, base) ;
- fflush(stderr) ;
- status = 1 ;
- }
- continue ;
- }
- // parse lines containing tags
- else
- if( parse_line(base) )
- status = 1 ;
- // check that header labelling is sane
- for( i = x = y = 0 ; i < 10 ; i++ ) {
- // count non-zero entries
- if( x = header_flags[i] )
- y++ ;
- // should be in 0 or 1 headers at a time
- if( x > 1 || x < 0 )
- status = 1 ;
- }
- if( y > 1 )
- status = 1 ;
- }
- return status ;
-}
-
-int parse_line( char *data )
-{
- char *p, *q, *end ;
- int x ;
-
- // set end pointer
- for( end = data ; *end ; end++ )
- ;
- // trim off trailing returns or newlines
- for( p = end - 1, q = end ; q > data ; p--,q-- ) {
- switch( *p ) {
- case '\012':
- case '\015':
- *p = '\0' ;
- continue ;
- default:
- break ; // out of switch()
- }
- break ; // out of for()
- }
- end = q ;
- p = data ;
- while( p < end ) {
- // find tag delimiters
- if( *p == '<') {
- for( q = p + 1 ; *q ; q++ )
- if( *q == '<' || *q == '>' )
- break ;
- // if we find another '<'
- // restart tag search from it
- if( *q == '<' ) {
- p = q ;
- continue ;
- }
- // "<>" is not interesting
- if( q == p + 1 ) {
- fflush(stdout) ;
- fprintf(stderr, "%s: null tag\n", prog_name) ;
- fprintf(stderr, "%s: line\n", prog_name, data) ;
- fflush(stderr) ;
- p = q + 1 ;
- continue ;
- }
- // ignore delimiters once found
- *q = '\0' ;
- p++ ;
- // p points to tag contents, null terminated
- switch( *p ) {
- // save contents of <a name= > tags
- case 'a' :
- case 'A' :
- if( p[1] == ' ' &&
- (p[2] == 'n' || p[2] == 'N') &&
- (p[3] == 'a' || p[3] == 'A') &&
- (p[4] == 'm' || p[4] == 'M') &&
- (p[5] == 'e' || p[5] == 'E') &&
- p[6] == '=' )
- strncpy(label, p + 7, MAX_NAME) ;
- break ;
- case 'b' :
- case 'B' :
- if( in_header && strlen(p) == 2 &&
- (p[1] == 'r' || p[1] == 'R') )
- putchar(' ') ;
- break ;
- // header tags
- case 'h' :
- case 'H' :
- if( strlen(p) == 2 && isdigit(p[1]) ) {
- if( in_header )
- fprintf(stderr, "%s: bad header nesting in %s\n",
- prog_name, current_file) ;
- x = p[1] - '0' ;
- in_header = 1 ;
- header_flags[x]++ ;
- printf("%s\t%s\tH%d\t", current_file, label, x) ;
- }
- break ;
- // only care about end-of-header
- case '/':
- p++ ;
- switch( *p ) {
- case 'h' :
- case 'H' :
- if( strlen(p) == 2 && isdigit(p[1]) ) {
- if( ! in_header )
- fprintf(stderr, "%s: bad header nesting in %s\n",
- prog_name, current_file) ;
- x = p[1] - '0' ;
- in_header = 0 ;
- header_flags[x]-- ;
- printf("\n") ;
- }
- break ;
- }
- break ;
- // uninteresting tag, look for next
- default :
- break ;
- }
- // tag done, point p beyond it
- p = q + 1 ;
- }
- else if( in_header ) {
- if( isprint(*p) && *p != '\n' )
- putchar(*p) ;
- else
- putchar(' ');
- p++ ;
- }
- else
- p++ ;
- }
- return(0) ;
-}
-
-int print_line( char *tag, char *text)
-{
- printf("%%s\ts\t%s\t%s\t\n", current_file, label, tag, text) ;
- return 0 ;
-}
-
-int print_header_problem( char *file )
-{
- int i ;
- fflush(stdout) ;
- fprintf(stderr, "%s: HEADER TAG PROBLEM in file %s\n", prog_name, file) ;
- fprintf(stderr, "%s: counts", prog_name) ;
- for ( i = 0 ; i < 10 ; i++ )
- fprintf(stderr, "\t%d", i) ;
- fprintf(stderr,"\n") ;
- fflush(stderr) ;
- return(0) ;
-}
-
diff --git a/doc/utils/html2txt.sed b/doc/utils/html2txt.sed
deleted file mode 100644
index fc4940991..000000000
--- a/doc/utils/html2txt.sed
+++ /dev/null
@@ -1,86 +0,0 @@
-# skip over header material
-# Copyright (C) 1999 Sandy Harris.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: html2txt.sed,v 1.1 2004/03/15 20:35:24 as Exp $
-/<head>/,/<\/head>/d
-/<HEAD>/,/<\/HEAD>/d
-/<^body$>/d
-s/<body>//
-# eliminate possible DOS crud
-s/\015//
-#get rid of HTML comments
-s/<!--.*-->//
-/<!--/,/-->/d
-# citations & emphasis -> visible
-s/<cite>/"/g
-s/<\/cite>/"/g
-s/<em>/*/g
-s/<\/em>/*/g
-s/<strong>/!->/g
-s/<\/strong>/<-!/g
-s/<b>//g
-s/<\/b>//g
-s/<blockquote>/Quote -->/
-s/<\/blockquote>/<-- End Quote/
-# mark headers
-s/<h1>/Header 1: /
-s/<h2>/Header 2: /
-s/<h3>/Header 3: /
-s/<h4>/Header 4: /
-s/<h5>/Header 5: /
-s/<h6>/Header 6: /
-# remove some cruft
-s/<\/h[1-6]>//
-/^<a name=[a-zA-Z0-9\.]*>$/d
-s/<a name=[a-zA-Z0-9\.]*>//
-# definition lists
-s/<dl>//
-s/<\/dl>//
-s/^<dt>$/-----------------------------------------/
-s/^<dt>/-----------------------------------------\
-/
-s/<dd>/\
-/
-# other types of lists
-s/<li>//
-s/<ol>//
-s/<ul>//
-s/<\/ol>//
-s/<\/ul>//
-# tables
-s/<table>//
-s/<\/table>//
-s/<tr>//
-s/<td>/ /g
-# line break and paragraph markers
-# different subst depending where they are in line
-s/^<br>//
-s/<br>$//
-s/<br>/\
-/
-s/^<p>$//
-s/<p>$/\
-/
-s/^<p>/\
-/
-s/<p>/\
-\
-/
-s/<\/p>//
-# remove more cruft
-s/<pre>//
-s/<\/pre>//
-s/<\/body>//
-s/<\/html//
-s/<\/BODY>//
-s/<\/HTML>//
diff --git a/doc/utils/killtoodeepcontents.pl b/doc/utils/killtoodeepcontents.pl
deleted file mode 100644
index a6fe551d6..000000000
--- a/doc/utils/killtoodeepcontents.pl
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/perl
-
-$toc=0;
-$memo=0;
-
-while(<>) {
- if(0 && /^Status of this Memo/) {
- $memo=1;
- print;
- next;
- }
-
- if(/^Table of Contents/) {
- print ".bp\n";
- $toc=1;
- print;
- next;
- }
-
- if(!$toc && !$memo) {
- print;
- next;
- }
-
- if($toc) {
- if(/^[0-9]*\.[0-9]*\.[0-9]* / ||
-# /^[0-9]*\.[0-9]* / ||
- /^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]* /) {
- next;
- }
-
- if(/^14./) {
- $toc=0;
- }
- if(/^\.bp/) {
- next;
- }
- print;
- }
-
- if($memo) {
- if(/^\.bp/) {
- next;
- }
-
- if(/^Copyright Notice/) {
- print ".fi\n";
- print "This memo provides information for the Internet community. It does\n";
- print "not specify an Internet standard of any kind. Distribution of this\n";
- print "memo is unlimited.\n";
- print "\n.ti 0\n";
-
- print;
-
- $memo=0;
- next;
- }
- }
-}
diff --git a/doc/utils/man2html.script b/doc/utils/man2html.script
deleted file mode 100755
index 515911c81..000000000
--- a/doc/utils/man2html.script
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/sh
-
-# Assumes man2html command in path
-# That is a Perl script downloadable from
-# http://www.oac.uci.edu/indiv/ehood/man2html.html
-
-# also uses our man_xref utility
-
-case $# in
-2) ;;
-*) echo "Usage: $0 mantree destdir" >&2 ; exit 2 ;;
-esac
-
-mkdir -p $2
-rm -f $2/*
-
-# handle all sections just in case
-# only 3 5 8 expected
-for i in `find $1 -name 'ipsec*.[1-9]'`
-do
- b=`basename $i`
- # then parse that into section number s
- # and name n
- case $b in
- *.1) s=1 ;;
- *.2) s=2 ;;
- *.3) s=3 ;;
- *.4) s=4 ;;
- *.5) s=5 ;;
- *.6) s=6 ;;
- *.7) s=7 ;;
- *.8) s=8 ;;
- *.9) s=9 ;;
- *) echo "$0 has lost its mind" ; exit 1 ;;
- esac
- n=`basename $b \.$s`
- # the echos are a kluge
- # without them, the first section head is not tagged
- (echo ; echo ; man $s $n ) | man2html > $2/$b.html
-done
-# man2html doesn't convert man page cross-references such as
-# ipsec.conf(5) into HTML links
-# So post-process to do that.
-for i in $2/*.html
-do
- ../utils/man_xref $i > temp
- mv temp $i
-done
diff --git a/doc/utils/man_xref.c b/doc/utils/man_xref.c
deleted file mode 100644
index fc3afb696..000000000
--- a/doc/utils/man_xref.c
+++ /dev/null
@@ -1,125 +0,0 @@
-#include <stdio.h>
-#include <ctype.h>
-#include <assert.h>
-
-/*
- look through HTMLized man pages
- convert references like man(1) into HTML links
-
- somewhat quick & dirty code
- various dubious assumptions made:
-
- [a-zA-Z0-9\-_\.]* defines legal characters in name
- pagename(x) corresponds to pagename.x.html
- (Fine *if* it's been converted by my scripts)
- x in the above must be a single digit
- (or we ignore it, which does no damage)
- Lazy parsing: malloc() enough RAM to read in whole file
- Limited syntax: exactly one input file, results to stdout
-
- Sandy Harris
-*/
-
-int do_file( char *, char *) ;
-
-main(int argc, char **argv)
-{
- FILE *in ;
- char *progname;
- long lsize ;
- size_t size, nread;
- char *buffer, *bufend ;
- progname = *argv ;
- if( argc != 2 ) {
- fprintf(stderr,"usage: %s input-file\n", progname);
- exit(1) ;
- }
- if( (in = fopen(argv[1],"r")) == NULL ) {
- fprintf(stderr,"%s Can't open input file\n", progname);
- exit(2) ;
- }
- if( (lsize = fseek(in, 0L, SEEK_END)) < 0L ) {
- fprintf(stderr,"%s fseek() fails\n", progname);
- exit(3) ;
- }
- lsize = ftell(in) ;
- rewind(in) ;
- size = (size_t) lsize ;
- if( lsize != (long) size ) {
- fprintf(stderr,"%s file too large\n", progname);
- exit(4) ;
- }
- if( (buffer = (char *) malloc(size)) == NULL) {
- fprintf(stderr,"%s malloc() failed\n", progname);
- exit(5) ;
- }
- bufend = buffer + size ;
- if( (nread = fread(buffer, size, 1, in)) != 1) {
- fprintf(stderr,"%s fread() failed\n", progname);
- exit(6) ;
- }
- do_file(buffer,bufend);
-}
-
-do_file(char *start, char *end)
-{
- /* p is where to start parsing, one past last output */
- /* q is how far we've parsed */
- char *p, *q ;
- int value ;
- for( p = q = start ; p < end ; q = (q<end) ? (q+1) : q ) {
- /* if p is beyond q, catch up */
- if( q < p )
- continue ;
- /* move q ahead until we know if we've got manpage name */
- if( isalnum(*q) )
- continue ;
- switch(*q) {
- /* can appear in manpage name */
- case '.':
- case '_':
- case '-':
- case '(':
- continue ;
- break ;
- /* whatever's between p and q
- is not a manpage name
- so output it
- */
- default:
- /* leave p one past output */
- for( ; p <= q ; p++ )
- putchar(*p);
- break ;
- /* we may have a manpage name */
- case ')':
- value = do_name(p,q);
- if(value) {
- p = q ;
- p++ ;
- }
- /* unreached with current do_name() */
- else
- for( ; p <= q ; p++ )
- putchar(*p);
- break ;
-} } }
-
-do_name(char *p, char *q)
-{
- *q = '\0' ;
- /* if end of string matches RE ([0-9])
- with at least one legal character before it
- add HTML xref stuff
- */
- if( (q-p > 3) && isdigit(q[-1]) && (q[-2]=='(')) {
- q[-2] = '\0' ;
- q-- ;
- printf("<a href=\"%s.%s.html\">", p, q);
- printf("%s(%s)", p, q);
- printf("</a>");
- }
- // otherwise just print string
- else printf("%s)", p);
- return 1 ;
-}
diff --git a/doc/utils/mkhtmlman b/doc/utils/mkhtmlman
deleted file mode 100755
index 6d73bd1f2..000000000
--- a/doc/utils/mkhtmlman
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/sh
-# gathers manpages up into dir, converts them to HTML, including interlinking
-# Assumes RedHat6.0 man2html available.
-
-PATH=/usr/local/bin:/bin:/usr/bin:/usr/contrib/bin:$PATH ; export PATH
-
-# note, this is always run from freeswan/doc.
-
-TOPDIR=..
-
-case $# in
-1) exit 0 ;;
-0) echo "Usage: $0 destdir manpage ..." >&2 ; exit 1 ;;
-esac
-
-dir=$1
-shift
-mkdir -p $dir
-rm -f $dir/*
-
-for f
-do
- b=`basename $f`
- case $b in
- ipsec*) ;; # ipsec.8, ipsec.conf.5, etc.
- *) b="ipsec_$b" ;;
- esac
- cp $f $dir/$b
- $TOPDIR/packaging/utils/manlink $f | while read from to
- do
- (cd $dir; ln -s ../$f $to)
- done
-done
-
-# build the html (sed mess fixes overly-smart man2html's crud)
-refpat='"http://localhost/cgi-bin/man/man2html?\([1-8]\)+\([^"]*\)"'
-for f in $dir/*.[1-8]
-do
- echo Processing $f
- man2html <$f | sed 's;'"$refpat"';"\2.\1.html";g' >$f.html
-done
-
-# remove the source files (must wait until after all builds, due to symlinks)
-rm -f $dir/*.[1-8]
diff --git a/doc/utils/perm1.awk b/doc/utils/perm1.awk
deleted file mode 100644
index d9f8f5565..000000000
--- a/doc/utils/perm1.awk
+++ /dev/null
@@ -1 +0,0 @@
-{ print $4 "\t<a href=\"" $1 "#" $2 "\">" }
diff --git a/doc/utils/perm2.awk b/doc/utils/perm2.awk
deleted file mode 100644
index 3c55fef11..000000000
--- a/doc/utils/perm2.awk
+++ /dev/null
@@ -1,46 +0,0 @@
-BEGIN {
- print "<html>\n<body>"
- print "<h2>Permuted Index of HTML headers in FreeS/WAN documents</h2>"
- print "<h3>Jump to a letter</h3>"
- print "<center><big><strong>"
- print "<a href=\"#0\">numeric</a>"
- print "<a href=\"#a\">A</a>"
- print "<a href=\"#b\">B</a>"
- print "<a href=\"#c\">C</a>"
- print "<a href=\"#d\">D</a>"
- print "<a href=\"#e\">E</a>"
- print "<a href=\"#f\">F</a>"
- print "<a href=\"#g\">G</a>"
- print "<a href=\"#h\">H</a>"
- print "<a href=\"#i\">I</a>"
- print "<a href=\"#j\">J</a>"
- print "<a href=\"#k\">K</a>"
- print "<a href=\"#l\">L</a>"
- print "<a href=\"#m\">M</a>"
- print "<a href=\"#n\">N</a>"
- print "<a href=\"#o\">O</a>"
- print "<a href=\"#p\">P</a>"
- print "<a href=\"#q\">Q</a>"
- print "<a href=\"#r\">R</a>"
- print "<a href=\"#s\">S</a>"
- print "<a href=\"#t\">T</a>"
- print "<a href=\"#u\">U</a>"
- print "<a href=\"#v\">V</a>"
- print "<a href=\"#w\">W</a>"
- print "<a href=\"#x\">X</a>"
- print "<a href=\"#y\">Y</a>"
- print "<a href=\"#z\">Z</a>"
- print "</strong></big></center>"
- print "<hr>"
- print "<pre>"
- print "<a name=0>"
- old =""
- }
-{ x = tolower(substr($1,1,1))
- if( (x ~ /[a-zA-Z]/) && (x != old) )
- print "<a name=" x ">" $2
- else
- print $2
- old = x
- }
-END { print "</pre>\n</html>" }
diff --git a/doc/utils/rfc_pg.c b/doc/utils/rfc_pg.c
deleted file mode 100644
index e2484959e..000000000
--- a/doc/utils/rfc_pg.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * $Header: /root/strongswan/doc/utils/rfc_pg.c,v 1.1 2004/03/15 20:35:24 as Exp $
- *
- * from 2-nroff.template file.
- *
- * Remove N lines following any line that contains a form feed (^L).
- * (Why can't this be done with awk or sed?)
- *
- * OPTION:
- * -n# Number of lines to delete following each ^L (0 default).
- * $Log: rfc_pg.c,v $
- * Revision 1.1 2004/03/15 20:35:24 as
- * added files from freeswan-2.04-x509-1.5.3
- *
- * Revision 1.1 2002/07/23 18:42:43 mcr
- * required utility from IETF to help with formatting of drafts.
- *
- */
-#include <stdio.h>
-
-#define FORM_FEED '\f'
-#define OPTION "n:N:" /* for getopt() */
-
-extern char *optarg;
-extern int optind;
-
-main(argc, argv)
-int argc;
-char *argv[];
-{
- int c, /* next input char */
- nlines = 0; /* lines to delete after ^L */
- void print_and_delete(); /* print line starting with ^L,
- then delete N lines */
-
-/*********************** Process option (-nlines) ***********************/
-
- while ((c = getopt(argc, argv, OPTION)) != EOF)
- switch(c)
- {
- case 'n' :
- case 'N' : nlines = atoi(optarg);
- break;
- }
-/************************* READ AND PROCESS CHARS **********************/
-
- while ((c = getchar()) != EOF)
- if (c == FORM_FEED)
- print_and_delete(nlines); /* remove N lines after this one */
- else
- putchar(c); /* we write the form feed */
- exit(0);
-}
-
-
-/*
- * Print rest of line, then delete next N lines.
- */
-void print_and_delete(n)
-int n; /* nbr of lines to delete */
-{
- int c, /* next input char */
- cntr = 0; /* count of deleted lines */
-
- while ((c = getchar()) != '\n') /* finish current line */
- putchar(c);
- putchar('\n'); /* write the last CR */
- putchar(FORM_FEED);
-
- for ( ; cntr < n; cntr++)
- while ((c = getchar()) != '\n')
- if (c == EOF)
- exit(0); /* exit on EOF */
- putchar(c); /* write that last CR */
-}
-
diff --git a/doc/utils/xref.sed b/doc/utils/xref.sed
deleted file mode 100644
index 8c3b442cc..000000000
--- a/doc/utils/xref.sed
+++ /dev/null
@@ -1,56 +0,0 @@
-# turn end-of xref tags into <*>
-# Copyright (C) 1999 Sandy Harris.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: xref.sed,v 1.1 2004/03/15 20:35:24 as Exp $
-s/<\/a>/<*>/g
-# delete all xrefs that point
-# within our document set
-s/<a href="..\/Internet-docs\/rfc....\.txt">//
-# in same doc
-s/<a href="#[a-zA-Z0-9\.]*">//
-# pointer into another doc
-s/<a href="DES.html#[a-zA-Z0-9\.]*">//
-s/<a href="RFCs.html#[a-zA-Z0-9\.]*">//
-s/<a href="WWWref.html#[a-zA-Z0-9\.]*">//
-s/<a href="bibliography.html#[a-zA-Z0-9\.]*">//
-s/<a href="compatibility.html#[a-zA-Z0-9\.]*">//
-s/<a href="configuration.html#[a-zA-Z0-9\.]*">//
-s/<a href="contents.html#[a-zA-Z0-9\.]*">//
-s/<a href="debugging.html#[a-zA-Z0-9\.]*">//
-s/<a href="exportlaws.html#[a-zA-Z0-9\.]*">//
-s/<a href="glossary.html#[a-zA-Z0-9\.]*">//
-s/<a href="index.html#[a-zA-Z0-9\.]*">//
-s/<a href="overview.html#[a-zA-Z0-9\.]*">//
-s/<a href="roadmap.html#[a-zA-Z0-9\.]*">//
-s/<a href="testbed.html#[a-zA-Z0-9\.]*">//
-s/<a href="setup.html#[a-zA-Z0-9\.]*">//
-# pointer to head of doc
-s/<a href="DES.html">//
-s/<a href="RFCs.html">//
-s/<a href="WWWref.html">//
-s/<a href="bibliography.html">//
-s/<a href="compatibility.html">//
-s/<a href="configuration.html">//
-s/<a href="contents.html">//
-s/<a href="debugging.html">//
-s/<a href="exportlaws.html">//
-s/<a href="glossary.html">//
-s/<a href="index.html">//
-s/<a href="overview.html">//
-s/<a href="roadmap.html">//
-s/<a href="testbed.html">//
-s/<a href="setup.html">//
-# xref to non-HTML files
-s/<a href="standards">//
-s/<a href="impl.notes">//
-s/<a href="prob.report">//
diff --git a/programs/pluto/Makefile b/programs/pluto/Makefile
index 908060038..a11a755c0 100644
--- a/programs/pluto/Makefile
+++ b/programs/pluto/Makefile
@@ -12,7 +12,7 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
-# RCSID $Id: Makefile,v 1.45 2006/07/06 12:33:08 as Exp $
+# RCSID $Id: Makefile,v 1.47 2007/01/11 21:47:13 as Exp $
# relative path to top directory of FreeS/WAN source
# Note: referenced in ${FREESWANSRCDIR}/Makefile.inc
@@ -137,8 +137,8 @@ ifeq ($(USE_VENDORID),true)
DEFINES+= -DVENDORID
endif
-ifeq ($(USE_XAUTH_VID),true)
- DEFINES+= -DXAUTH_VID
+ifeq ($(USE_CISCO_QUIRKS),true)
+ DEFINES+= -DCISCO_QUIRKS
endif
# This compile option activates dynamic URL fetching using libcurl
@@ -262,6 +262,7 @@ DISTSRC = \
spdb.c spdb.h \
state.c state.h \
timer.c timer.h \
+ xauth.c xauth.h \
x509.c x509.h \
$(DISTGCRYPT) \
vendor.c nat_traversal.c virtual.c \
@@ -280,7 +281,7 @@ OBJSPLUTO = asn1.o connections.o constants.o cookie.o crypto.o defs.o fetch.o fo
ca.o certs.o id.o ipsec_doi.o kernel.o $(KERNEL26_OBJS) kernel_pfkey.o mp_defs.o \
kernel_noklips.o rcv_whack.o ${IPSECPOLICY_OBJS} demux.o packet.o lex.o keys.o \
dnskey.o smartcard.o ac.o rnd.o spdb.o sha1.o md5.o md2.o modecfg.o ocsp.o crl.o \
- vendor.o nat_traversal.o virtual.o
+ vendor.o nat_traversal.o virtual.o xauth.o
OBJSADNS = adns.o
@@ -477,6 +478,7 @@ vendor.o: vendor.c
virtual.o: virtual.c
whack.o: whack.c
x509.o: x509.c
+xauth.o: xauth.c
ac.o: constants.h
ac.o: defs.h
@@ -794,7 +796,7 @@ keys.o: log.h
keys.o: whack.h
keys.o: timer.h
keys.o: fetch.h
-keys.o: nat_traversal.h
+keys.o: xauth.h
lex.o: constants.h
lex.o: defs.h
lex.o: log.h
@@ -823,6 +825,7 @@ modecfg.o: sha1.h
modecfg.o: crypto.h
modecfg.o: modecfg.h
modecfg.o: whack.h
+modecfg.o: xauth.h
mp_defs.o: constants.h
mp_defs.o: defs.h
mp_defs.o: mp_defs.h
@@ -1088,3 +1091,8 @@ x509.o: whack.h
x509.o: fetch.h
x509.o: ocsp.h
x509.o: sha1.h
+xauth.o: constants.h
+xauth.o: defs.h
+xauth.o: xauth.h
+xauth.o: keys.h
+xauth.o: log.h
diff --git a/programs/pluto/connections.c b/programs/pluto/connections.c
index 1ea6ac5fa..93b3bd2b6 100644
--- a/programs/pluto/connections.c
+++ b/programs/pluto/connections.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: connections.c,v 1.46 2006/10/19 15:40:52 as Exp $
+ * RCSID $Id: connections.c,v 1.47 2007/01/10 00:36:19 as Exp $
*/
#include <string.h>
@@ -3254,13 +3254,17 @@ find_host_connection(const ip_address *me, u_int16_t my_port
if (policy != LEMPTY)
{
+ lset_t auth_requested = policy & POLICY_ID_AUTH_MASK;
+
/* if we have requirements for the policy,
* choose the first matching connection.
*/
while (c != NULL)
{
- if ((c->policy & policy) == policy)
- break;
+ if (c->policy & auth_requested)
+ {
+ break;
+ }
c = c->hp_next;
}
}
@@ -3367,11 +3371,20 @@ refine_host_connection(const struct state *st, const struct id *peer_id
if (psk == NULL)
return NULL; /* cannot determine PSK! */
break;
-
+ case XAUTHInitPreShared:
+ case XAUTHRespPreShared:
+ auth_policy = POLICY_XAUTH_PSK;
+ psk = get_preshared_secret(c);
+ if (psk == NULL)
+ return NULL; /* cannot determine PSK! */
+ break;
case OAKLEY_RSA_SIG:
auth_policy = POLICY_RSASIG;
break;
-
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
+ auth_policy = POLICY_XAUTH_RSASIG;
+ break;
default:
bad_case(auth);
}
@@ -3394,17 +3407,21 @@ refine_host_connection(const struct state *st, const struct id *peer_id
bool matching_id = match_id(peer_id
, &d->spd.that.id, &wildcards);
+ bool matching_auth = (d->policy & auth_policy) != LEMPTY;
+
bool matching_trust = trusted_ca(peer_ca
, d->spd.that.ca, &peer_pathlen);
bool matching_request = match_requested_ca(c->requested_ca
, d->spd.this.ca, &our_pathlen);
- bool match = matching_id && matching_trust && matching_request;
-
+ bool match = matching_id && matching_auth &&
+ matching_trust && matching_request;
+
DBG(DBG_CONTROLMORE,
- DBG_log("%s: %s match (id: %s, trust: %s, request: %s)"
+ DBG_log("%s: %s match (id: %s, auth: %s, trust: %s, request: %s)"
, d->name
, match ? "full":" no"
, match_name[matching_id]
+ , match_name[matching_auth]
, match_name[matching_trust]
, match_name[matching_request])
)
@@ -3423,13 +3440,11 @@ refine_host_connection(const struct state *st, const struct id *peer_id
continue;
#endif
- /* authentication used must fit policy of this connection */
- if ((d->policy & auth_policy) == LEMPTY)
- continue; /* our auth isn't OK for this connection */
-
switch (auth)
{
case OAKLEY_PRESHARED_KEY:
+ case XAUTHInitPreShared:
+ case XAUTHRespPreShared:
/* secret must match the one we already used */
{
const chunk_t *dpsk = get_preshared_secret(d);
@@ -3445,6 +3460,8 @@ refine_host_connection(const struct state *st, const struct id *peer_id
break;
case OAKLEY_RSA_SIG:
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
/*
* We must at least be able to find our private key
.*/
diff --git a/programs/pluto/constants.c b/programs/pluto/constants.c
index 5ca7b65ce..f4aa9d5d1 100644
--- a/programs/pluto/constants.c
+++ b/programs/pluto/constants.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: constants.c,v 1.22 2006/10/19 21:07:40 as Exp $
+ * RCSID $Id: constants.c,v 1.23 2007/01/10 00:36:19 as Exp $
*/
/*
@@ -54,8 +54,8 @@ const char compile_time_interop_options[] = ""
#ifdef VENDORID
" VENDORID"
#endif
-#ifdef XAUTH_VID
- " XAUTH_VID"
+#ifdef CISCO_QUIRKS
+ " CISCO_QUIRKS"
#endif
#ifdef USE_KEYRR
" KEYRR"
@@ -183,12 +183,22 @@ static const char *const state_name[] = {
"STATE_INFO",
"STATE_INFO_PROTECTED",
+ "STATE_XAUTH_I0",
+ "STATE_XAUTH_R1",
+ "STATE_XAUTH_I1",
+ "STATE_XAUTH_R2",
+ "STATE_XAUTH_I2",
+ "STATE_XAUTH_R3",
+
"STATE_MODE_CFG_R0",
- "STATE_MODE_CFG_R1",
- "STATE_MODE_CFG_R2",
"STATE_MODE_CFG_I1",
+ "STATE_MODE_CFG_R1",
"STATE_MODE_CFG_I2",
+
+ "STATE_MODE_CFG_I0",
+ "STATE_MODE_CFG_R3",
"STATE_MODE_CFG_I3",
+ "STATE_MODE_CFG_R4",
"STATE_IKE_ROOF"
};
@@ -216,13 +226,23 @@ const char *const state_story[] = {
"got Informational Message in clear", /* STATE_INFO */
"got encrypted Informational Message", /* STATE_INFO_PROTECTED */
-
- "sent ModeCfg reply", /* STATE_MODE_CFG_R0 */
- "sent ModeCfg reply", /* STATE_MODE_CFG_R1 */
- "received ModeCfg ack", /* STATE_MODE_CFG_R2 */
+
+ "expecting XAUTH request", /* STATE_XAUTH_I0 */
+ "sent XAUTH request, expecting reply", /* STATE_XAUTH_R1 */
+ "sent XAUTH reply, expecting status", /* STATE_XAUTH_I1 */
+ "sent XAUTH status, expecting ack", /* STATE_XAUTH_R2 */
+ "sent XAUTH ack, established", /* STATE_XAUTH_I2 */
+ "received XAUTH ack, established", /* STATE_XAUTH_R3 */
+
+ "expecting ModeCfg request", /* STATE_MODE_CFG_R0 */
"sent ModeCfg request, expecting reply", /* STATE_MODE_CFG_I1 */
- "received ModeCfg reply", /* STATE_MODE_CFG_I2 */
- "received ModeCfg set, sent ack", /* STATE_MODE_CFG_I3 */
+ "sent ModeCfg reply, established", /* STATE_MODE_CFG_R1 */
+ "received ModeCfg reply, established", /* STATE_MODE_CFG_I2 */
+
+ "expecting ModeCfg set", /* STATE_MODE_CFG_I0 */
+ "sent ModeCfg set, expecting ack", /* STATE_MODE_CFG_R3 */
+ "sent ModeCfg ack, established", /* STATE_MODE_CFG_I3 */
+ "received ModeCfg ack, established", /* STATE_MODE_CFG_R4 */
};
/* kind of struct connection */
@@ -487,6 +507,9 @@ const char *const sa_policy_bit_names[] = {
"GROUTED",
"UP",
"MODECFGPUSH",
+ "XAUTHPSK",
+ "XAUTHRSASIG",
+ "XAUTHSERVER",
NULL
};
@@ -675,7 +698,49 @@ enum_names auth_alg_names =
{ AUTH_ALGORITHM_HMAC_MD5, AUTH_ALGORITHM_HMAC_RIPEMD, auth_alg_name
, &extended_auth_alg_names };
-const char *const modecfg_attr_name[] = {
+/* From draft-beaulieu-ike-xauth */
+static const char *const xauth_type_name[] = {
+ "Generic",
+ "RADIUS-CHAP",
+ "OTP",
+ "S/KEY",
+};
+
+enum_names xauth_type_names =
+ { XAUTH_TYPE_GENERIC, XAUTH_TYPE_SKEY, xauth_type_name, NULL};
+
+/* From draft-beaulieu-ike-xauth */
+static const char *const xauth_attr_tv_name[] = {
+ "XAUTH_TYPE",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "XAUTH_STATUS",
+ };
+
+enum_names xauth_attr_tv_names = {
+ XAUTH_TYPE + ISAKMP_ATTR_AF_TV,
+ XAUTH_STATUS + ISAKMP_ATTR_AF_TV, xauth_attr_tv_name, NULL };
+
+static const char *const xauth_attr_name[] = {
+ "XAUTH_USER_NAME",
+ "XAUTH_USER_PASSWORD",
+ "XAUTH_PASSCODE",
+ "XAUTH_MESSAGE",
+ "XAUTH_CHALLENGE",
+ "XAUTH_DOMAIN",
+ "XAUTH_STATUS (wrong TLV syntax, should be TV)",
+ "XAUTH_NEXT_PIN",
+ "XAUTH_ANSWER",
+ };
+
+enum_names xauth_attr_names =
+ { XAUTH_USER_NAME , XAUTH_ANSWER, xauth_attr_name , &xauth_attr_tv_names };
+
+static const char *const modecfg_attr_name[] = {
"INTERNAL_IP4_ADDRESS",
"INTERNAL_IP4_NETMASK",
"INTERNAL_IP4_DNS",
@@ -695,7 +760,7 @@ const char *const modecfg_attr_name[] = {
};
enum_names modecfg_attr_names =
- { INTERNAL_IP4_ADDRESS , INTERNAL_IP6_SUBNET, modecfg_attr_name , NULL };
+ { INTERNAL_IP4_ADDRESS, INTERNAL_IP6_SUBNET, modecfg_attr_name , &xauth_attr_names };
/* Oakley Lifetime Type attribute */
diff --git a/programs/pluto/constants.h b/programs/pluto/constants.h
index bad162898..f18e93fed 100644
--- a/programs/pluto/constants.h
+++ b/programs/pluto/constants.h
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: constants.h,v 1.22 2006/10/19 21:07:40 as Exp $
+ * RCSID $Id: constants.h,v 1.23 2007/01/10 00:36:19 as Exp $
*/
#ifndef _CONSTANTS_H
@@ -504,13 +504,28 @@ enum state_kind {
STATE_INFO,
STATE_INFO_PROTECTED,
- STATE_MODE_CFG_R0, /* these states are used on the responder */
- STATE_MODE_CFG_R1,
- STATE_MODE_CFG_R2,
+ /* XAUTH states */
+
+ STATE_XAUTH_I0, /* initiator state (client) */
+ STATE_XAUTH_R1, /* responder state (server) */
+ STATE_XAUTH_I1,
+ STATE_XAUTH_R2,
+ STATE_XAUTH_I2,
+ STATE_XAUTH_R3,
+
+ /* Mode Config pull states */
- STATE_MODE_CFG_I1, /* this is used on the initiator */
+ STATE_MODE_CFG_R0, /* responder state (server) */
+ STATE_MODE_CFG_I1, /* initiator state (client) */
+ STATE_MODE_CFG_R1,
STATE_MODE_CFG_I2,
+
+ /* Mode Config push states */
+
+ STATE_MODE_CFG_I0, /* initiator state (client) */
+ STATE_MODE_CFG_R3, /* responder state (server) */
STATE_MODE_CFG_I3,
+ STATE_MODE_CFG_R4,
STATE_IKE_ROOF
};
@@ -519,22 +534,30 @@ enum state_kind {
#define PHASE1_INITIATOR_STATES (LELEM(STATE_MAIN_I1) | LELEM(STATE_MAIN_I2) \
| LELEM(STATE_MAIN_I3) | LELEM(STATE_MAIN_I4))
-#define ISAKMP_SA_ESTABLISHED_STATES (LELEM(STATE_MAIN_R3) | LELEM(STATE_MAIN_I4) \
- | LELEM(STATE_MODE_CFG_R1) | LELEM(STATE_MODE_CFG_R2) \
- | LELEM(STATE_MODE_CFG_I2) | LELEM(STATE_MODE_CFG_I3))
+#define ISAKMP_SA_ESTABLISHED_STATES ( \
+ LELEM(STATE_MAIN_R3) | LELEM(STATE_MAIN_I4) \
+ | LELEM(STATE_XAUTH_R1) | LELEM(STATE_XAUTH_R2) | LELEM(STATE_XAUTH_R3) \
+ | LELEM(STATE_XAUTH_I1) | LELEM(STATE_XAUTH_I2) \
+ | LELEM(STATE_MODE_CFG_I1) | LELEM(STATE_MODE_CFG_R1) | LELEM(STATE_MODE_CFG_I2) \
+ | LELEM(STATE_MODE_CFG_R3) | LELEM(STATE_MODE_CFG_I3) | LELEM(STATE_MODE_CFG_R4))
#define IS_PHASE1(s) ((STATE_MAIN_R0 <= (s) && (s) <= STATE_MAIN_I4) \
- || (STATE_MODE_CFG_R0 <= (s) && (s) <= STATE_MODE_CFG_I3))
+ || (STATE_XAUTH_I0 <= (s) && (s) <= STATE_XAUTH_R3) \
+ || (STATE_MODE_CFG_R0 <= (s) && (s) <= STATE_MODE_CFG_R4))
+
#define IS_QUICK(s) (STATE_QUICK_R0 <= (s) && (s) <= STATE_QUICK_R2)
#define IS_ISAKMP_ENCRYPTED(s) (STATE_MAIN_I2 <= (s))
-#define IS_ISAKMP_SA_ESTABLISHED(s) ( \
- (s) == STATE_MAIN_R3 \
- || (s) == STATE_MAIN_I4 \
- || (s) == STATE_MODE_CFG_R0 \
- || (s) == STATE_MODE_CFG_R1 \
- || (s) == STATE_MODE_CFG_R2 \
- || (s) == STATE_MODE_CFG_I2 \
- || (s) == STATE_MODE_CFG_I3)
+
+#define IS_ISAKMP_SA_ESTABLISHED(s) ( \
+ (s) == STATE_MAIN_R3 \
+ || (s) == STATE_MAIN_I4 \
+ || (s) == STATE_XAUTH_R3 \
+ || (s) == STATE_XAUTH_I2 \
+ || (s) == STATE_MODE_CFG_R1 \
+ || (s) == STATE_MODE_CFG_I2 \
+ || (s) == STATE_MODE_CFG_I3 \
+ || (s) == STATE_MODE_CFG_R4)
+
#define IS_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_I2 || (s) == STATE_QUICK_R2)
#define IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_R1)
@@ -638,7 +661,32 @@ extern enum_names attr_msg_type_names;
#define SUPPORTED_ATTRIBUTES 14
#define INTERNAL_IP6_SUBNET 15
+#define MODECFG_ROOF 16
+
extern enum_names modecfg_attr_names;
+/* XAUTH attribute values */
+#define XAUTH_TYPE 16520
+#define XAUTH_USER_NAME 16521
+#define XAUTH_USER_PASSWORD 16522
+#define XAUTH_PASSCODE 16523
+#define XAUTH_MESSAGE 16524
+#define XAUTH_CHALLENGE 16525
+#define XAUTH_DOMAIN 16526
+#define XAUTH_STATUS 16527
+#define XAUTH_NEXT_PIN 16528
+#define XAUTH_ANSWER 16529
+
+#define XAUTH_BASE XAUTH_TYPE
+
+extern enum_names xauth_attr_names;
+
+/* XAUTH authentication types */
+#define XAUTH_TYPE_GENERIC 0
+#define XAUTH_TYPE_CHAP 1
+#define XAUTH_TYPE_OTP 2
+#define XAUTH_TYPE_SKEY 3
+
+extern enum_names xauth_type_names;
/* Exchange types
* RFC2408 "Internet Security Association and Key Management Protocol (ISAKMP)"
@@ -752,7 +800,7 @@ extern const char *prettypolicy(lset_t policy);
#define POLICY_RSASIG LELEM(1)
#define POLICY_ISAKMP_SHIFT 0 /* log2(POLICY_PSK) */
-#define POLICY_ID_AUTH_MASK LRANGES(POLICY_PSK, POLICY_RSASIG)
+#define POLICY_ID_AUTH_MASK (POLICY_PSK | POLICY_RSASIG | POLICY_XAUTH_PSK | POLICY_XAUTH_RSASIG)
#define POLICY_ISAKMP_MASK POLICY_ID_AUTH_MASK /* all so far */
/* Quick Mode (IPSEC) attributes */
@@ -794,7 +842,9 @@ extern const char *prettypolicy(lset_t policy);
#define POLICY_GROUTED LELEM(15) /* do we want this group routed? */
#define POLICY_UP LELEM(16) /* do we want this up? */
#define POLICY_MODECFG_PUSH LELEM(17) /* is modecfg pushed by server? */
-
+#define POLICY_XAUTH_PSK LELEM(18) /* do we support XAUTH????PreShared? */
+#define POLICY_XAUTH_RSASIG LELEM(19) /* do we support XAUTH????RSA? */
+#define POLICY_XAUTH_SERVER LELEM(20) /* are we an XAUTH server? */
/* Any IPsec policy? If not, a connection description
* is only for ISAKMP SA, not IPSEC SA. (A pun, I admit.)
@@ -804,7 +854,7 @@ extern const char *prettypolicy(lset_t policy);
#define HAS_IPSEC_POLICY(p) (((p) & POLICY_IPSEC_MASK) != 0)
/* Don't allow negotiation? */
-#define NEVER_NEGOTIATE(p) (LDISJOINT((p), POLICY_PSK | POLICY_RSASIG))
+#define NEVER_NEGOTIATE(p) (LDISJOINT((p), POLICY_ID_AUTH_MASK))
/* Oakley transform attributes
diff --git a/programs/pluto/defs.h b/programs/pluto/defs.h
index 7e92ea540..3fe5053d1 100644
--- a/programs/pluto/defs.h
+++ b/programs/pluto/defs.h
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: defs.h,v 1.10 2006/01/04 21:00:43 as Exp $
+ * RCSID $Id: defs.h,v 1.11 2007/01/09 21:59:06 as Exp $
*/
#ifndef _DEFS_H
@@ -82,7 +82,7 @@ typedef struct chunk chunk_t;
#define chunkcpy(dst, chunk) \
{ memcpy(dst, chunk.ptr, chunk.len); dst += chunk.len;}
#define same_chunk(a, b) \
- (a).len == (b).len && memcmp((a).ptr, (b).ptr, (b).len) == 0
+ ( (a).len == (b).len && memcmp((a).ptr, (b).ptr, (b).len) == 0 )
extern char* temporary_cyclic_buffer(void);
extern const char* concatenate_paths(const char *a, const char *b);
diff --git a/programs/pluto/demux.c b/programs/pluto/demux.c
index 3146b3d40..304d790e3 100644
--- a/programs/pluto/demux.c
+++ b/programs/pluto/demux.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: demux.c,v 1.16 2006/10/19 21:07:40 as Exp $
+ * RCSID $Id: demux.c,v 1.17 2007/01/10 00:36:19 as Exp $
*/
/* Ordering Constraints on Payloads
@@ -454,45 +454,81 @@ static const struct state_microcode state_microcode_table[] = {
, P(HASH), LEMPTY, PT(NONE)
, EVENT_NULL, informational },
- /* MODE_CFG_x:
- * Case R0: Responder -> Initiator
- * <- Req(addr=0)
- * Reply(ad=x) ->
- *
- * Case R1: Set(addr=x) ->
- * <- Ack(ok)
- */
+ /* XAUTH state transitions */
+ { STATE_XAUTH_I0, STATE_XAUTH_I1
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_RETRANSMIT, xauth_inI0 },
- { STATE_MODE_CFG_R0, STATE_MODE_CFG_R1
+ { STATE_XAUTH_R1, STATE_XAUTH_R2
, SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
, P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inR0 },
+ , EVENT_RETRANSMIT, xauth_inR1 },
- { STATE_MODE_CFG_R1, STATE_MODE_CFG_R2
- , SMF_ALL_AUTH | SMF_ENCRYPTED
+ { STATE_XAUTH_I1, STATE_XAUTH_I2
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
, P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inR1 },
+ , EVENT_SA_REPLACE, xauth_inI1 },
+
+ { STATE_XAUTH_R2, STATE_XAUTH_R3
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
+ , P(ATTR) | P(HASH), P(VID), PT(NONE)
+ , EVENT_SA_REPLACE, xauth_inR2 },
+
+ { STATE_XAUTH_I2, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
- { STATE_MODE_CFG_R2, STATE_UNDEFINED
+ { STATE_XAUTH_R3, STATE_UNDEFINED
, SMF_ALL_AUTH | SMF_ENCRYPTED
, LEMPTY, LEMPTY, PT(NONE)
, EVENT_NULL, unexpected },
+ /* ModeCfg pull mode state transitions */
+
+ { STATE_MODE_CFG_R0, STATE_MODE_CFG_R1
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_SA_REPLACE, modecfg_inR0 },
+
{ STATE_MODE_CFG_I1, STATE_MODE_CFG_I2
, SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
, P(ATTR) | P(HASH), P(VID), PT(HASH)
, EVENT_SA_REPLACE, modecfg_inI1 },
- { STATE_MODE_CFG_I2, STATE_MODE_CFG_I3
+ { STATE_MODE_CFG_R1, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
+
+ { STATE_MODE_CFG_I2, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
+
+ /* ModeCfg push mode state transitions */
+
+ { STATE_MODE_CFG_I0, STATE_MODE_CFG_I3
, SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
, P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inI2 },
+ , EVENT_SA_REPLACE, modecfg_inI0 },
+
+ { STATE_MODE_CFG_R3, STATE_MODE_CFG_R4
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_SA_REPLACE, modecfg_inR3 },
{ STATE_MODE_CFG_I3, STATE_UNDEFINED
, SMF_ALL_AUTH | SMF_ENCRYPTED
, LEMPTY, LEMPTY, PT(NONE)
, EVENT_NULL, unexpected },
+ { STATE_MODE_CFG_R4, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
+
#undef P
#undef PT
};
@@ -1258,6 +1294,11 @@ process_packet(struct msg_digest **mdp)
{
plog("size (%u) differs from size specified in ISAKMP HDR (%u)"
, (unsigned) pbs_room(&md->packet_pbs), md->hdr.isa_length);
+#ifdef CISCO_QUIRKS
+ if (pbs_room(&md->packet_pbs) - md->hdr.isa_length == 16)
+ plog("Cisco VPN client appends 16 surplus NULL bytes");
+ else
+#endif
return;
}
@@ -1447,11 +1488,6 @@ process_packet(struct msg_digest **mdp)
return;
}
- if (st->st_state == STATE_MODE_CFG_R2) /* Have we just give an IP address to peer? */
- {
- st->st_state = STATE_MAIN_R3; /* ISAKMP is up... */
- }
-
set_cur_state(st);
if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
@@ -1490,7 +1526,7 @@ process_packet(struct msg_digest **mdp)
case ISAKMP_XCHG_MODE_CFG:
if (is_zero_cookie(md->hdr.isa_icookie))
{
- plog("Mode Config message is invalid because"
+ plog("ModeCfg message is invalid because"
" it has an Initiator Cookie of 0");
/* XXX Could send notification back */
return;
@@ -1498,7 +1534,7 @@ process_packet(struct msg_digest **mdp)
if (is_zero_cookie(md->hdr.isa_rcookie))
{
- plog("Mode Config message is invalid because"
+ plog("ModeCfg message is invalid because"
" it has a Responder Cookie of 0");
/* XXX Could send notification back */
return;
@@ -1506,7 +1542,7 @@ process_packet(struct msg_digest **mdp)
if (md->hdr.isa_msgid == 0)
{
- plog("Mode Config message is invalid because"
+ plog("ModeCfg message is invalid because"
" it has a Message ID of 0");
/* XXX Could send notification back */
return;
@@ -1517,7 +1553,9 @@ process_packet(struct msg_digest **mdp)
if (st == NULL)
{
- /* No appropriate Mode Config state.
+ bool has_xauth_policy;
+
+ /* No appropriate ModeCfg state.
* See if we have a Main Mode state.
* ??? what if this is a duplicate of another message?
*/
@@ -1526,7 +1564,7 @@ process_packet(struct msg_digest **mdp)
if (st == NULL)
{
- plog("Mode Config message is for a non-existent (expired?)"
+ plog("ModeCfg message is for a non-existent (expired?)"
" ISAKMP SA");
/* XXX Could send notification back */
return;
@@ -1536,7 +1574,7 @@ process_packet(struct msg_digest **mdp)
if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
{
- loglog(RC_LOG_SERIOUS, "Mode Config message is unacceptable because"
+ loglog(RC_LOG_SERIOUS, "ModeCfg message is unacceptable because"
" it is for an incomplete ISAKMP SA (state=%s)"
, enum_name(&state_names, st->st_state));
/* XXX Could send notification back */
@@ -1565,7 +1603,16 @@ process_packet(struct msg_digest **mdp)
*
*/
- if (st->st_connection->spd.that.modecfg
+ has_xauth_policy = (st->st_connection->policy
+ & (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
+ != LEMPTY;
+
+ if (has_xauth_policy && !st->st_xauth.started
+ && IS_PHASE1(st->st_state))
+ {
+ from_state = STATE_XAUTH_I0;
+ }
+ else if (st->st_connection->spd.that.modecfg
&& IS_PHASE1(st->st_state))
{
from_state = STATE_MODE_CFG_R0;
@@ -1573,12 +1620,12 @@ process_packet(struct msg_digest **mdp)
else if (st->st_connection->spd.this.modecfg
&& IS_PHASE1(st->st_state))
{
- from_state = STATE_MODE_CFG_I2;
+ from_state = STATE_MODE_CFG_I0;
}
else
{
/* XXX check if we are being a mode config server here */
- plog("received MODECFG message when in state %s, and we aren't mode config client"
+ plog("received ModeCfg message when in state %s, and we aren't mode config client"
, enum_name(&state_names, st->st_state));
return;
}
@@ -1588,7 +1635,6 @@ process_packet(struct msg_digest **mdp)
set_cur_state(st);
from_state = st->st_state;
}
-
break;
#ifdef NOTYET
@@ -1630,7 +1676,23 @@ process_packet(struct msg_digest **mdp)
if (st != NULL)
{
- while (!LHAS(smc->flags, st->st_oakley.auth))
+ u_int16_t auth;
+
+ switch (st->st_oakley.auth)
+ {
+ case XAUTHInitPreShared:
+ case XAUTHRespPreShared:
+ auth = OAKLEY_PRESHARED_KEY;
+ break;
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
+ auth = OAKLEY_RSA_SIG;
+ break;
+ default:
+ auth = st->st_oakley.auth;
+ }
+
+ while (!LHAS(smc->flags, auth))
{
smc++;
passert(smc->state == from_state);
@@ -2046,6 +2108,8 @@ process_packet(struct msg_digest **mdp)
void
complete_state_transition(struct msg_digest **mdp, stf_status result)
{
+ bool has_xauth_policy;
+ bool is_xauth_server;
struct msg_digest *md = *mdp;
const struct state_microcode *smc = md->smc;
enum state_kind from_state = md->from_state;
@@ -2263,7 +2327,7 @@ complete_state_transition(struct msg_digest **mdp, stf_status result)
}
/* advance b to end of string */
b = b + strlen(b);
-
+
if (st->st_ah.present)
{
snprintf(b, sizeof(sadetails)-(b-sadetails)-1
@@ -2276,7 +2340,7 @@ complete_state_transition(struct msg_digest **mdp, stf_status result)
}
/* advance b to end of string */
b = b + strlen(b);
-
+
if (st->st_ipcomp.present)
{
snprintf(b, sizeof(sadetails)-(b-sadetails)-1
@@ -2319,7 +2383,7 @@ complete_state_transition(struct msg_digest **mdp, stf_status result)
}
if (IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- || IS_IPSEC_SA_ESTABLISHED(st->st_state))
+ || IS_IPSEC_SA_ESTABLISHED(st->st_state))
{
/* log our success */
plog("%s%s", story, sadetails);
@@ -2333,6 +2397,36 @@ complete_state_transition(struct msg_digest **mdp, stf_status result)
, story, sadetails);
}
+ has_xauth_policy = (st->st_connection->policy
+ & (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
+ != LEMPTY;
+ is_xauth_server = (st->st_connection->policy
+ & POLICY_XAUTH_SERVER)
+ != LEMPTY;
+
+ /* Should we start XAUTH as a server */
+ if (has_xauth_policy && is_xauth_server
+ && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
+ && !st->st_xauth.started)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("starting XAUTH server")
+ )
+ xauth_send_request(st);
+ break;
+ }
+
+ /* Wait for XAUTH request from server */
+ if (has_xauth_policy && !is_xauth_server
+ && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
+ && !st->st_xauth.started)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("waiting for XAUTH request from server")
+ )
+ break;
+ }
+
/* Should we start ModeConfig as a client? */
if (st->st_connection->spd.this.modecfg
&& IS_ISAKMP_SA_ESTABLISHED(st->st_state)
@@ -2384,7 +2478,7 @@ complete_state_transition(struct msg_digest **mdp, stf_status result)
}
if (IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- || IS_IPSEC_SA_ESTABLISHED(st->st_state))
+ || IS_IPSEC_SA_ESTABLISHED(st->st_state))
release_whack(st);
break;
diff --git a/programs/pluto/demux.h b/programs/pluto/demux.h
index 7adac44f3..dc38e4cfc 100644
--- a/programs/pluto/demux.h
+++ b/programs/pluto/demux.h
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: demux.h,v 1.4 2004/07/22 22:57:25 as Exp $
+ * RCSID $Id: demux.h,v 1.5 2007/01/11 05:44:02 as Exp $
*/
#include "packet.h"
@@ -69,7 +69,7 @@ struct msg_digest {
bool dpd; /* peer supports RFC 3706 DPD */
bool openpgp; /* peer supports OpenPGP certificates */
-# define PAYLIMIT 20
+# define PAYLIMIT 40
struct payload_digest
digest[PAYLIMIT],
*digest_roof,
diff --git a/programs/pluto/ike_alg.c b/programs/pluto/ike_alg.c
index 47393079a..456ca3a96 100644
--- a/programs/pluto/ike_alg.c
+++ b/programs/pluto/ike_alg.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: ike_alg.c,v 1.6 2004/09/17 21:29:50 as Exp $
+ * RCSID $Id: ike_alg.c,v 1.7 2007/01/10 00:36:19 as Exp $
*/
#include <stdio.h>
@@ -233,6 +233,7 @@ ike_alg_db_new(struct alg_info_ike *ai , lset_t policy)
struct ike_info *ike_info;
u_int ealg, halg, modp, eklen = 0;
struct encrypt_desc *enc_desc;
+ bool is_xauth_server;
int i;
if (!ai)
@@ -298,11 +299,37 @@ ike_alg_db_new(struct alg_info_ike *ai , lset_t policy)
db_trans_add(db_ctx, KEY_IKE);
db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
- if (ike_info->ike_eklen)
- db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, ike_info->ike_eklen);
+ if (eklen)
+ db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
}
+
+ is_xauth_server = (policy & POLICY_XAUTH_SERVER) != LEMPTY;
+
+ if (policy & POLICY_XAUTH_RSASIG)
+ {
+ db_trans_add(db_ctx, KEY_IKE);
+ db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
+ db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
+ if (eklen)
+ db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
+ db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
+ , is_xauth_server ? XAUTHRespRSA : XAUTHInitRSA);
+ db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
+ }
+
+ if (policy & POLICY_XAUTH_PSK)
+ {
+ db_trans_add(db_ctx, KEY_IKE);
+ db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
+ db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
+ if (eklen)
+ db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
+ db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
+ , is_xauth_server ? XAUTHRespPreShared : XAUTHInitPreShared);
+ db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
+ }
}
fail:
return db_ctx;
diff --git a/programs/pluto/ipsec_doi.c b/programs/pluto/ipsec_doi.c
index fe5c846a7..e627f98b2 100644
--- a/programs/pluto/ipsec_doi.c
+++ b/programs/pluto/ipsec_doi.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: ipsec_doi.c,v 1.39 2006/04/22 21:59:20 as Exp $
+ * RCSID $Id: ipsec_doi.c,v 1.42 2007/01/10 00:36:19 as Exp $
*/
#include <stdio.h>
@@ -84,13 +84,13 @@
#endif /* !VENDORID */
/*
- * are we sending an XAUTH VID (Cisco Mode Config Interoperability)?
+ * are we sending a Cisco Unity VID?
*/
-#ifdef XAUTH_VID
-#define SEND_XAUTH_VID 1
-#else /* !XAUTH_VID */
-#define SEND_XAUTH_VID 0
-#endif /* !XAUTH_VID */
+#ifdef CISCO_QUIRKS
+#define SEND_CISCO_UNITY_VID 1
+#else /* !CISCO_QUIRKS */
+#define SEND_CISCO_UNITY_VID 0
+#endif /* !CISCO_QUIRKS */
/* MAGIC: perform f, a function that returns notification_t
* and return from the ENCLOSING stf_status returning function if it fails.
@@ -896,10 +896,12 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
/* determine how many Vendor ID payloads we will be sending */
if (SEND_PLUTO_VID)
vids_to_send++;
- if (SEND_XAUTH_VID)
+ if (SEND_CISCO_UNITY_VID)
vids_to_send++;
if (c->spd.this.cert.type == CERT_PGP)
vids_to_send++;
+ /* always send XAUTH Vendor ID */
+ vids_to_send++;
/* always send DPD Vendor ID */
vids_to_send++;
#ifdef NAT_TRAVERSAL
@@ -946,8 +948,8 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
u_char *sa_start = rbody.cur;
lset_t auth_policy = policy & POLICY_ID_AUTH_MASK;
- if (!out_sa(&rbody, &oakley_sadb[auth_policy >> POLICY_ISAKMP_SHIFT]
- , st, TRUE, vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
+ if (!out_sa(&rbody, &oakley_sadb, st, TRUE
+ , vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
{
reset_cur_state();
return STF_INTERNAL_ERROR;
@@ -970,17 +972,16 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
}
}
- /* if enabled send XAUTH Vendor ID */
- if (SEND_XAUTH_VID)
+ /* if enabled send Cisco Unity Vendor ID */
+ if (SEND_CISCO_UNITY_VID)
{
if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_MISC_XAUTH))
+ , &rbody, VID_CISCO_UNITY))
{
reset_cur_state();
return STF_INTERNAL_ERROR;
}
}
-
/* if we have an OpenPGP certificate we assume an
* OpenPGP peer and have to send the Vendor ID
*/
@@ -994,6 +995,14 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
}
}
+ /* Announce our ability to do eXtended AUTHentication to the peer */
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &rbody, VID_MISC_XAUTH))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
+
/* Announce our ability to do Dead Peer Detection to the peer */
{
if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
@@ -1199,11 +1208,15 @@ generate_skeyids_iv(struct state *st)
switch (st->st_oakley.auth)
{
case OAKLEY_PRESHARED_KEY:
+ case XAUTHInitPreShared:
+ case XAUTHRespPreShared:
if (!skeyid_preshared(st))
return FALSE;
break;
case OAKLEY_RSA_SIG:
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
if (!skeyid_digisig(st))
return FALSE;
break;
@@ -2972,8 +2985,7 @@ main_inI1_outR1(struct msg_digest *md)
{
struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
struct state *st;
- struct connection *c = find_host_connection(&md->iface->addr, pluto_port
- , &md->sender, md->sender_port, LEMPTY);
+ struct connection *c;
struct isakmp_proposal proposal;
pb_stream proposal_pbs;
pb_stream r_sa_pbs;
@@ -2981,14 +2993,28 @@ main_inI1_outR1(struct msg_digest *md)
lset_t policy = LEMPTY;
int vids_to_send = 0;
+ /* We preparse the peer's proposal in order to determine
+ * the requested authentication policy (RSA or PSK)
+ */
RETURN_STF_FAILURE(preparse_isakmp_sa_body(&sa_pd->payload.sa
, &sa_pd->pbs, &ipsecdoisit, &proposal_pbs, &proposal));
+ backup_pbs(&proposal_pbs);
+ RETURN_STF_FAILURE(parse_isakmp_policy(&proposal_pbs
+ , proposal.isap_notrans, &policy));
+ restore_pbs(&proposal_pbs);
+
+ /* We are only considering candidate connections that match
+ * the requested authentication policy (RSA or PSK)
+ */
+ c = find_host_connection(&md->iface->addr, pluto_port
+ , &md->sender, md->sender_port, policy);
+
#ifdef NAT_TRAVERSAL
if (c == NULL && md->iface->ike_float)
{
c = find_host_connection(&md->iface->addr, NAT_T_IKE_FLOAT_PORT
- , &md->sender, md->sender_port, LEMPTY);
+ , &md->sender, md->sender_port, policy);
}
#endif
@@ -3007,11 +3033,6 @@ main_inI1_outR1(struct msg_digest *md)
{
struct connection *d;
- backup_pbs(&proposal_pbs);
- RETURN_STF_FAILURE(parse_isakmp_policy(&proposal_pbs
- , proposal.isap_notrans, &policy));
- restore_pbs(&proposal_pbs);
-
d = find_host_connection(&md->iface->addr
, pluto_port, (ip_address*)NULL, md->sender_port, policy);
@@ -3071,6 +3092,13 @@ main_inI1_outR1(struct msg_digest *md)
NULL);
}
}
+ else if (c->kind == CK_TEMPLATE)
+ {
+ /* Create an instance
+ * This is a rare case: wildcard peer ID but static peer IP address
+ */
+ c = rw_instantiate(c, &md->sender, md->sender_port, NULL, &c->spd.that.id);
+ }
/* Set up state */
md->st = st = new_state();
@@ -3109,10 +3137,12 @@ main_inI1_outR1(struct msg_digest *md)
/* determine how many Vendor ID payloads we will be sending */
if (SEND_PLUTO_VID)
vids_to_send++;
- if (SEND_XAUTH_VID)
+ if (SEND_CISCO_UNITY_VID)
vids_to_send++;
if (md->openpgp)
vids_to_send++;
+ /* always send XAUTH Vendor ID */
+ vids_to_send++;
/* always send DPD Vendor ID */
vids_to_send++;
#ifdef NAT_TRAVERSAL
@@ -3146,7 +3176,7 @@ main_inI1_outR1(struct msg_digest *md)
/* SA body in and out */
RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit, &proposal_pbs
- ,&proposal, &r_sa_pbs, st));
+ ,&proposal, &r_sa_pbs, st, FALSE));
/* if enabled send Pluto Vendor ID */
if (SEND_PLUTO_VID)
@@ -3158,11 +3188,11 @@ main_inI1_outR1(struct msg_digest *md)
}
}
- /* if enabled send XAUTH Vendor ID */
- if (SEND_XAUTH_VID)
+ /* if enabled send Cisco Unity Vendor ID */
+ if (SEND_CISCO_UNITY_VID)
{
if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_MISC_XAUTH))
+ , &md->rbody, VID_CISCO_UNITY))
{
return STF_INTERNAL_ERROR;
}
@@ -3180,13 +3210,18 @@ main_inI1_outR1(struct msg_digest *md)
}
}
+ /* Announce our ability to do eXtended AUTHentication to the peer */
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &md->rbody, VID_MISC_XAUTH))
+ {
+ return STF_INTERNAL_ERROR;
+ }
+
/* Announce our ability to do Dead Peer Detection to the peer */
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &md->rbody, VID_MISC_DPD))
{
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_MISC_DPD))
- {
- return STF_INTERNAL_ERROR;
- }
+ return STF_INTERNAL_ERROR;
}
#ifdef NAT_TRAVERSAL
@@ -3249,7 +3284,7 @@ main_inR1_outI2(struct msg_digest *md)
RETURN_STF_FAILURE(BAD_PROPOSAL_SYNTAX);
}
RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit
- , &proposal_pbs, &proposal, NULL, st));
+ , &proposal_pbs, &proposal, NULL, st, TRUE));
}
#ifdef NAT_TRAVERSAL
@@ -3342,9 +3377,11 @@ main_inI2_outR2(struct msg_digest *md)
pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
/* send CR if auth is RSA and no preloaded RSA public key exists*/
- bool send_cr = !no_cr_send && (st->st_oakley.auth == OAKLEY_RSA_SIG) &&
- !has_preloaded_public_key(st);
-
+ bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
+ || st->st_oakley.auth == XAUTHInitRSA
+ || st->st_oakley.auth == XAUTHRespRSA;
+ bool send_cr = !no_cr_send && RSA_auth && !has_preloaded_public_key(st);
+
u_int8_t np = ISAKMP_NEXT_NONE;
/* KE in */
@@ -3487,14 +3524,18 @@ main_inR2_outI3(struct msg_digest *md)
{
struct state *const st = md->st;
pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
- int auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY
- ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG;
pb_stream id_pbs; /* ID Payload; also used for hash calculation */
certpolicy_t cert_policy = st->st_connection->spd.this.sendcert;
cert_t mycert = st->st_connection->spd.this.cert;
bool requested, send_cert, send_cr;
+ bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
+ || st->st_oakley.auth == XAUTHInitRSA
+ || st->st_oakley.auth == XAUTHRespRSA;
+
+ int auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
+
/* KE in */
RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", st->st_oakley.group, keyex_pbs));
@@ -3516,8 +3557,7 @@ main_inR2_outI3(struct msg_digest *md)
*/
requested = cert_policy == CERT_SEND_IF_ASKED
&& st->st_connection->got_certrequest;
- send_cert = st->st_oakley.auth == OAKLEY_RSA_SIG
- && mycert.type != CERT_NONE
+ send_cert = RSA_auth && mycert.type != CERT_NONE
&& (cert_policy == CERT_ALWAYS_SEND || requested);
/* send certificate request if we don't have a preloaded RSA public key */
@@ -3560,7 +3600,7 @@ main_inR2_outI3(struct msg_digest *md)
}
/* CERT out */
- if ( st->st_oakley.auth == OAKLEY_RSA_SIG)
+ if (RSA_auth)
{
DBG(DBG_CONTROL,
DBG_log("our certificate policy is %s"
@@ -3716,6 +3756,8 @@ main_id_and_auth(struct msg_digest *md
switch (st->st_oakley.auth)
{
case OAKLEY_PRESHARED_KEY:
+ case XAUTHInitPreShared:
+ case XAUTHRespPreShared:
{
pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs;
@@ -3732,6 +3774,8 @@ main_id_and_auth(struct msg_digest *md
break;
case OAKLEY_RSA_SIG:
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
r = RSA_check_signature(&peer, st, hash_val, hash_len
, &md->chain[ISAKMP_NEXT_SIG]->pbs
#ifdef USE_KEYRR
@@ -3909,6 +3953,7 @@ main_inI3_outR3_tail(struct msg_digest *md
pb_stream r_id_pbs; /* ID Payload; also used for hash calculation */
certpolicy_t cert_policy;
cert_t mycert;
+ bool RSA_auth;
bool send_cert;
bool requested;
@@ -3931,7 +3976,10 @@ main_inI3_outR3_tail(struct msg_digest *md
mycert = st->st_connection->spd.this.cert;
requested = cert_policy == CERT_SEND_IF_ASKED
&& st->st_connection->got_certrequest;
- send_cert = st->st_oakley.auth == OAKLEY_RSA_SIG
+ RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
+ || st->st_oakley.auth == XAUTHInitRSA
+ || st->st_oakley.auth == XAUTHRespRSA;
+ send_cert = RSA_auth
&& mycert.type != CERT_NONE
&& (cert_policy == CERT_ALWAYS_SEND || requested);
@@ -3949,8 +3997,7 @@ main_inI3_outR3_tail(struct msg_digest *md
*/
echo_hdr(md, TRUE, ISAKMP_NEXT_ID);
- auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY
- ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG;
+ auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
/* IDir out */
{
@@ -3969,7 +4016,7 @@ main_inI3_outR3_tail(struct msg_digest *md
}
/* CERT out */
- if (st->st_oakley.auth == OAKLEY_RSA_SIG)
+ if (RSA_auth)
{
DBG(DBG_CONTROL,
DBG_log("our certificate policy is %s"
diff --git a/programs/pluto/keys.c b/programs/pluto/keys.c
index 55d13282c..39726f424 100644
--- a/programs/pluto/keys.c
+++ b/programs/pluto/keys.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: keys.c,v 1.25 2006/07/06 19:23:28 as Exp $
+ * RCSID $Id: keys.c,v 1.26 2007/01/10 00:36:19 as Exp $
*/
#include <stddef.h>
@@ -54,6 +54,7 @@
#include "whack.h" /* for RC_LOG_SERIOUS */
#include "timer.h"
#include "fetch.h"
+#include "xauth.h"
const char *shared_secrets_file = SHARED_SECRETS_FILE;
@@ -72,6 +73,7 @@ struct secret {
union {
chunk_t preshared_secret;
RSA_private_key_t RSA_private_key;
+ xauth_t xauth_secret;
smartcard_t *smartcard;
} u;
secret_t *next;
@@ -96,11 +98,11 @@ allocate_RSA_public_key(const cert_t cert)
default:
plog("RSA public key allocation error");
}
- init_RSA_public_key(&pk->u.rsa, e, n);
-#ifdef DEBUG
- DBG(DBG_PRIVATE, RSA_show_public_key(&pk->u.rsa));
-#endif
+ init_RSA_public_key(&pk->u.rsa, e, n);
+ DBG(DBG_RAW,
+ RSA_show_public_key(&pk->u.rsa)
+ )
pk->alg = PUBKEY_ALG_RSA;
pk->id = empty_id;
@@ -182,14 +184,14 @@ get_secret(const struct connection *c, enum PrivateKeyKind kind, bool asym)
}
#ifdef NAT_TRAVERSAL
else if (kind == PPK_PSK
- && (c->policy & POLICY_PSK)
+ && (c->policy & (POLICY_PSK | POLICY_XAUTH_PSK))
&& ((c->kind == CK_TEMPLATE && c->spd.that.id.kind == ID_NONE) ||
(c->kind == CK_INSTANCE && id_is_ipaddr(&c->spd.that.id))))
{
- /* roadwarrior: replace him with 0.0.0.0 */
- rw_id.kind = ID_IPV4_ADDR;
- happy(anyaddr(addrtypeof(&c->spd.that.host_addr), &rw_id.ip_addr));
- his_id = &rw_id;
+ /* roadwarrior: replace him with 0.0.0.0 */
+ rw_id.kind = ID_IPV4_ADDR;
+ happy(anyaddr(addrtypeof(&c->spd.that.host_addr), &rw_id.ip_addr));
+ his_id = &rw_id;
}
#endif
@@ -295,14 +297,12 @@ get_preshared_secret(const struct connection *c)
{
const secret_t *s = get_secret(c, PPK_PSK, FALSE);
-#ifdef DEBUG
DBG(DBG_PRIVATE,
if (s == NULL)
DBG_log("no Preshared Key Found");
else
DBG_dump_chunk("Preshared Key", s->u.preshared_secret);
- );
-#endif
+ )
return s == NULL? NULL : &s->u.preshared_secret;
}
@@ -417,7 +417,7 @@ process_psk_secret(chunk_t *psk)
}
else
{
- char buf[RSA_MAX_ENCODING_BYTES]; /* limit on size of binary representation of key */
+ char buf[BUF_LEN]; /* limit on size of binary representation of key */
size_t sz;
ugh = ttodatav(tok, flp->cur - tok, 0, buf, sizeof(buf), &sz
@@ -586,6 +586,119 @@ process_rsa_keyfile(RSA_private_key_t *rsak, int whackfd)
}
/*
+ * process xauth secret read from ipsec.secrets
+ */
+static err_t
+process_xauth(secret_t *s)
+{
+ chunk_t user_name;
+
+ s->kind = PPK_XAUTH;
+
+ if (!shift())
+ return "missing xauth user name";
+ if (*tok == '"' || *tok == '\'') /* quoted user name */
+ {
+ user_name.ptr = tok + 1;
+ user_name.len = flp->cur - tok - 2;
+ }
+ else
+ {
+ user_name.ptr = tok;
+ user_name.len = flp->cur - tok;
+ }
+ plog(" loaded xauth credentials of user '%.*s'"
+ , user_name.len
+ , user_name.ptr);
+ clonetochunk(s->u.xauth_secret.user_name
+ , user_name.ptr, user_name.len, "xauth user name");
+
+ if (!shift())
+ return "missing xauth user password";
+ return process_psk_secret(&s->u.xauth_secret.user_password);
+}
+
+/* get XAUTH secret from chained secrets lists
+ * only one entry is currently supported
+ */
+static bool
+xauth_get_secret(xauth_t *xauth_secret)
+{
+ secret_t *s;
+ bool found = FALSE;
+
+ for (s = secrets; s != NULL; s = s->next)
+ {
+ if (s->kind == PPK_XAUTH)
+ {
+ if (found)
+ {
+ plog("found multiple xauth secrets - first selected");
+ }
+ else
+ {
+ found = TRUE;
+ *xauth_secret = s->u.xauth_secret;
+ }
+ }
+ }
+ return found;
+}
+
+/*
+ * find a matching secret
+ */
+static bool
+xauth_verify_secret(const xauth_t *xauth_secret)
+{
+ bool found = FALSE;
+ secret_t *s;
+
+ for (s = secrets; s != NULL; s = s->next)
+ {
+ if (s->kind == PPK_XAUTH)
+ {
+ if (!same_chunk(xauth_secret->user_name, s->u.xauth_secret.user_name))
+ continue;
+ found = TRUE;
+ if (same_chunk(xauth_secret->user_password, s->u.xauth_secret.user_password))
+ return TRUE;
+ }
+ }
+ plog("xauth user '%.*s' %s"
+ , xauth_secret->user_name.len, xauth_secret->user_name.ptr
+ , found? "sent wrong password":"not found");
+ return FALSE;
+}
+
+/*
+ * the global xauth_module struct is defined here
+ */
+xauth_module_t xauth_module;
+
+/*
+ * assign the default xauth functions to any null function pointers
+ */
+void
+xauth_defaults(void)
+{
+ if (xauth_module.get_secret == NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("xauth module: using default get_secret() function")
+ )
+ xauth_module.get_secret = xauth_get_secret;
+ }
+ if (xauth_module.verify_secret == NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("xauth module: using default verify_secret() function")
+ )
+ xauth_module.verify_secret = xauth_verify_secret;
+ }
+};
+
+/*
* process pin read from ipsec.secrets or prompted for it using whack
*/
static err_t
@@ -696,6 +809,10 @@ process_secret(secret_t *s, int whackfd)
ugh = process_rsa_keyfile(&s->u.RSA_private_key, whackfd);
}
}
+ else if (tokeqword("xauth"))
+ {
+ ugh = process_xauth(s);
+ }
else if (tokeqword("pin"))
{
ugh = process_pin(s, whackfd);
@@ -925,7 +1042,7 @@ void
free_preshared_secrets(void)
{
lock_certs_and_keys("free_preshared_secrets");
-
+
if (secrets != NULL)
{
secret_t *s, *ns;
@@ -951,6 +1068,10 @@ free_preshared_secrets(void)
case PPK_RSA:
free_RSA_private_content(&s->u.RSA_private_key);
break;
+ case PPK_XAUTH:
+ pfree(s->u.xauth_secret.user_name.ptr);
+ pfree(s->u.xauth_secret.user_password.ptr);
+ break;
case PPK_PIN:
scx_release(s->u.smartcard);
break;
@@ -961,7 +1082,7 @@ free_preshared_secrets(void)
}
secrets = NULL;
}
-
+
unlock_certs_and_keys("free_preshard_secrets");
}
@@ -1105,14 +1226,11 @@ unpack_RSA_public_key(RSA_public_key_t *rsa, const chunk_t *pubkey)
return RSA_MAX_OCTETS_UGH;
init_RSA_public_key(rsa, exp, mod);
-
-#ifdef DEBUG
- DBG(DBG_PRIVATE, RSA_show_public_key(rsa));
-#endif
-
-
rsa->k = mpz_sizeinbase(&rsa->n, 2); /* size in bits, for a start */
rsa->k = (rsa->k + BITS_PER_BYTE - 1) / BITS_PER_BYTE; /* now octets */
+ DBG(DBG_RAW,
+ RSA_show_public_key(rsa)
+ )
if (rsa->k != mod.len)
{
diff --git a/programs/pluto/keys.h b/programs/pluto/keys.h
index d47d8b0a2..2f6216b93 100644
--- a/programs/pluto/keys.h
+++ b/programs/pluto/keys.h
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: keys.h,v 1.7 2006/01/26 20:10:34 as Exp $
+ * RCSID $Id: keys.h,v 1.8 2007/01/10 00:36:19 as Exp $
*/
#ifndef _KEYS_H
@@ -31,15 +31,19 @@ const char *shared_secrets_file;
extern void load_preshared_secrets(int whackfd);
extern void free_preshared_secrets(void);
-struct state; /* forward declaration */
-
enum PrivateKeyKind {
PPK_PSK,
/* PPK_DSS, */ /* not implemented */
PPK_RSA,
+ PPK_XAUTH,
PPK_PIN
};
+extern void xauth_defaults(void);
+
+/* forward declaration */
+struct connection;
+
extern const chunk_t *get_preshared_secret(const struct connection *c);
extern err_t unpack_RSA_public_key(RSA_public_key_t *rsa, const chunk_t *pubkey);
extern const RSA_private_key_t *get_RSA_private_key(const struct connection *c);
diff --git a/programs/pluto/modecfg.c b/programs/pluto/modecfg.c
index ec334aaf5..01bab8c6e 100644
--- a/programs/pluto/modecfg.c
+++ b/programs/pluto/modecfg.c
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: modecfg.c,v 1.9 2006/10/21 17:11:13 as Exp $
+ * RCSID $Id: modecfg.c,v 1.10 2007/01/10 00:36:19 as Exp $
*
* This code originally written by Colubris Networks, Inc.
* Extraction of patch and porting to 1.99 codebases by Xelerance Corporation
@@ -39,6 +39,9 @@
#include "crypto.h"
#include "modecfg.h"
#include "whack.h"
+#include "xauth.h"
+
+#define MAX_XAUTH_TRIES 3
#define SUPPORTED_ATTR_SET ( LELEM(INTERNAL_IP4_ADDRESS) \
| LELEM(INTERNAL_IP4_NETMASK) \
@@ -53,10 +56,17 @@ typedef struct internal_addr internal_addr_t;
struct internal_addr
{
- lset_t attr_set;
- ip_address ipaddr;
- ip_address dns[2];
- ip_address wins[2];
+ lset_t attr_set;
+
+ /* ModeCfg variables */
+ ip_address ipaddr;
+ ip_address dns[2];
+ ip_address wins[2];
+
+ /* XAUTH variables */
+ u_int16_t xauth_type;
+ xauth_t xauth_secret;
+ bool xauth_status;
};
/*
@@ -66,6 +76,10 @@ static void
init_internal_addr(internal_addr_t *ia)
{
ia->attr_set = LEMPTY;
+ ia->xauth_secret.user_name = empty_chunk;
+ ia->xauth_secret.user_password = empty_chunk;
+ ia->xauth_status = FALSE;
+
anyaddr(AF_INET, &ia->ipaddr);
anyaddr(AF_INET, &ia->dns[0]);
anyaddr(AF_INET, &ia->dns[1]);
@@ -218,7 +232,20 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
u_int len;
/* ISAKMP attr out */
- attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TLV;
+ if (attr_type == XAUTH_TYPE)
+ {
+ attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
+ attr.isaat_lv = ia->xauth_type;
+ }
+ else if (attr_type == XAUTH_STATUS)
+ {
+ attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
+ attr.isaat_lv = ia->xauth_status;
+ }
+ else
+ {
+ attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TLV;
+ }
out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, &attrval);
switch (attr_type)
@@ -288,14 +315,34 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
case INTERNAL_IP4_NBNS:
if (!isanyaddr(&ia->wins[wins_idx]))
{
- len = addrbytesptr(&ia->wins[wins_idx++], &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_wins");
+ len = addrbytesptr(&ia->wins[wins_idx++], &byte_ptr);
+ out_raw(byte_ptr, len, &attrval, "IP4_wins");
}
if (wins_idx < 2 && !isanyaddr(&ia->wins[wins_idx]))
{
dont_advance = TRUE;
}
- break;
+ break;
+ case XAUTH_TYPE:
+ break;
+ case XAUTH_USER_NAME:
+ if (ia->xauth_secret.user_name.ptr != NULL)
+ {
+ out_raw(ia->xauth_secret.user_name.ptr
+ , ia->xauth_secret.user_name.len
+ , &attrval, "xauth_user_name");
+ }
+ break;
+ case XAUTH_USER_PASSWORD:
+ if (ia->xauth_secret.user_password.ptr != NULL)
+ {
+ out_raw(ia->xauth_secret.user_password.ptr
+ , ia->xauth_secret.user_password.len
+ , &attrval, "xauth_user_password");
+ }
+ break;
+ case XAUTH_STATUS:
+ break;
default:
plog("attempt to send unsupported mode cfg attribute %s."
, enum_show(&modecfg_attr_names, attr_type));
@@ -306,13 +353,17 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
if (!dont_advance)
{
attr_type++;
+ if (attr_type == MODECFG_ROOF)
+ {
+ attr_type = XAUTH_BASE;
+ }
attr_set >>= 1;
}
}
close_message(&strattr);
}
- modecfg_hash(r_hashval, r_hash_start, rbody->cur,st);
+ modecfg_hash(r_hashval, r_hash_start, rbody->cur, st);
close_message(rbody);
encrypt_message(rbody, st);
return STF_OK;
@@ -361,6 +412,7 @@ modecfg_send_msg(struct state *st, int isama_type, internal_addr_t *ia)
, 0 /* XXX isama_id */
);
+ freeanychunk(st->st_tpacket);
clonetochunk(st->st_tpacket, msg.start, pbs_offset(&msg), "ModeCfg msg");
/* Transmit */
@@ -371,43 +423,10 @@ modecfg_send_msg(struct state *st, int isama_type, internal_addr_t *ia)
delete_event(st);
event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
}
- st->st_modecfg.started = TRUE;
return STF_OK;
}
/*
- * Send ModeCfg request message from client to server in pull mode
- */
-stf_status
-modecfg_send_request(struct state *st)
-{
- internal_addr_t ia;
-
- init_internal_addr(&ia);
- ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS)
- | LELEM(INTERNAL_IP4_NETMASK);
-
- plog("sending ModeCfg request");
- st->st_state = STATE_MODE_CFG_I1;
- return modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
-}
-
-/*
- * Send ModeCfg set message from server to client in push mode
- */
-stf_status
-modecfg_send_set(struct state *st)
-{
- internal_addr_t ia;
-
- get_internal_addr(st->st_connection, &ia);
-
- plog("sending ModeCfg set");
- st->st_state = STATE_MODE_CFG_R1;
- return modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
-}
-
-/*
* Parse a ModeCfg attribute payload
*/
static stf_status
@@ -442,6 +461,22 @@ modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia)
case INTERNAL_IP4_NBNS:
ia->attr_set |= LELEM(attr_type);
break;
+ case XAUTH_TYPE:
+ ia->xauth_type = attr.isaat_lv;
+ ia->attr_set |= LELEM(attr_type - XAUTH_BASE + MODECFG_ROOF);
+ break;
+ case XAUTH_USER_NAME:
+ setchunk(ia->xauth_secret.user_name, strattr.cur, attr_len);
+ ia->attr_set |= LELEM(attr_type - XAUTH_BASE + MODECFG_ROOF);
+ break;
+ case XAUTH_USER_PASSWORD:
+ setchunk(ia->xauth_secret.user_password, strattr.cur, attr_len);
+ ia->attr_set |= LELEM(attr_type - XAUTH_BASE + MODECFG_ROOF);
+ break;
+ case XAUTH_STATUS:
+ ia->xauth_status = attr.isaat_lv;
+ ia->attr_set |= LELEM(attr_type - XAUTH_BASE + MODECFG_ROOF);
+ break;
default:
plog("unsupported ModeCfg attribute %s received."
, enum_show(&modecfg_attr_names, attr_type));
@@ -483,7 +518,7 @@ modecfg_parse_msg(struct msg_digest *md, int isama_type, u_int16_t *isama_id
stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
if (stat == STF_OK)
{
- /* retrun with a valid set of attributes */
+ /* return with a valid set of attributes */
*ia = ia_candidate;
return STF_OK;
}
@@ -502,6 +537,27 @@ modecfg_parse_msg(struct msg_digest *md, int isama_type, u_int16_t *isama_id
return STF_IGNORE;
}
+/*
+ * Send ModeCfg request message from client to server in pull mode
+ */
+stf_status
+modecfg_send_request(struct state *st)
+{
+ stf_status stat;
+ internal_addr_t ia;
+
+ init_internal_addr(&ia);
+ ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS)
+ | LELEM(INTERNAL_IP4_NETMASK);
+
+ plog("sending ModeCfg request");
+ st->st_state = STATE_MODE_CFG_I1;
+ stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
+ if (stat == STF_OK)
+ st->st_modecfg.started = TRUE;
+ return stat;
+}
+
/* STATE_MODE_CFG_R0:
* HDR*, HASH, ATTR(REQ=IP) --> HDR*, HASH, ATTR(REPLY=IP)
*
@@ -513,37 +569,118 @@ modecfg_inR0(struct msg_digest *md)
struct state *const st = md->st;
u_int16_t isama_id;
internal_addr_t ia;
- stf_status stat;
+ stf_status stat, stat_build;
stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
if (stat != STF_OK)
return stat;
+
+ get_internal_addr(st->st_connection, &ia);
+
+ plog("sending ModeCfg reply");
+
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_REPLY
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ return stat_build;
+
+ st->st_msgid = 0;
+ return STF_OK;
+}
+
+/* STATE_MODE_CFG_I1:
+ * HDR*, HASH, ATTR(REPLY=IP)
+ *
+ * used in ModeCfg pull mode, on the client (initiator)
+ */
+stf_status
+modecfg_inI1(struct msg_digest *md)
+{
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat;
+
+ plog("parsing ModeCfg reply");
+
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
+ if (stat != STF_OK)
+ return stat;
+
+ st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
+ st->st_msgid = 0;
+ return STF_OK;
+}
+
+
+/*
+ * Send ModeCfg set message from server to client in push mode
+ */
+stf_status
+modecfg_send_set(struct state *st)
+{
+ stf_status stat;
+ internal_addr_t ia;
get_internal_addr(st->st_connection, &ia);
- /* build ISAKMP_CFG_REPLY */
- stat = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_REPLY
- , &ia
- , isama_id);
+ plog("sending ModeCfg set");
+ st->st_state = STATE_MODE_CFG_R3;
+ stat = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
+ if (stat == STF_OK)
+ st->st_modecfg.started = TRUE;
+ return stat;
+}
+
+/* STATE_MODE_CFG_I0:
+ * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK)
+ *
+ * used in ModeCfg push mode, on the client (initiator).
+ */
+stf_status
+modecfg_inI0(struct msg_digest *md)
+{
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ lset_t attr_set;
+ stf_status stat, stat_build;
+
+ plog("parsing ModeCfg set");
+
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
if (stat != STF_OK)
- {
- /* notification payload - not exactly the right choice, but okay */
- md->note = ATTRIBUTES_NOT_SUPPORTED;
return stat;
- }
+
+ st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
+
+ /* prepare ModeCfg ack which sends zero length attributes */
+ attr_set = ia.attr_set;
+ init_internal_addr(&ia);
+ ia.attr_set = attr_set & SUPPORTED_ATTR_SET;
+
+ plog("sending ModeCfg ack");
+
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_ACK
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ return stat_build;
st->st_msgid = 0;
return STF_OK;
}
-/* STATE_MODE_CFG_R1:
+/* STATE_MODE_CFG_R3:
* HDR*, HASH, ATTR(ACK,OK)
*
* used in ModeCfg push mode, on the server (responder)
*/
stf_status
-modecfg_inR1(struct msg_digest *md)
+modecfg_inR3(struct msg_digest *md)
{
struct state *const st = md->st;
u_int16_t isama_id;
@@ -560,61 +697,211 @@ modecfg_inR1(struct msg_digest *md)
return STF_OK;
}
-/* STATE_MODE_CFG_I1:
- * HDR*, HASH, ATTR(REPLY=IP)
+/*
+ * Send XAUTH credentials request (username + password)
+ */
+stf_status
+xauth_send_request(struct state *st)
+{
+ stf_status stat;
+ internal_addr_t ia;
+
+ init_internal_addr(&ia);
+ ia.attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)
+ | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF);
+
+ plog("sending XAUTH request");
+ st->st_state = STATE_XAUTH_R1;
+ stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
+ if (stat == STF_OK)
+ st->st_xauth.started = TRUE;
+ return stat;
+}
+
+/* STATE_XAUTH_I0:
+ * HDR*, HASH, ATTR(REQ) --> HDR*, HASH, ATTR(REPLY=USERNAME/PASSWORD)
*
- * used in ModeCfg pull mode, on the client (initiator)
+ * used on the XAUTH client (initiator)
*/
stf_status
-modecfg_inI1(struct msg_digest *md)
+xauth_inI0(struct msg_digest *md)
{
struct state *const st = md->st;
u_int16_t isama_id;
internal_addr_t ia;
- stf_status stat;
+ stf_status stat, stat_build;
- plog("parsing ModeCfg reply");
+ plog("parsing XAUTH request");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
if (stat != STF_OK)
return stat;
+
+ /* check XAUTH attributes */
+ if ((ia.attr_set & LELEM(XAUTH_TYPE - XAUTH_BASE + MODECFG_ROOF)) != LEMPTY
+ && ia.xauth_type != XAUTH_TYPE_GENERIC)
+ {
+ plog("xauth type %s is not supported", enum_name(&xauth_type_names, ia.xauth_type));
+ stat = STF_FAIL;
+ }
+ else if ((ia.attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY)
+ {
+ plog("user name attribute is missing in XAUTH request");
+ stat = STF_FAIL;
+ }
+ else if ((ia.attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY)
+ {
+ plog("user password attribute is missing in XAUTH request");
+ stat = STF_FAIL;
+ }
- st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
- st->st_msgid = 0;
- return STF_OK;
+ /* prepare XAUTH reply */
+ init_internal_addr(&ia);
+
+ if (stat == STF_OK)
+ {
+ /* get user credentials using a plugin function */
+ if (!xauth_module.get_secret(&ia.xauth_secret))
+ {
+ plog("xauth user credentials not found");
+ stat = STF_FAIL;
+ }
+ }
+ if (stat == STF_OK)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("my xauth user name is '%.*s'"
+ , ia.xauth_secret.user_name.len
+ , ia.xauth_secret.user_name.ptr)
+ )
+ DBG(DBG_PRIVATE,
+ DBG_log("my xauth user password is '%.*s'"
+ , ia.xauth_secret.user_password.len
+ , ia.xauth_secret.user_password.ptr)
+ )
+ ia.attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)
+ | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF);
+ }
+ else
+ {
+ ia.attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE + MODECFG_ROOF);
+ ia.xauth_status = FALSE;
+ }
+
+ plog("sending XAUTH reply");
+
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_REPLY
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ return stat_build;
+
+ if (stat == STF_OK)
+ {
+ st->st_xauth.started = TRUE;
+ return STF_OK;
+ }
+ else
+ {
+ /* send XAUTH reply msg and then delete ISAKMP SA */
+ freeanychunk(st->st_tpacket);
+ clonetochunk(st->st_tpacket, md->reply.start
+ , pbs_offset(&md->reply), "XAUTH reply msg");
+ send_packet(st, "XAUTH reply msg");
+ delete_state(st);
+ return STF_IGNORE;
+ }
}
-/* STATE_MODE_CFG_I2:
- * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK)
+/* STATE_XAUTH_R1:
+ * HDR*, HASH, ATTR(REPLY=USERNAME/PASSWORD) --> HDR*, HASH, ATTR(STATUS)
*
- * used in ModeCfg push mode, on the client (initiator).
+ * used on the XAUTH server (responder)
*/
stf_status
-modecfg_inI2(struct msg_digest *md)
+xauth_inR1(struct msg_digest *md)
{
struct state *const st = md->st;
u_int16_t isama_id;
internal_addr_t ia;
- lset_t attr_set;
- stf_status stat;
+ stf_status stat, stat_build;
- plog("parsing ModeCfg set");
+ plog("parsing XAUTH reply");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
if (stat != STF_OK)
return stat;
+
+ /* did the client return an XAUTH FAIL status? */
+ if ((ia.attr_set & LELEM(XAUTH_STATUS - XAUTH_BASE + MODECFG_ROOF)) != LEMPTY)
+ {
+ plog("received FAIL status in XAUTH reply");
- st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
+ /* client is not able to do XAUTH, delete ISAKMP SA */
+ delete_state(st);
+ return STF_IGNORE;
+ }
- /* prepare ModeCfg ack which sends zero length attributes */
- attr_set = ia.attr_set;
+ /* check XAUTH reply */
+ if ((ia.attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY)
+ {
+ plog("user name attribute is missing in XAUTH reply");
+ st->st_xauth.status = FALSE;
+ }
+ else if ((ia.attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY)
+ {
+ plog("user password attribute is missing in XAUTH reply");
+ st->st_xauth.status = FALSE;
+ }
+ else
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("peer xauth user name is '%.*s'"
+ , ia.xauth_secret.user_name.len
+ , ia.xauth_secret.user_name.ptr)
+ )
+ DBG(DBG_PRIVATE,
+ DBG_log("peer xauth user password is '%.*s'"
+ , ia.xauth_secret.user_password.len
+ , ia.xauth_secret.user_password.ptr)
+ )
+ /* verify the user credentials using a plugn function */
+ st->st_xauth.status = xauth_module.verify_secret(&ia.xauth_secret);
+ plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
+ }
+
+ /* prepare XAUTH set which sends the authentication status */
init_internal_addr(&ia);
- ia.attr_set = attr_set & SUPPORTED_ATTR_SET;
+ ia.attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE + MODECFG_ROOF);
+ ia.xauth_status = st->st_xauth.status;
+
+ plog("sending XAUTH status:");
+
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_SET
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ return stat_build;
+ return STF_OK;
+}
- stat = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_ACK
- , &ia
- , isama_id);
+/* STATE_XAUTH_I1:
+ * HDR*, HASH, ATTR(STATUS) --> HDR*, HASH, ATTR(ACK)
+ *
+ * used on the XAUTH client (initiator)
+ */
+stf_status
+xauth_inI1(struct msg_digest *md)
+{
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat, stat_build;
+
+ plog("parsing XAUTH status");
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
if (stat != STF_OK)
{
/* notification payload - not exactly the right choice, but okay */
@@ -622,6 +909,62 @@ modecfg_inI2(struct msg_digest *md)
return stat;
}
+ st->st_xauth.status = ia.xauth_status;
+ plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
+
+ plog("sending XAUTH ack");
+ init_internal_addr(&ia);
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_ACK
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ return stat_build;
+
+ if (st->st_xauth.status)
+ {
+ st->st_msgid = 0;
+ return STF_OK;
+ }
+ else
+ {
+ /* send XAUTH ack msg and then delete ISAKMP SA */
+ freeanychunk(st->st_tpacket);
+ clonetochunk(st->st_tpacket, md->reply.start
+ , pbs_offset(&md->reply), "XAUTH ack msg");
+ send_packet(st, "XAUTH ack msg");
+ delete_state(st);
+ return STF_IGNORE;
+ }
+}
+
+/* STATE_XAUTH_R2:
+ * HDR*, ATTR(STATUS), HASH --> Done
+ *
+ * used on the XAUTH server (responder)
+ */
+stf_status
+xauth_inR2(struct msg_digest *md)
+{
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat;
+
+ plog("parsing XAUTH ack");
+
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
+ if (stat != STF_OK)
+ return stat;
+
st->st_msgid = 0;
- return STF_OK;
+ if (st->st_xauth.status)
+ {
+ return STF_OK;
+ }
+ else
+ {
+ delete_state(st);
+ return STF_IGNORE;
+ }
}
diff --git a/programs/pluto/modecfg.h b/programs/pluto/modecfg.h
index 1f8259ca8..4fce75aef 100644
--- a/programs/pluto/modecfg.h
+++ b/programs/pluto/modecfg.h
@@ -12,17 +12,36 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: modecfg.h,v 1.3 2006/10/19 21:07:40 as Exp $
+ * RCSID $Id: modecfg.h,v 1.4 2007/01/10 00:36:19 as Exp $
*/
+#ifndef _MODECFG_H
+#define _MODECFG_H
+
struct state;
+struct msg_digest;
-/* ModeConfig starting functions */
+/* ModeConfig pull mode start function */
extern stf_status modecfg_send_request(struct state *st);
-extern stf_status modecfg_send_set(struct state *st);
-/* ModeConfig state transition functions */
+/* ModeConfig pull mode state transition functions */
extern stf_status modecfg_inR0(struct msg_digest *md);
-extern stf_status modecfg_inR1(struct msg_digest *md);
extern stf_status modecfg_inI1(struct msg_digest *md);
-extern stf_status modecfg_inI2(struct msg_digest *md);
+
+/* ModeConfig push mode start function */
+extern stf_status modecfg_send_set(struct state *st);
+
+/* ModeConfig push mode state transition functions */
+extern stf_status modecfg_inI0(struct msg_digest *md);
+extern stf_status modecfg_inR3(struct msg_digest *md);
+
+/* XAUTH start function */
+extern stf_status xauth_send_request(struct state *st);
+
+/* XAUTH state transition funcgtions */
+extern stf_status xauth_inI0(struct msg_digest *md);
+extern stf_status xauth_inR1(struct msg_digest *md);
+extern stf_status xauth_inI1(struct msg_digest *md);
+extern stf_status xauth_inR2(struct msg_digest *md);
+
+#endif /* _MODECFG_H */
diff --git a/programs/pluto/plutomain.c b/programs/pluto/plutomain.c
index f9badbae3..613f8d50f 100644
--- a/programs/pluto/plutomain.c
+++ b/programs/pluto/plutomain.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: plutomain.c,v 1.16 2005/09/25 21:30:52 as Exp $
+ * RCSID $Id: plutomain.c,v 1.18 2007/01/14 10:11:56 as Exp $
*/
#include <stdio.h>
@@ -57,6 +57,7 @@
#include "ocsp.h"
#include "crl.h"
#include "fetch.h"
+#include "xauth.h"
#include "sha1.h"
#include "md5.h"
@@ -628,6 +629,7 @@ main(int argc, char **argv)
init_virtual_ip(virtual_private);
#endif
scx_init(pkcs11_module_path); /* load and initialize PKCS #11 module */
+ xauth_init(); /* load and initialize XAUTH module */
init_rnd_pool();
init_secret();
init_states();
@@ -678,6 +680,7 @@ exit_pluto(int status)
free_ocsp(); /* free ocsp cache */
free_ifaces();
scx_finalize(); /* finalize and unload PKCS #11 module */
+ xauth_finalize(); /* finalize and unload XAUTH module */
stop_adns();
free_md_pool();
delete_lock();
diff --git a/programs/pluto/spdb.c b/programs/pluto/spdb.c
index 0544a1da2..ab976511e 100644
--- a/programs/pluto/spdb.c
+++ b/programs/pluto/spdb.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: spdb.c,v 1.9 2006/04/22 21:59:20 as Exp $
+ * RCSID $Id: spdb.c,v 1.10 2007/01/10 00:36:19 as Exp $
*/
#include <stdio.h>
@@ -54,158 +54,26 @@
/**************** Oakely (main mode) SA database ****************/
-/* arrays of attributes for transforms, preshared key */
-
-static struct db_attr otpsk1024des3md5[] = {
- { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC },
- { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 },
- { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY },
- { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 },
- };
-
-static struct db_attr otpsk1536des3md5[] = {
- { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC },
- { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 },
- { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY },
- { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 },
- };
-
-static struct db_attr otpsk1024des3sha[] = {
- { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC },
- { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA },
- { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY },
- { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 },
- };
-
-static struct db_attr otpsk1536des3sha[] = {
- { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC },
- { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA },
- { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY },
- { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 },
- };
-
-/* arrays of attributes for transforms, RSA signatures */
-
-static struct db_attr otrsasig1024des3md5[] = {
- { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC },
- { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 },
- { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG },
- { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 },
- };
-
-static struct db_attr otrsasig1536des3md5[] = {
- { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC },
- { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 },
- { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG },
- { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 },
- };
-
-static struct db_attr otrsasig1024des3sha[] = {
- { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC },
- { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA },
- { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG },
- { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 },
- };
-
-static struct db_attr otrsasig1536des3sha[] = {
- { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC },
- { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA },
- { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG },
- { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 },
- };
-
-/* We won't accept this, but by proposing it, we get to test
- * our rejection. We better not propose it to an IKE daemon
- * that will accept it!
- */
-#ifdef TEST_INDECENT_PROPOSAL
-static struct db_attr otpsk1024des3tiger[] = {
- { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC },
- { OAKLEY_HASH_ALGORITHM, OAKLEY_TIGER },
- { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY },
- { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 },
- };
-#endif /* TEST_INDECENT_PROPOSAL */
-
-/* tables of transforms, in preference order (select based on AUTH) */
-
-static struct db_trans oakley_trans_psk[] = {
-#ifdef TEST_INDECENT_PROPOSAL
- { KEY_IKE, AD(otpsk1024des3tiger) },
-#endif
- { KEY_IKE, AD(otpsk1536des3md5) },
- { KEY_IKE, AD(otpsk1536des3sha) },
- { KEY_IKE, AD(otpsk1024des3sha) },
- { KEY_IKE, AD(otpsk1024des3md5) },
- };
-
-static struct db_trans oakley_trans_rsasig[] = {
- { KEY_IKE, AD(otrsasig1536des3md5) },
- { KEY_IKE, AD(otrsasig1536des3sha) },
- { KEY_IKE, AD(otrsasig1024des3sha) },
- { KEY_IKE, AD(otrsasig1024des3md5) },
- };
-
-/* In this table, either PSK or RSA sig is accepted.
- * The order matters, but I don't know what would be best.
- */
-static struct db_trans oakley_trans_pskrsasig[] = {
-#ifdef TEST_INDECENT_PROPOSAL
- { KEY_IKE, AD(otpsk1024des3tiger) },
-#endif
- { KEY_IKE, AD(otrsasig1536des3md5) },
- { KEY_IKE, AD(otpsk1536des3md5) },
- { KEY_IKE, AD(otrsasig1536des3sha) },
- { KEY_IKE, AD(otpsk1536des3sha) },
- { KEY_IKE, AD(otrsasig1024des3sha) },
- { KEY_IKE, AD(otpsk1024des3sha) },
- { KEY_IKE, AD(otrsasig1024des3md5) },
- { KEY_IKE, AD(otpsk1024des3md5) },
- };
-
/* array of proposals to be conjoined (can only be one for Oakley) */
-static struct db_prop oakley_pc_psk[] =
- { { PROTO_ISAKMP, AD(oakley_trans_psk) } };
-
-static struct db_prop oakley_pc_rsasig[] =
- { { PROTO_ISAKMP, AD(oakley_trans_rsasig) } };
-
-static struct db_prop oakley_pc_pskrsasig[] =
- { { PROTO_ISAKMP, AD(oakley_trans_pskrsasig) } };
+static struct db_prop oakley_pc[] =
+ { { PROTO_ISAKMP, AD_NULL } };
/* array of proposal conjuncts (can only be one) */
-static struct db_prop_conj oakley_props_psk[] = { { AD(oakley_pc_psk) } };
+static struct db_prop_conj oakley_props[] = { { AD(oakley_pc) } };
-static struct db_prop_conj oakley_props_rsasig[] = { { AD(oakley_pc_rsasig) } };
-
-static struct db_prop_conj oakley_props_pskrsasig[] = { { AD(oakley_pc_pskrsasig) } };
-
-/* the sadb entry, subscripted by POLICY_PSK and POLICY_RSASIG bits */
-struct db_sa oakley_sadb[] = {
- { AD_NULL }, /* none */
- { AD(oakley_props_psk) }, /* POLICY_PSK */
- { AD(oakley_props_rsasig) }, /* POLICY_RSASIG */
- { AD(oakley_props_pskrsasig) }, /* POLICY_PSK + POLICY_RSASIG */
- };
+/* the sadb entry */
+struct db_sa oakley_sadb = { AD(oakley_props) };
/**************** IPsec (quick mode) SA database ****************/
/* arrays of attributes for transforms */
-static struct db_attr espmd5_attr[] = {
- { AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_MD5 },
- };
-
static struct db_attr espsha1_attr[] = {
{ AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1 },
};
-static struct db_attr ah_HMAC_MD5_attr[] = {
- { AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_MD5 },
- };
-
static struct db_attr ah_HMAC_SHA1_attr[] = {
{ AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1 },
};
@@ -213,7 +81,6 @@ static struct db_attr ah_HMAC_SHA1_attr[] = {
/* arrays of transforms, each in in preference order */
static struct db_trans espa_trans[] = {
- { ESP_3DES, AD(espmd5_attr) },
{ ESP_3DES, AD(espsha1_attr) },
};
@@ -223,13 +90,11 @@ static struct db_trans esp_trans[] = {
#ifdef SUPPORT_ESP_NULL
static struct db_trans espnull_trans[] = {
- { ESP_NULL, AD(espmd5_attr) },
{ ESP_NULL, AD(espsha1_attr) },
};
#endif /* SUPPORT_ESP_NULL */
static struct db_trans ah_trans[] = {
- { AH_MD5, AD(ah_HMAC_MD5_attr) },
{ AH_SHA, AD(ah_HMAC_SHA1_attr) },
};
@@ -452,7 +317,7 @@ out_sa(pb_stream *outs
proposal.isap_spisize = oakley_mode ? 0
: p->protoid == PROTO_IPCOMP ? IPCOMP_CPI_SIZE
: IPSEC_DOI_SPI_SIZE;
-
+
/* In quick mode ONLY, create proposal for runtime kernel algos.
* Replace ESP proposals with runtime created one
*/
@@ -503,7 +368,7 @@ out_sa(pb_stream *outs
return_on(ret, FALSE);
}
}
-
+
proposal.isap_notrans = p->trans_cnt;
if (!out_struct(&proposal, &isakmp_proposal_desc, &sa_pbs, &proposal_pbs))
return_on(ret, FALSE);
@@ -888,7 +753,9 @@ restore_pbs(pb_stream *pbs)
* Parse an ISAKMP Proposal Payload for RSA and PSK authentication policies
*/
notification_t
-parse_isakmp_policy(pb_stream *proposal_pbs, u_int notrans, lset_t *policy)
+parse_isakmp_policy(pb_stream *proposal_pbs
+ , u_int notrans
+ , lset_t *policy)
{
int last_transnum = -1;
@@ -945,6 +812,18 @@ parse_isakmp_policy(pb_stream *proposal_pbs, u_int notrans, lset_t *policy)
case OAKLEY_RSA_SIG:
*policy |= POLICY_RSASIG;
break;
+ case XAUTHInitPreShared:
+ *policy |= POLICY_XAUTH_SERVER;
+ /* fall through */
+ case XAUTHRespPreShared:
+ *policy |= POLICY_XAUTH_PSK;
+ break;
+ case XAUTHInitRSA:
+ *policy |= POLICY_XAUTH_SERVER;
+ /* fall through */
+ case XAUTHRespRSA:
+ *policy |= POLICY_XAUTH_RSASIG;
+ break;
default:
break;
}
@@ -954,23 +833,35 @@ parse_isakmp_policy(pb_stream *proposal_pbs, u_int notrans, lset_t *policy)
}
}
}
+ DBG(DBG_CONTROL|DBG_PARSING,
+ DBG_log("preparse_isakmp_policy: peer requests %s authentication"
+ , prettypolicy(*policy))
+ )
+ return NOTHING_WRONG;
+}
- if ((*policy & POLICY_PSK) && (*policy & POLICY_RSASIG))
- {
- DBG(DBG_CONTROL|DBG_PARSING,
- DBG_log("preparse_isakmp_policy: "
- "peer supports both PSK and RSASIG authentication")
- )
- *policy = LEMPTY;
- }
- else
+/*
+ * check that we can find a preshared secret
+ */
+static err_t
+find_preshared_key(struct state* st)
+{
+ err_t ugh = NULL;
+ struct connection *c = st->st_connection;
+
+ if (get_preshared_secret(c) == NULL)
{
- DBG(DBG_CONTROL|DBG_PARSING,
- DBG_log("preparse_isakmp_policy: peer requests %s authentication"
- , (*policy & POLICY_PSK) ? "PSK":"RSASIG")
- )
+ char my_id[BUF_LEN], his_id[BUF_LEN];
+
+ idtoa(&c->spd.this.id, my_id, sizeof(my_id));
+ if (his_id_was_instantiated(c))
+ strcpy(his_id, "%any");
+ else
+ idtoa(&c->spd.that.id, his_id, sizeof(his_id));
+ ugh = builddiag("Can't authenticate: no preshared key found for `%s' and `%s'"
+ , my_id, his_id);
}
- return NOTHING_WRONG;
+ return ugh;
}
/* Parse the body of an ISAKMP SA Payload (i.e. Phase 1 / Main Mode).
@@ -987,7 +878,8 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit
, pb_stream *proposal_pbs
, struct isakmp_proposal *proposal
, pb_stream *r_sa_pbs
- , struct state *st)
+ , struct state *st
+ , bool initiator)
{
struct connection *c = st->st_connection;
unsigned no_trans_left;
@@ -1093,6 +985,10 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit
/* check that authentication method is acceptable */
lset_t iap = st->st_policy & POLICY_ID_AUTH_MASK;
+ /* is the initiator the XAUTH client? */
+ bool xauth_init = initiator && (st->st_policy & POLICY_XAUTH_SERVER) == LEMPTY
+ || !initiator && (st->st_policy & POLICY_XAUTH_SERVER) != LEMPTY;
+
switch (val)
{
case OAKLEY_PRESHARED_KEY:
@@ -1102,23 +998,30 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit
}
else
{
- /* check that we can find a preshared secret */
- struct connection *c = st->st_connection;
-
- if (get_preshared_secret(c) == NULL)
- {
- char mid[BUF_LEN]
- , hid[BUF_LEN];
-
- idtoa(&c->spd.this.id, mid, sizeof(mid));
- if (his_id_was_instantiated(c))
- strcpy(hid, "%any");
- else
- idtoa(&c->spd.that.id, hid, sizeof(hid));
- ugh = builddiag("Can't authenticate: no preshared key found for `%s' and `%s'"
- , mid, hid);
- }
- ta.auth = val;
+ ugh = find_preshared_key(st);
+ ta.auth = OAKLEY_PRESHARED_KEY;
+ }
+ break;
+ case XAUTHInitPreShared:
+ if ((iap & POLICY_XAUTH_PSK) == LEMPTY || !xauth_init)
+ {
+ ugh = "policy does not allow XAUTHInitPreShared authentication";
+ }
+ else
+ {
+ ugh = find_preshared_key(st);
+ ta.auth = XAUTHInitPreShared;
+ }
+ break;
+ case XAUTHRespPreShared:
+ if ((iap & POLICY_XAUTH_PSK) == LEMPTY || xauth_init)
+ {
+ ugh = "policy does not allow XAUTHRespPreShared authentication";
+ }
+ else
+ {
+ ugh = find_preshared_key(st);
+ ta.auth = XAUTHRespPreShared;
}
break;
case OAKLEY_RSA_SIG:
@@ -1129,18 +1032,29 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit
}
else
{
- /* We'd like to check that we can find a public
- * key for him and a private key for us that is
- * suitable, but we don't yet have his
- * Id Payload, so it seems futile to try.
- * We can assume that if he proposes it, he
- * thinks we've got it. If we proposed it,
- * perhaps we know what we're doing.
- */
- ta.auth = val;
+ ta.auth = OAKLEY_RSA_SIG;
+ }
+ break;
+ case XAUTHInitRSA:
+ if ((iap & POLICY_XAUTH_RSASIG) == LEMPTY || !xauth_init)
+ {
+ ugh = "policy does not allow XAUTHInitRSA authentication";
+ }
+ else
+ {
+ ta.auth = XAUTHInitRSA;
+ }
+ break;
+ case XAUTHRespRSA:
+ if ((iap & POLICY_XAUTH_RSASIG) == LEMPTY || xauth_init)
+ {
+ ugh = "policy does not allow XAUTHRespRSA authentication";
+ }
+ else
+ {
+ ta.auth = XAUTHRespRSA;
}
break;
-
default:
ugh = builddiag("Pluto does not support %s authentication"
, enum_show(&oakley_auth_names, val));
@@ -1194,10 +1108,23 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit
{
case OAKLEY_LIFE_SECONDS:
if (val > OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM)
+ {
+#ifdef CISCO_QUIRKS
+ plog("peer requested %lu seconds"
+ " which exceeds our limit %d seconds"
+ , (long) val
+ , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
+ plog("lifetime reduced to %d seconds "
+ "(todo: IPSEC_RESPONDER_LIFETIME notification)"
+ , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
+ val = OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM;
+#else
ugh = builddiag("peer requested %lu seconds"
" which exceeds our limit %d seconds"
, (long) val
, OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
+#endif
+ }
ta.life_seconds = val;
break;
case OAKLEY_LIFE_KILOBYTES:
diff --git a/programs/pluto/spdb.h b/programs/pluto/spdb.h
index 5eebf86cf..6cb92f036 100644
--- a/programs/pluto/spdb.h
+++ b/programs/pluto/spdb.h
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: spdb.h,v 1.4 2006/04/22 21:59:20 as Exp $
+ * RCSID $Id: spdb.h,v 1.5 2007/01/10 00:36:19 as Exp $
*/
#ifndef _SPDB_H
@@ -60,10 +60,8 @@ struct db_sa {
*/
};
-/* The oakley sadb is subscripted by a bitset with members
- * from POLICY_PSK and POLICY_RSASIG.
- */
-extern struct db_sa oakley_sadb[1 << 2];
+/* The oakley sadb */
+extern struct db_sa oakley_sadb;
/* The ipsec sadb is subscripted by a bitset with members
* from POLICY_ENCRYPT, POLICY_AUTHENTICATE, POLICY_COMPRESS
@@ -90,14 +88,15 @@ extern notification_t preparse_isakmp_sa_body(
extern notification_t parse_isakmp_policy(
pb_stream *proposal_pbs, /* body of proposal Payload */
u_int notrans, /* number of transforms */
- lset_t *policy); /* RSA or PSK policy */
+ lset_t *policy); /* RSA, PSK or XAUTH policy */
extern notification_t parse_isakmp_sa_body(
u_int32_t ipsecdoisit, /* IPsec DOI SIT bitset */
pb_stream *proposal_pbs, /* body of proposal Payload */
struct isakmp_proposal *proposal,
pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
- struct state *st); /* current state object */
+ struct state *st, /* current state object */
+ bool initiator); /* is caller initiator? */
extern notification_t parse_ipsec_sa_body(
pb_stream *sa_pbs, /* body of input SA Payload */
diff --git a/programs/pluto/state.h b/programs/pluto/state.h
index c7212fd1a..d885d145d 100644
--- a/programs/pluto/state.h
+++ b/programs/pluto/state.h
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: state.h,v 1.12 2006/10/17 10:30:54 as Exp $
+ * RCSID $Id: state.h,v 1.13 2007/01/10 00:36:19 as Exp $
*/
#include <sys/types.h>
@@ -212,7 +212,13 @@ struct state
bool vars_set;
bool started;
} st_modecfg;
-
+
+ struct {
+ int attempt;
+ bool started;
+ bool status;
+ } st_xauth;
+
#ifdef NAT_TRAVERSAL
u_int32_t nat_traversal;
ip_address nat_oa;
diff --git a/programs/pluto/vendor.c b/programs/pluto/vendor.c
index cbb26a5ef..3e2e0768a 100644
--- a/programs/pluto/vendor.c
+++ b/programs/pluto/vendor.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: vendor.c,v 1.41 2006/10/19 15:21:08 as Exp $
+ * RCSID $Id: vendor.c,v 1.43 2007/01/10 00:31:36 as Exp $
*/
#include <stdlib.h>
@@ -164,6 +164,9 @@ static struct vid_struct _vid_tab[] = {
{ VID_CISCO3K, VID_KEEP | VID_SUBSTRING_MATCH,
NULL, "Cisco VPN 3000 Series" , "\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a\x50", 14},
+ { VID_CISCO_IOS, VID_KEEP | VID_SUBSTRING_MATCH,
+ NULL, "Cisco IOS Device", "\x3e\x98\x40\x48", 4},
+
/*
* Timestep VID seen:
* - 54494d455354455020312053475720313532302033313520322e303145303133
@@ -204,8 +207,10 @@ static struct vid_struct _vid_tab[] = {
DEC_MD5_VID(STRONGSWAN_4_0_3, "strongSwan 4.0.3")
DEC_MD5_VID(STRONGSWAN_4_0_4, "strongSwan 4.0.4")
DEC_MD5_VID(STRONGSWAN_4_0_5, "strongSwan 4.0.5")
+ DEC_MD5_VID(STRONGSWAN_4_0_6, "strongSwan 4.0.6")
- DEC_MD5_VID(STRONGSWAN, "strongSwan 2.8.0")
+ DEC_MD5_VID(STRONGSWAN, "strongSwan 2.8.1")
+ DEC_MD5_VID(STRONGSWAN_2_8_0, "strongSwan 2.8.0")
DEC_MD5_VID(STRONGSWAN_2_7_3, "strongSwan 2.7.3")
DEC_MD5_VID(STRONGSWAN_2_7_2, "strongSwan 2.7.2")
DEC_MD5_VID(STRONGSWAN_2_7_1, "strongSwan 2.7.1")
@@ -260,6 +265,12 @@ static struct vid_struct _vid_tab[] = {
DEC_MD5_VID(INITIAL_CONTACT, "Vid-Initial-Contact")
+ /**
+ * Cisco VPN 3000
+ */
+ { VID_MISC_FRAGMENTATION, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
+ "FRAGMENTATION", NULL, NULL, 0 },
+
/* -- */
{ 0, 0, NULL, NULL, NULL, 0 }
@@ -386,6 +397,9 @@ handle_known_vendorid (struct msg_digest *md
md->dpd = TRUE;
vid_useful = TRUE;
break;
+ case VID_MISC_XAUTH:
+ vid_useful = TRUE;
+ break;
default:
break;
}
diff --git a/programs/pluto/vendor.h b/programs/pluto/vendor.h
index c7f70a480..060311b92 100644
--- a/programs/pluto/vendor.h
+++ b/programs/pluto/vendor.h
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: vendor.h,v 1.36 2006/10/19 15:21:08 as Exp $
+ * RCSID $Id: vendor.h,v 1.38 2007/01/10 00:31:36 as Exp $
*/
#ifndef _VENDOR_H_
@@ -45,41 +45,43 @@ enum known_vendorid {
VID_SSH_IPSEC_4_2_0 = 24,
VID_CISCO_UNITY = 25,
VID_CISCO3K = 26,
- VID_TIMESTEP = 27,
- VID_SAFENET = 28,
- VID_MACOSX = 29,
- VID_OPENSWAN2 = 30,
- VID_NCP_SERVER = 31,
- VID_NCP_CLIENT = 32,
- VID_STRONGSWAN = 33,
- VID_STRONGSWAN_2_2_0 = 34,
- VID_STRONGSWAN_2_2_1 = 35,
- VID_STRONGSWAN_2_2_2 = 36,
- VID_STRONGSWAN_2_3_0 = 37,
- VID_STRONGSWAN_2_3_1 = 38,
- VID_STRONGSWAN_2_3_2 = 39,
- VID_STRONGSWAN_2_4_0 = 40,
- VID_STRONGSWAN_2_4_1 = 41,
- VID_STRONGSWAN_2_4_2 = 42,
- VID_STRONGSWAN_2_4_3 = 43,
- VID_STRONGSWAN_2_4_4 = 44,
- VID_STRONGSWAN_2_5_0 = 45,
- VID_STRONGSWAN_2_5_1 = 46,
- VID_STRONGSWAN_2_5_2 = 47,
- VID_STRONGSWAN_2_5_3 = 48,
- VID_STRONGSWAN_2_5_4 = 49,
- VID_STRONGSWAN_2_5_5 = 50,
- VID_STRONGSWAN_2_5_6 = 51,
- VID_STRONGSWAN_2_5_7 = 52,
- VID_STRONGSWAN_2_6_0 = 53,
- VID_STRONGSWAN_2_6_1 = 54,
- VID_STRONGSWAN_2_6_2 = 55,
- VID_STRONGSWAN_2_6_3 = 56,
- VID_STRONGSWAN_2_6_4 = 57,
- VID_STRONGSWAN_2_7_0 = 58,
- VID_STRONGSWAN_2_7_1 = 59,
- VID_STRONGSWAN_2_7_2 = 60,
- VID_STRONGSWAN_2_7_3 = 61,
+ VID_CISCO_IOS = 27,
+ VID_TIMESTEP = 28,
+ VID_SAFENET = 29,
+ VID_MACOSX = 30,
+ VID_OPENSWAN2 = 31,
+ VID_NCP_SERVER = 32,
+ VID_NCP_CLIENT = 33,
+ VID_STRONGSWAN = 34,
+ VID_STRONGSWAN_2_2_0 = 35,
+ VID_STRONGSWAN_2_2_1 = 36,
+ VID_STRONGSWAN_2_2_2 = 37,
+ VID_STRONGSWAN_2_3_0 = 38,
+ VID_STRONGSWAN_2_3_1 = 39,
+ VID_STRONGSWAN_2_3_2 = 40,
+ VID_STRONGSWAN_2_4_0 = 41,
+ VID_STRONGSWAN_2_4_1 = 42,
+ VID_STRONGSWAN_2_4_2 = 43,
+ VID_STRONGSWAN_2_4_3 = 44,
+ VID_STRONGSWAN_2_4_4 = 45,
+ VID_STRONGSWAN_2_5_0 = 46,
+ VID_STRONGSWAN_2_5_1 = 47,
+ VID_STRONGSWAN_2_5_2 = 48,
+ VID_STRONGSWAN_2_5_3 = 49,
+ VID_STRONGSWAN_2_5_4 = 50,
+ VID_STRONGSWAN_2_5_5 = 51,
+ VID_STRONGSWAN_2_5_6 = 52,
+ VID_STRONGSWAN_2_5_7 = 53,
+ VID_STRONGSWAN_2_6_0 = 54,
+ VID_STRONGSWAN_2_6_1 = 55,
+ VID_STRONGSWAN_2_6_2 = 56,
+ VID_STRONGSWAN_2_6_3 = 57,
+ VID_STRONGSWAN_2_6_4 = 58,
+ VID_STRONGSWAN_2_7_0 = 59,
+ VID_STRONGSWAN_2_7_1 = 60,
+ VID_STRONGSWAN_2_7_2 = 61,
+ VID_STRONGSWAN_2_7_3 = 62,
+ VID_STRONGSWAN_2_8_0 = 63,
VID_STRONGSWAN_4_0_0 = 70,
VID_STRONGSWAN_4_0_1 = 71,
@@ -87,6 +89,7 @@ enum known_vendorid {
VID_STRONGSWAN_4_0_3 = 73,
VID_STRONGSWAN_4_0_4 = 74,
VID_STRONGSWAN_4_0_5 = 75,
+ VID_STRONGSWAN_4_0_6 = 76,
/* 101 - 200 : NAT-Traversal */
VID_NATT_STENBERG_01 =101,
@@ -104,7 +107,8 @@ enum known_vendorid {
VID_MISC_DPD =202,
VID_MISC_HEARTBEAT_NOTIFY =203,
VID_MISC_FRAGMENTATION =204,
- VID_INITIAL_CONTACT =205
+ VID_INITIAL_CONTACT =205,
+ VID_CISCO3K_FRAGMENTATION =206
};
void init_vendorid(void);
diff --git a/programs/pluto/xauth.c b/programs/pluto/xauth.c
new file mode 100644
index 000000000..c33ad9b3d
--- /dev/null
+++ b/programs/pluto/xauth.c
@@ -0,0 +1,77 @@
+/* Initialization and finalization of the dynamic XAUTH module
+ * Copyright (C) 2006 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil, Switzerland
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: xauth.c,v 1.1 2007/01/11 21:48:41 as Exp $
+ */
+
+#include <dlfcn.h>
+
+#include <freeswan.h>
+
+#include "constants.h"
+#include "defs.h"
+#include "xauth.h"
+#include "keys.h"
+#include "log.h"
+
+void
+xauth_init(void)
+{
+#ifdef XAUTH_DEFAULT_LIB
+ xauth_module.handle = dlopen(XAUTH_DEFAULT_LIB, RTLD_NOW);
+
+ if (xauth_module.handle != NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("xauth module '%s' loading'", XAUTH_DEFAULT_LIB)
+ )
+ xauth_module.get_secret = (bool (*) (const xauth_t*))
+ dlsym(xauth_module.handle, "get_secret");
+ DBG(DBG_CONTROL,
+ if (xauth_module.get_secret != NULL)
+ {
+ DBG_log("xauth module: found get_secret() function");
+ }
+ )
+ xauth_module.verify_secret = (bool (*) (const xauth_t*))
+ dlsym(xauth_module.handle, "verify_secret");
+ DBG(DBG_CONTROL,
+ if (xauth_module.verify_secret != NULL)
+ {
+ DBG_log("xauth module: found verify_secret() function");
+ }
+ )
+ }
+#endif
+ /* any null function pointers will be filled in by default functions */
+ xauth_defaults();
+}
+
+void
+xauth_finalize(void)
+{
+ if (xauth_module.handle != NULL)
+ {
+ if (dlclose(xauth_module.handle))
+ {
+ plog("failed to unload xauth module");
+ }
+ else
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("xauth module unloaded")
+ )
+ }
+ }
+}
diff --git a/programs/pluto/xauth.h b/programs/pluto/xauth.h
new file mode 100644
index 000000000..371e443ef
--- /dev/null
+++ b/programs/pluto/xauth.h
@@ -0,0 +1,41 @@
+/* Interface definition of the XAUTH server and|or client module
+ * Copyright (C) 2006 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil, Switzerland
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: xauth.h,v 1.1 2007/01/11 21:48:41 as Exp $
+ */
+
+#ifndef _XAUTH_H
+#define _XAUTH_H
+
+/* XAUTH credentials */
+
+struct chunk_t;
+
+typedef struct {
+ chunk_t user_name;
+ chunk_t user_password;
+} xauth_t;
+
+typedef struct {
+ void *handle;
+ bool (*get_secret) (xauth_t *xauth_secret);
+ bool (*verify_secret) (const xauth_t *xauth_secret);
+} xauth_module_t;
+
+extern xauth_module_t xauth_module;
+
+extern void xauth_init(void);
+extern void xauth_finalize(void);
+
+#endif /* _XAUTH_H */
diff --git a/programs/starter/args.c b/programs/starter/args.c
index 2b2853a20..9dece2dfb 100644
--- a/programs/starter/args.c
+++ b/programs/starter/args.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: args.c,v 1.10 2006/10/19 14:58:30 as Exp $
+ * RCSID $Id: args.c,v 1.11 2007/01/11 21:27:27 as Exp $
*/
#include <stddef.h>
@@ -192,6 +192,7 @@ static const token_info_t token_info[] =
{ ARG_TIME, offsetof(starter_conn_t, dpd_timeout), NULL },
{ ARG_ENUM, offsetof(starter_conn_t, dpd_action), LST_dpd_action },
{ ARG_MISC, 0, NULL /* KW_MODECONFIG */ },
+ { ARG_MISC, 0, NULL /* KW_XAUTH */ },
/* ca section keywords */
{ ARG_STR, offsetof(starter_ca_t, name), NULL },
diff --git a/programs/starter/confread.c b/programs/starter/confread.c
index edd041ab4..63010685b 100644
--- a/programs/starter/confread.c
+++ b/programs/starter/confread.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: confread.c,v 1.39 2006/10/19 14:58:30 as Exp $
+ * RCSID $Id: confread.c,v 1.40 2007/01/11 21:27:27 as Exp $
*/
#include <stddef.h>
@@ -418,7 +418,7 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
KW_POLICY_FLAG("ah", "esp", POLICY_AUTHENTICATE)
break;
case KW_AUTHBY:
- conn->policy &= ~(POLICY_RSASIG | POLICY_PSK | POLICY_ENCRYPT);
+ conn->policy &= ~(POLICY_ID_AUTH_MASK | POLICY_ENCRYPT);
if (strcmp(kw->value, "never") != 0)
{
@@ -433,8 +433,12 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
{
if (streq(value, "rsasig"))
conn->policy |= POLICY_RSASIG | POLICY_ENCRYPT;
- else if (streq(value, "secret"))
+ else if (streq(value, "secret") || streq(value, "psk"))
conn->policy |= POLICY_PSK | POLICY_ENCRYPT;
+ else if (streq(value, "xauthrsasig"))
+ conn->policy |= POLICY_XAUTH_RSASIG | POLICY_ENCRYPT;
+ else if (streq(value, "xauthpsk"))
+ conn->policy |= POLICY_XAUTH_PSK | POLICY_ENCRYPT;
else
{
plog("# bad policy value: %s=%s", kw->entry->name, kw->value);
@@ -454,6 +458,9 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
case KW_MODECONFIG:
KW_POLICY_FLAG("push", "pull", POLICY_MODECFG_PUSH)
break;
+ case KW_XAUTH:
+ KW_POLICY_FLAG("server", "client", POLICY_XAUTH_SERVER)
+ break;
default:
break;
}
diff --git a/programs/starter/keywords.c b/programs/starter/keywords.c
index 75be0a542..b06ee3c0c 100644
--- a/programs/starter/keywords.c
+++ b/programs/starter/keywords.c
@@ -44,7 +44,7 @@ error "gperf generated tables don't work with this execution character set. Plea
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: keywords.c,v 1.8 2006/10/19 14:58:30 as Exp $
+ * RCSID $Id: keywords.c,v 1.9 2007/01/11 21:29:28 as Exp $
*/
#include <string.h>
@@ -56,7 +56,7 @@ struct kw_entry {
kw_token_t token;
};
-#define TOTAL_KEYWORDS 80
+#define TOTAL_KEYWORDS 81
#define MIN_WORD_LENGTH 3
#define MAX_WORD_LENGTH 17
#define MIN_HASH_VALUE 9
@@ -87,7 +87,7 @@ hash (str, len)
157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 90, 157, 60,
- 50, 25, 0, 10, 5, 65, 157, 65, 70, 5,
+ 50, 25, 0, 10, 30, 65, 157, 65, 70, 5,
0, 75, 35, 157, 10, 20, 5, 70, 157, 157,
157, 55, 0, 157, 157, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
@@ -114,7 +114,7 @@ static const struct kw_entry wordlist[] =
{"leftupdown", KW_LEFTUPDOWN},
{""}, {""},
{"leftcert", KW_LEFTCERT,},
- {"auth", KW_AUTH},
+ {""},
{"leftsubnet", KW_LEFTSUBNET},
{"leftsubnetwithin", KW_LEFTSUBNETWITHIN},
{"leftsendcert", KW_LEFTSENDCERT},
@@ -135,7 +135,9 @@ static const struct kw_entry wordlist[] =
{"compress", KW_COMPRESS},
{"lefthostaccess", KW_LEFTHOSTACCESS},
{"interfaces", KW_INTERFACES},
- {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""},
+ {"auth", KW_AUTH},
+ {""},
{"rightgroups", KW_RIGHTGROUPS},
{""},
{"pfs", KW_PFS},
@@ -198,7 +200,7 @@ static const struct kw_entry wordlist[] =
{"crluri2", KW_CRLURI2},
{"ldaphost", KW_LDAPHOST},
{"postpluto", KW_POSTPLUTO},
- {""},
+ {"xauth", KW_XAUTH},
{"overridemtu", KW_OVERRIDEMTU},
{"rightca", KW_RIGHTCA},
{"prepluto", KW_PREPLUTO},
diff --git a/programs/starter/keywords.h b/programs/starter/keywords.h
index be3aabf3b..4356b4947 100644
--- a/programs/starter/keywords.h
+++ b/programs/starter/keywords.h
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: keywords.h,v 1.9 2006/10/19 14:57:56 as Exp $
+ * RCSID $Id: keywords.h,v 1.10 2007/01/11 21:27:27 as Exp $
*/
#ifndef _KEYWORDS_H_
@@ -77,9 +77,10 @@ typedef enum {
KW_DPDTIMEOUT,
KW_DPDACTION,
KW_MODECONFIG,
+ KW_XAUTH,
#define KW_CONN_FIRST KW_CONN_SETUP
-#define KW_CONN_LAST KW_MODECONFIG
+#define KW_CONN_LAST KW_XAUTH
/* ca section keywords */
KW_CA_NAME,
diff --git a/programs/starter/keywords.txt b/programs/starter/keywords.txt
index fc9e49e47..6ad2d5fce 100644
--- a/programs/starter/keywords.txt
+++ b/programs/starter/keywords.txt
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: keywords.txt,v 1.7 2006/10/19 14:57:56 as Exp $
+ * RCSID $Id: keywords.txt,v 1.8 2007/01/11 21:27:51 as Exp $
*/
#include <string.h>
@@ -66,6 +66,7 @@ dpddelay, KW_DPDDELAY
dpdtimeout, KW_DPDTIMEOUT
dpdaction, KW_DPDACTION
modeconfig, KW_MODECONFIG
+xauth, KW_XAUTH
cacert, KW_CACERT
ldaphost, KW_LDAPHOST
ldapbase, KW_LDAPBASE
diff --git a/programs/starter/lex.yy.c b/programs/starter/lex.yy.c
index 1626f1050..2c0dd040a 100644
--- a/programs/starter/lex.yy.c
+++ b/programs/starter/lex.yy.c
@@ -497,7 +497,7 @@ char *yytext;
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: lex.yy.c,v 1.4 2006/03/28 22:32:49 as Exp $
+ * RCSID $Id: lex.yy.c,v 1.6 2007/01/14 18:37:25 as Exp $
*/
#include <string.h>
@@ -1706,10 +1706,10 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
* @note If you want to scan bytes that may contain NUL values, then use
* yy_scan_bytes() instead.
*/
-YY_BUFFER_STATE yy_scan_string (yyconst char * __yystr )
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
{
- return yy_scan_bytes(__yystr,strlen(__yystr) );
+ return yy_scan_bytes(yystr,strlen(yystr) );
}
/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
diff --git a/programs/starter/parser.tab.c b/programs/starter/parser.tab.c
index bc21a2fd3..6e0061f89 100644
--- a/programs/starter/parser.tab.c
+++ b/programs/starter/parser.tab.c
@@ -1,7 +1,9 @@
-/* A Bison parser, made by GNU Bison 2.1. */
+/* A Bison parser, made by GNU Bison 2.2. */
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,13 +20,21 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
-/* Written by Richard Stallman by simplifying the original so called
- ``semantic'' parser. */
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
/* All symbols defined below should begin with yy or YY, to avoid
infringing on user name space. This should be done even for local
@@ -37,7 +47,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.1"
+#define YYBISON_VERSION "2.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -99,7 +109,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: parser.tab.c,v 1.5 2006/03/28 22:32:49 as Exp $
+ * RCSID $Id: parser.tab.c,v 1.7 2007/01/14 18:37:25 as Exp $
*/
#include <stdio.h>
@@ -158,11 +168,13 @@ extern kw_entry_t *in_word_set (char *str, unsigned int len);
# define YYTOKEN_TABLE 0
#endif
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
#line 56 "parser.y"
-typedef union YYSTYPE { char *s; } YYSTYPE;
-/* Line 196 of yacc.c. */
-#line 166 "parser.tab.c"
+{ char *s; }
+/* Line 193 of yacc.c. */
+#line 177 "parser.tab.c"
+ YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
@@ -173,23 +185,56 @@ typedef union YYSTYPE { char *s; } YYSTYPE;
/* Copy the second part of user declarations. */
-/* Line 219 of yacc.c. */
-#line 178 "parser.tab.c"
+/* Line 216 of yacc.c. */
+#line 190 "parser.tab.c"
-#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
-# define YYSIZE_T __SIZE_TYPE__
+#ifdef short
+# undef short
#endif
-#if ! defined (YYSIZE_T) && defined (size_t)
-# define YYSIZE_T size_t
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
#endif
-#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
#endif
-#if ! defined (YYSIZE_T)
-# define YYSIZE_T unsigned int
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
#endif
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
#ifndef YY_
# if YYENABLE_NLS
# if ENABLE_NLS
@@ -202,7 +247,32 @@ typedef union YYSTYPE { char *s; } YYSTYPE;
# endif
#endif
-#if ! defined (yyoverflow) || YYERROR_VERBOSE
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+ int i;
+#endif
+{
+ return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -210,64 +280,76 @@ typedef union YYSTYPE { char *s; } YYSTYPE;
# if YYSTACK_USE_ALLOCA
# ifdef __GNUC__
# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
-# if defined (__STDC__) || defined (__cplusplus)
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# define YYINCLUDED_STDLIB_H
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
# endif
# endif
# endif
# endif
# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
# ifndef YYSTACK_ALLOC_MAXIMUM
/* The OS might guarantee only one guard page at the bottom of the stack,
and a page size can be as small as 4096 bytes. So we cannot safely
invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
to allow for a few compiler-allocated temporary stack slots. */
-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
# endif
# else
# define YYSTACK_ALLOC YYMALLOC
# define YYSTACK_FREE YYFREE
# ifndef YYSTACK_ALLOC_MAXIMUM
-# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
-# ifdef __cplusplus
-extern "C" {
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
-# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
- && (defined (__STDC__) || defined (__cplusplus)))
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
-# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
- && (defined (__STDC__) || defined (__cplusplus)))
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
-# ifdef __cplusplus
-}
-# endif
# endif
-#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-#if (! defined (yyoverflow) \
- && (! defined (__cplusplus) \
- || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- short int yyss;
+ yytype_int16 yyss;
YYSTYPE yyvs;
};
@@ -277,13 +359,13 @@ union yyalloc
/* The size of an array large to enough to hold all stacks, each with
N elements. */
# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
-# if defined (__GNUC__) && 1 < __GNUC__
+# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
@@ -294,7 +376,7 @@ union yyalloc
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
- while (0)
+ while (YYID (0))
# endif
# endif
@@ -312,28 +394,22 @@ union yyalloc
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
- while (0)
+ while (YYID (0))
#endif
-#if defined (__STDC__) || defined (__cplusplus)
- typedef signed char yysigned_char;
-#else
- typedef short int yysigned_char;
-#endif
-
-/* YYFINAL -- State number of the termination state. */
+/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */
#define YYLAST 27
-/* YYNTOKENS -- Number of terminals. */
+/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 13
-/* YYNNTS -- Number of nonterminals. */
+/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 9
-/* YYNRULES -- Number of rules. */
+/* YYNRULES -- Number of rules. */
#define YYNRULES 18
-/* YYNRULES -- Number of states. */
+/* YYNRULES -- Number of states. */
#define YYNSTATES 34
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
@@ -344,7 +420,7 @@ union yyalloc
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const unsigned char yytranslate[] =
+static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -378,14 +454,14 @@ static const unsigned char yytranslate[] =
#if YYDEBUG
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */
-static const unsigned char yyprhs[] =
+static const yytype_uint8 yyprhs[] =
{
0, 0, 3, 6, 7, 11, 12, 18, 19, 25,
26, 32, 33, 38, 40, 45, 46, 50, 53
};
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yysigned_char yyrhs[] =
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int8 yyrhs[] =
{
14, 0, -1, 14, 15, -1, -1, 11, 12, 5,
-1, -1, 6, 7, 5, 16, 20, -1, -1, 8,
@@ -396,7 +472,7 @@ static const yysigned_char yyrhs[] =
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const unsigned char yyrline[] =
+static const yytype_uint8 yyrline[] =
{
0, 67, 67, 68, 72, 77, 76, 82, 81, 99,
98, 115, 114, 120, 124, 125, 129, 154, 158
@@ -405,7 +481,7 @@ static const unsigned char yyrline[] =
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
"$end", "error", "$undefined", "EQUAL", "FIRST_SPACES", "EOL", "CONFIG",
@@ -418,7 +494,7 @@ static const char *const yytname[] =
# ifdef YYPRINT
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
token YYLEX-NUM. */
-static const unsigned short int yytoknum[] =
+static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267
@@ -426,14 +502,14 @@ static const unsigned short int yytoknum[] =
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const unsigned char yyr1[] =
+static const yytype_uint8 yyr1[] =
{
0, 13, 14, 14, 15, 16, 15, 17, 15, 18,
15, 19, 15, 15, 20, 20, 21, 21, 21
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const unsigned char yyr2[] =
+static const yytype_uint8 yyr2[] =
{
0, 2, 2, 0, 3, 0, 5, 0, 5, 0,
5, 0, 4, 1, 4, 0, 3, 2, 0
@@ -442,7 +518,7 @@ static const unsigned char yyr2[] =
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
STATE-NUM when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
-static const unsigned char yydefact[] =
+static const yytype_uint8 yydefact[] =
{
3, 0, 1, 13, 0, 0, 0, 0, 0, 2,
0, 0, 0, 11, 0, 5, 7, 9, 0, 4,
@@ -450,8 +526,8 @@ static const unsigned char yydefact[] =
17, 15, 16, 14
};
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yysigned_char yydefgoto[] =
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int8 yydefgoto[] =
{
-1, 1, 9, 20, 21, 22, 18, 25, 29
};
@@ -459,7 +535,7 @@ static const yysigned_char yydefgoto[] =
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
#define YYPACT_NINF -20
-static const yysigned_char yypact[] =
+static const yytype_int8 yypact[] =
{
-20, 0, -20, -20, -6, -8, -5, 1, 2, -20,
10, 11, 12, -20, 13, -20, -20, -20, 14, -20,
@@ -468,7 +544,7 @@ static const yysigned_char yypact[] =
};
/* YYPGOTO[NTERM-NUM]. */
-static const yysigned_char yypgoto[] =
+static const yytype_int8 yypgoto[] =
{
-20, -20, -20, -20, -20, -20, -20, -19, -20
};
@@ -478,14 +554,14 @@ static const yysigned_char yypgoto[] =
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -1
-static const unsigned char yytable[] =
+static const yytype_uint8 yytable[] =
{
2, 10, 26, 27, 11, 3, 4, 12, 5, 6,
7, 8, 33, 13, 14, 15, 16, 17, 19, 23,
24, 28, 30, 31, 0, 0, 0, 32
};
-static const yysigned_char yycheck[] =
+static const yytype_int8 yycheck[] =
{
0, 7, 21, 22, 12, 5, 6, 12, 8, 9,
10, 11, 31, 12, 12, 5, 5, 5, 5, 5,
@@ -494,7 +570,7 @@ static const yysigned_char yycheck[] =
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
-static const unsigned char yystos[] =
+static const yytype_uint8 yystos[] =
{
0, 14, 0, 5, 6, 8, 9, 10, 11, 15,
7, 12, 12, 12, 12, 5, 5, 5, 19, 5,
@@ -527,7 +603,7 @@ do \
yychar = (Token); \
yylval = (Value); \
yytoken = YYTRANSLATE (yychar); \
- YYPOPSTACK; \
+ YYPOPSTACK (1); \
goto yybackup; \
} \
else \
@@ -535,7 +611,7 @@ do \
yyerror (YY_("syntax error: cannot back up")); \
YYERROR; \
} \
-while (0)
+while (YYID (0))
#define YYTERROR 1
@@ -550,7 +626,7 @@ while (0)
#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(Current, Rhs, N) \
do \
- if (N) \
+ if (YYID (N)) \
{ \
(Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
(Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
@@ -564,7 +640,7 @@ while (0)
(Current).first_column = (Current).last_column = \
YYRHSLOC (Rhs, 0).last_column; \
} \
- while (0)
+ while (YYID (0))
#endif
@@ -576,8 +652,8 @@ while (0)
# if YYLTYPE_IS_TRIVIAL
# define YY_LOCATION_PRINT(File, Loc) \
fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
# else
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
@@ -604,36 +680,96 @@ while (0)
do { \
if (yydebug) \
YYFPRINTF Args; \
-} while (0)
+} while (YYID (0))
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yysymprint (stderr, \
- Type, Value); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (0)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, const YYSTYPE * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ const YYSTYPE * const yyvaluep;
+#endif
+{
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, const YYSTYPE * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ const YYSTYPE * const yyvaluep;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
/*------------------------------------------------------------------.
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
| TOP (included). |
`------------------------------------------------------------------*/
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static void
-yy_stack_print (short int *bottom, short int *top)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
#else
static void
yy_stack_print (bottom, top)
- short int *bottom;
- short int *top;
+ yytype_int16 *bottom;
+ yytype_int16 *top;
#endif
{
YYFPRINTF (stderr, "Stack now");
- for (/* Nothing. */; bottom <= top; ++bottom)
+ for (; bottom <= top; ++bottom)
YYFPRINTF (stderr, " %d", *bottom);
YYFPRINTF (stderr, "\n");
}
@@ -642,37 +778,48 @@ yy_stack_print (bottom, top)
do { \
if (yydebug) \
yy_stack_print ((Bottom), (Top)); \
-} while (0)
+} while (YYID (0))
/*------------------------------------------------.
| Report that the YYRULE is going to be reduced. |
`------------------------------------------------*/
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static void
-yy_reduce_print (int yyrule)
+yy_reduce_print (YYSTYPE *yyvsp,
+ int yyrule)
#else
static void
-yy_reduce_print (yyrule)
- int yyrule;
+yy_reduce_print (yyvsp, yyrule
+ )
+ YYSTYPE *yyvsp;
+
+ int yyrule;
#endif
{
+ int yynrhs = yyr2[yyrule];
int yyi;
unsigned long int yylno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ",
- yyrule - 1, yylno);
- /* Print the symbols being reduced, and their result. */
- for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
- YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
- YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ fprintf (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ fprintf (stderr, "\n");
+ }
}
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
- yy_reduce_print (Rule); \
-} while (0)
+ yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
@@ -706,42 +853,44 @@ int yydebug;
#if YYERROR_VERBOSE
# ifndef yystrlen
-# if defined (__GLIBC__) && defined (_STRING_H)
+# if defined __GLIBC__ && defined _STRING_H
# define yystrlen strlen
# else
/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static YYSIZE_T
-# if defined (__STDC__) || defined (__cplusplus)
yystrlen (const char *yystr)
-# else
+#else
+static YYSIZE_T
yystrlen (yystr)
- const char *yystr;
-# endif
+ const char *yystr;
+#endif
{
- const char *yys = yystr;
-
- while (*yys++ != '\0')
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
continue;
-
- return yys - yystr - 1;
+ return yylen;
}
# endif
# endif
# ifndef yystpcpy
-# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
# define yystpcpy stpcpy
# else
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static char *
-# if defined (__STDC__) || defined (__cplusplus)
yystpcpy (char *yydest, const char *yysrc)
-# else
+#else
+static char *
yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-# endif
+ char *yydest;
+ const char *yysrc;
+#endif
{
char *yyd = yydest;
const char *yys = yysrc;
@@ -767,7 +916,7 @@ yytnamerr (char *yyres, const char *yystr)
{
if (*yystr == '"')
{
- size_t yyn = 0;
+ YYSIZE_T yyn = 0;
char const *yyp = yystr;
for (;;)
@@ -802,53 +951,123 @@ yytnamerr (char *yyres, const char *yystr)
}
# endif
-#endif /* YYERROR_VERBOSE */
-
-
-
-#if YYDEBUG
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yysymprint (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE *yyvaluep;
-#endif
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
{
- /* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
+ int yyn = yypact[yystate];
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
-# ifdef YYPRINT
- if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
- switch (yytype)
- {
- default:
- break;
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
}
- YYFPRINTF (yyoutput, ")");
}
+#endif /* YYERROR_VERBOSE */
+
-#endif /* ! YYDEBUG */
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
`-----------------------------------------------*/
-#if defined (__STDC__) || defined (__cplusplus)
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static void
yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
#else
@@ -859,8 +1078,7 @@ yydestruct (yymsg, yytype, yyvaluep)
YYSTYPE *yyvaluep;
#endif
{
- /* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
+ YYUSE (yyvaluep);
if (!yymsg)
yymsg = "Deleting";
@@ -870,7 +1088,7 @@ yydestruct (yymsg, yytype, yyvaluep)
{
default:
- break;
+ break;
}
}
@@ -878,13 +1096,13 @@ yydestruct (yymsg, yytype, yyvaluep)
/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
+#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
-# else
+#else
int yyparse ();
-# endif
+#endif
#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
+#if defined __STDC__ || defined __cplusplus
int yyparse (void);
#else
int yyparse ();
@@ -909,20 +1127,24 @@ int yynerrs;
`----------*/
#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void *YYPARSE_PARAM)
-# else
-int yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-# endif
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
int
yyparse (void)
#else
int
yyparse ()
- ;
+
#endif
#endif
{
@@ -934,6 +1156,12 @@ yyparse ()
int yyerrstatus;
/* Look-ahead token as an internal (translated) token number. */
int yytoken = 0;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
/* Three stacks and their tools:
`yyss': related to states,
@@ -944,9 +1172,9 @@ yyparse ()
to reallocate them elsewhere. */
/* The state stack. */
- short int yyssa[YYINITDEPTH];
- short int *yyss = yyssa;
- short int *yyssp;
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
@@ -955,7 +1183,7 @@ yyparse ()
-#define YYPOPSTACK (yyvsp--, yyssp--)
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
YYSIZE_T yystacksize = YYINITDEPTH;
@@ -964,9 +1192,9 @@ yyparse ()
YYSTYPE yyval;
- /* When reducing, the number of symbols on the RHS of the reduced
- rule. */
- int yylen;
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
YYDPRINTF ((stderr, "Starting parse\n"));
@@ -990,8 +1218,7 @@ yyparse ()
`------------------------------------------------------------*/
yynewstate:
/* In all cases, when you get here, the value and location stacks
- have just been pushed. so pushing a state here evens the stacks.
- */
+ have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
yysetstate:
@@ -1004,11 +1231,11 @@ yyparse ()
#ifdef yyoverflow
{
- /* Give user a chance to reallocate the stack. Use copies of
+ /* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
memory. */
YYSTYPE *yyvs1 = yyvs;
- short int *yyss1 = yyss;
+ yytype_int16 *yyss1 = yyss;
/* Each stack pointer address is followed by the size of the
@@ -1036,7 +1263,7 @@ yyparse ()
yystacksize = YYMAXDEPTH;
{
- short int *yyss1 = yyss;
+ yytype_int16 *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
@@ -1071,12 +1298,10 @@ yyparse ()
`-----------*/
yybackup:
-/* Do appropriate processing given the current state. */
-/* Read a look-ahead token if we need one and don't already have one. */
-/* yyresume: */
+ /* Do appropriate processing given the current state. Read a
+ look-ahead token if we need one and don't already have one. */
/* First try to decide what to do without reference to look-ahead token. */
-
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
goto yydefault;
@@ -1118,22 +1343,21 @@ yybackup:
if (yyn == YYFINAL)
YYACCEPT;
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
/* Shift the look-ahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
- /* Discard the token being shifted unless it is eof. */
+ /* Discard the shifted token unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
+ yystate = yyn;
*++yyvsp = yylval;
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- yystate = yyn;
goto yynewstate;
@@ -1171,7 +1395,7 @@ yyreduce:
case 4:
#line 73 "parser.y"
{
- free((yyvsp[-1].s));
+ free((yyvsp[(2) - (3)].s));
;}
break;
@@ -1189,7 +1413,7 @@ yyreduce:
section_list_t *section = (section_list_t *)alloc_thing(section_list_t
, "section_list_t");
- section->name = clone_str((yyvsp[-1].s), "conn section name");
+ section->name = clone_str((yyvsp[(2) - (3)].s), "conn section name");
section->kw = NULL;
section->next = NULL;
_parser_kw = &(section->kw);
@@ -1199,7 +1423,7 @@ yyreduce:
_parser_cfg->conn_last->next = section;
_parser_cfg->conn_last = section;
_parser_kw_last = NULL;
- free((yyvsp[-1].s));
+ free((yyvsp[(2) - (3)].s));
;}
break;
@@ -1208,7 +1432,7 @@ yyreduce:
{
section_list_t *section = (section_list_t *)alloc_thing(section_list_t
, "section_list_t");
- section->name = clone_str((yyvsp[-1].s), "ca section name");
+ section->name = clone_str((yyvsp[(2) - (3)].s), "ca section name");
section->kw = NULL;
section->next = NULL;
_parser_kw = &(section->kw);
@@ -1218,7 +1442,7 @@ yyreduce:
_parser_cfg->ca_last->next = section;
_parser_cfg->ca_last = section;
_parser_kw_last = NULL;
- free((yyvsp[-1].s));
+ free((yyvsp[(2) - (3)].s));
;}
break;
@@ -1226,8 +1450,8 @@ yyreduce:
#line 115 "parser.y"
{
extern void _parser_y_include (const char *f);
- _parser_y_include((yyvsp[0].s));
- free((yyvsp[0].s));
+ _parser_y_include((yyvsp[(2) - (2)].s));
+ free((yyvsp[(2) - (2)].s));
;}
break;
@@ -1235,18 +1459,18 @@ yyreduce:
#line 130 "parser.y"
{
kw_list_t *new;
- kw_entry_t *entry = in_word_set((yyvsp[-2].s), strlen((yyvsp[-2].s)));
+ kw_entry_t *entry = in_word_set((yyvsp[(1) - (3)].s), strlen((yyvsp[(1) - (3)].s)));
if (entry == NULL)
{
- snprintf(errbuf, ERRSTRING_LEN, "unknown keyword '%s'", (yyvsp[-2].s));
+ snprintf(errbuf, ERRSTRING_LEN, "unknown keyword '%s'", (yyvsp[(1) - (3)].s));
yyerror(errbuf);
}
else if (_parser_kw)
{
new = (kw_list_t *)alloc_thing(kw_list_t, "kw_list_t");
new->entry = entry;
- new->value = clone_str((yyvsp[0].s), "kw_list value");
+ new->value = clone_str((yyvsp[(3) - (3)].s), "kw_list value");
new->next = NULL;
if (_parser_kw_last)
_parser_kw_last->next = new;
@@ -1254,29 +1478,27 @@ yyreduce:
if (!*_parser_kw)
*_parser_kw = new;
}
- free((yyvsp[-2].s));
- free((yyvsp[0].s));
+ free((yyvsp[(1) - (3)].s));
+ free((yyvsp[(3) - (3)].s));
;}
break;
case 17:
#line 155 "parser.y"
{
- free((yyvsp[-1].s));
+ free((yyvsp[(1) - (2)].s));
;}
break;
+/* Line 1267 of yacc.c. */
+#line 1496 "parser.tab.c"
default: break;
}
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-/* Line 1126 of yacc.c. */
-#line 1275 "parser.tab.c"
-
- yyvsp -= yylen;
- yyssp -= yylen;
-
-
+ YYPOPSTACK (yylen);
+ yylen = 0;
YY_STACK_PRINT (yyss, yyssp);
*++yyvsp = yyval;
@@ -1305,110 +1527,41 @@ yyerrlab:
if (!yyerrstatus)
{
++yynerrs;
-#if YYERROR_VERBOSE
- yyn = yypact[yystate];
-
- if (YYPACT_NINF < yyn && yyn < YYLAST)
- {
- int yytype = YYTRANSLATE (yychar);
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- int yysize_overflow = 0;
- char *yymsg = 0;
-# define YYERROR_VERBOSE_ARGS_MAXIMUM 5
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- int yyx;
-
-#if 0
- /* This is so xgettext sees the translatable formats that are
- constructed on the fly. */
- YY_("syntax error, unexpected %s");
- YY_("syntax error, unexpected %s, expecting %s");
- YY_("syntax error, unexpected %s, expecting %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-#endif
- char *yyfmt;
- char const *yyf;
- static char const yyunexpected[] = "syntax error, unexpected %s";
- static char const yyexpecting[] = ", expecting %s";
- static char const yyor[] = " or %s";
- char yyformat[sizeof yyunexpected
- + sizeof yyexpecting - 1
- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
- * (sizeof yyor - 1))];
- char const *yyprefix = yyexpecting;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 1;
-
- yyarg[0] = yytname[yytype];
- yyfmt = yystpcpy (yyformat, yyunexpected);
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
{
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- yyformat[sizeof yyunexpected - 1] = '\0';
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- yysize_overflow |= yysize1 < yysize;
- yysize = yysize1;
- yyfmt = yystpcpy (yyfmt, yyprefix);
- yyprefix = yyor;
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
}
+ }
- yyf = YY_(yyformat);
- yysize1 = yysize + yystrlen (yyf);
- yysize_overflow |= yysize1 < yysize;
- yysize = yysize1;
-
- if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM)
- yymsg = (char *) YYSTACK_ALLOC (yysize);
- if (yymsg)
- {
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- char *yyp = yymsg;
- int yyi = 0;
- while ((*yyp = *yyf))
- {
- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyf += 2;
- }
- else
- {
- yyp++;
- yyf++;
- }
- }
- yyerror (yymsg);
- YYSTACK_FREE (yymsg);
- }
- else
- {
- yyerror (YY_("syntax error"));
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
goto yyexhaustedlab;
- }
- }
- else
-#endif /* YYERROR_VERBOSE */
- yyerror (YY_("syntax error"));
+ }
+ }
+#endif
}
@@ -1419,14 +1572,15 @@ yyerrlab:
error, discard it. */
if (yychar <= YYEOF)
- {
+ {
/* Return failure if at end of input. */
if (yychar == YYEOF)
YYABORT;
- }
+ }
else
{
- yydestruct ("Error: discarding", yytoken, &yylval);
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
yychar = YYEMPTY;
}
}
@@ -1444,11 +1598,14 @@ yyerrorlab:
/* Pacify compilers like GCC when the user code never invokes
YYERROR and the label yyerrorlab therefore never appears in user
code. */
- if (0)
+ if (/*CONSTCOND*/ 0)
goto yyerrorlab;
-yyvsp -= yylen;
- yyssp -= yylen;
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
yystate = *yyssp;
goto yyerrlab1;
@@ -1478,8 +1635,9 @@ yyerrlab1:
YYABORT;
- yydestruct ("Error: popping", yystos[yystate], yyvsp);
- YYPOPSTACK;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
@@ -1490,7 +1648,7 @@ yyerrlab1:
*++yyvsp = yylval;
- /* Shift the error token. */
+ /* Shift the error token. */
YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
yystate = yyn;
@@ -1525,16 +1683,24 @@ yyreturn:
if (yychar != YYEOF && yychar != YYEMPTY)
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
yystos[*yyssp], yyvsp);
- YYPOPSTACK;
+ YYPOPSTACK (1);
}
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
return yyresult;
}
diff --git a/programs/starter/parser.tab.h b/programs/starter/parser.tab.h
index 1ded28fdb..b6a810f51 100644
--- a/programs/starter/parser.tab.h
+++ b/programs/starter/parser.tab.h
@@ -1,7 +1,9 @@
-/* A Bison parser, made by GNU Bison 2.1. */
+/* A Bison parser, made by GNU Bison 2.2. */
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,10 +20,18 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
@@ -56,11 +66,13 @@
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
#line 56 "parser.y"
-typedef union YYSTYPE { char *s; } YYSTYPE;
-/* Line 1447 of yacc.c. */
-#line 64 "parser.tab.h"
+{ char *s; }
+/* Line 1528 of yacc.c. */
+#line 75 "parser.tab.h"
+ YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
@@ -68,5 +80,3 @@ typedef union YYSTYPE { char *s; } YYSTYPE;
extern YYSTYPE yylval;
-
-
diff --git a/testing/INSTALL b/testing/INSTALL
index cfb9f1806..033291aa5 100644
--- a/testing/INSTALL
+++ b/testing/INSTALL
@@ -53,7 +53,7 @@ are required for the strongSwan testing environment:
* A vanilla Linux kernel on which the UML kernel will be based on.
We recommend the use of
- http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.1.tar.bz2
+ http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.3.tar.bz2
* Starting with Linux kernel 2.6.9 no patch must be applied any more in order
to make the vanilla kernel UML-capable. For older kernels you'll find
@@ -71,7 +71,7 @@ are required for the strongSwan testing environment:
* The latest strongSwan distribution
- http://download.strongswan.org/strongswan-2.8.0.tar.gz
+ http://download.strongswan.org/strongswan-2.8.1.tar.gz
3. Creating the environment
@@ -146,5 +146,5 @@ README document.
-----------------------------------------------------------------------------
-This file is RCSID $Id: INSTALL,v 1.43 2006/10/19 15:36:10 as Exp $
+This file is RCSID $Id: INSTALL,v 1.44 2007/01/14 12:17:50 as Exp $
diff --git a/testing/scripts/kstart-umls b/testing/scripts/kstart-umls
index a533fb728..21baee52c 100755
--- a/testing/scripts/kstart-umls
+++ b/testing/scripts/kstart-umls
@@ -14,7 +14,7 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
-# RCSID $Id: kstart-umls,v 1.6 2005/08/30 22:13:12 as Exp $
+# RCSID $Id: kstart-umls,v 1.7 2007/01/11 20:32:01 as Exp $
DIR=`dirname $0`
@@ -35,6 +35,12 @@ BOOTING_HOSTS=""
count_max=12
count=0
+#position of konsole window on the desktop
+x0=8
+y0=8
+dx=12
+dy=24
+
for host in $HOSTS
do
up=0
@@ -57,13 +63,16 @@ do
[ -f $UMLHOSTFS ] || die "!! uml root file system '$UMLHOSTFS' not found"
cecho-n " * Starting ${host}.."
- eval konsole -title ${host} -e "$UMLKERNEL \
+ eval konsole -title ${host} --geometry "+${x0}+${y0}" -e "$UMLKERNEL \
umid=${host} \
ubda=$UMLHOSTFS \
\$SWITCH_${host} \
mem=${MEM}M con=pty con0=fd:0,fd:1" &
cecho "done"
fi
+ let "x0+=dx"
+ let "y0+=dy"
+ sleep 15
done
if [ -z "$BOOTING_HOSTS" ]
@@ -90,14 +99,13 @@ do
exit 1
fi
- pid=`cat ~/.uml/$host/pid`
- up=`ps up $pid | grep agetty | wc -l`
+ up=`uml_mconsole $host proc net/route 2> /dev/null | grep eth0 | wc -l`
while [ $count -lt $count_max ] && [ $up -eq 0 ]
do
cecho-n "."
sleep 5
- up=`ps up $pid | grep agetty | wc -l`
+ up=`uml_mconsole $host proc net/route 2> /dev/null | grep eth0 | wc -l`
let "count+=1"
done
diff --git a/testing/scripts/start-umls b/testing/scripts/start-umls
index f51791dfa..89d9e0d81 100755
--- a/testing/scripts/start-umls
+++ b/testing/scripts/start-umls
@@ -14,7 +14,7 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
-# RCSID $Id: start-umls,v 1.5 2005/08/30 22:13:12 as Exp $
+# RCSID $Id: start-umls,v 1.6 2007/01/11 20:32:01 as Exp $
DIR=`dirname $0`
@@ -90,14 +90,13 @@ do
exit 1
fi
- pid=`cat ~/.uml/$host/pid`
- up=`ps up $pid | grep agetty | wc -l`
+ up=`uml_mconsole $host proc net/route 2> /dev/null | grep eth0 | wc -l`
while [ $count -lt $count_max ] && [ $up -eq 0 ]
do
cecho-n "."
sleep 5
- up=`ps up $pid | grep agetty | wc -l`
+ up=`uml_mconsole $host proc net/route 2> /dev/null | grep eth0 | wc -l`
let "count+=1"
done
diff --git a/testing/scripts/xstart-umls b/testing/scripts/xstart-umls
index 13c5d10a1..5983d405f 100755
--- a/testing/scripts/xstart-umls
+++ b/testing/scripts/xstart-umls
@@ -14,7 +14,7 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
-# RCSID $Id: xstart-umls,v 1.6 2005/08/30 22:13:12 as Exp $
+# RCSID $Id: xstart-umls,v 1.7 2007/01/11 20:32:01 as Exp $
DIR=`dirname $0`
@@ -35,6 +35,12 @@ BOOTING_HOSTS=""
count_max=12
count=0
+#position of xterm window on the desktop
+x0=8
+y0=8
+dx=12
+dy=24
+
for host in $HOSTS
do
up=0
@@ -57,13 +63,16 @@ do
[ -f $UMLHOSTFS ] || die "!! uml root file system '$UMLHOSTFS' not found"
cecho-n " * Starting ${host}.."
- eval xterm -title ${host} -rightbar -sb -sl 500 -e "$UMLKERNEL \
+ eval xterm -title ${host} -geometry "+${x0}+${y0}" -rightbar -sb -sl 500 -e "$UMLKERNEL \
umid=${host} \
ubda=$UMLHOSTFS \
\$SWITCH_${host} \
mem=${MEM}M con=pty con0=fd:0,fd:1" &
cecho "done"
fi
+ let "x0+=dx"
+ let "y0+=dy"
+ sleep 15
done
if [ -z "$BOOTING_HOSTS" ]
@@ -90,14 +99,13 @@ do
exit 1
fi
- pid=`cat ~/.uml/$host/pid`
- up=`ps up $pid | grep agetty | wc -l`
+ up=`uml_mconsole $host proc net/route 2> /dev/null | grep eth0 | wc -l`
while [ $count -lt $count_max ] && [ $up -eq 0 ]
do
cecho-n "."
sleep 5
- up=`ps up $pid | grep agetty | wc -l`
+ up=`uml_mconsole $host proc net/route 2> /dev/null | grep eth0 | wc -l`
let "count+=1"
done
diff --git a/testing/testing.conf b/testing/testing.conf
index 6a2db67fd..d59333cba 100755
--- a/testing/testing.conf
+++ b/testing/testing.conf
@@ -14,14 +14,14 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
-# RCSID $Id: testing.conf,v 1.57 2006/10/19 21:38:44 as Exp $
+# RCSID $Id: testing.conf,v 1.58 2007/01/14 12:18:31 as Exp $
# Root directory of testing
UMLTESTDIR=~/strongswan-testing
# Bzipped kernel sources
# (file extension .tar.bz2 required)
-KERNEL=$UMLTESTDIR/linux-2.6.18.1.tar.bz2
+KERNEL=$UMLTESTDIR/linux-2.6.18.3.tar.bz2
# Extract kernel version
KERNELVERSION=`basename $KERNEL .tar.bz2 | sed -e 's/linux-//'`
@@ -34,7 +34,7 @@ KERNELCONFIG=$UMLTESTDIR/.config-2.6.18
UMLPATCH=$UMLTESTDIR/uml_jmpbuf-2.6.18.patch.bz2
# Bzipped source of strongSwan
-STRONGSWAN=$UMLTESTDIR/strongswan-2.8.0.tar.bz2
+STRONGSWAN=$UMLTESTDIR/strongswan-2.8.1.tar.bz2
# strongSwan compile options (use "yes" or "no")
USE_LIBCURL="yes"
diff --git a/testing/tests/crl-ldap/pretest.dat b/testing/tests/crl-ldap/pretest.dat
index 0097e78f4..64fa8116b 100644
--- a/testing/tests/crl-ldap/pretest.dat
+++ b/testing/tests/crl-ldap/pretest.dat
@@ -5,4 +5,4 @@ moon::ipsec start
carol::ipsec start
carol::sleep 2
carol::ipsec up home
-carol::sleep 2
+carol::sleep 3
diff --git a/testing/tests/xauth-psk-mode-config/description.txt b/testing/tests/xauth-psk-mode-config/description.txt
new file mode 100644
index 000000000..9abe6298c
--- /dev/null
+++ b/testing/tests/xauth-psk-mode-config/description.txt
@@ -0,0 +1,11 @@
+The roadwarriors <b>carol</b> and <b>dave</b> set up a connection to gateway <b>moon</b>.
+The authentication is based on Pre-Shared Keys (<b>PSK</b>)
+followed by extended authentication (<b>XAUTH</b>) of <b>carol</b> and <b>dave</b>
+based on user names and passwords. Next <b>carol</b> and <b>dave</b> request a
+<b>virtual IP</b> via the IKE Mode Config protocol by using the
+<b>leftsourceip=%modeconfig</b> parameter.
+<p>
+Upon the successful establishment of the IPsec tunnel, leftfirewall=yes automatically
+inserts iptables-based firewall rules that let pass the tunneled traffic.
+In order to test both tunnel and firewall, <b>carol</b> and <b>dave</b> ping the client
+<b>alice</b> behind the gateway <b>moon</b>.
diff --git a/testing/tests/xauth-psk-mode-config/evaltest.dat b/testing/tests/xauth-psk-mode-config/evaltest.dat
new file mode 100644
index 000000000..15dd054a0
--- /dev/null
+++ b/testing/tests/xauth-psk-mode-config/evaltest.dat
@@ -0,0 +1,18 @@
+carol::cat /var/log/auth.log::extended authentication was successful::YES
+dave::cat /var/log/auth.log::extended authentication was successful::YES
+moon::cat /var/log/auth.log::carol.*extended authentication was successful::YES
+moon::cat /var/log/auth.log::dave.*extended authentication was successful::YES
+carol::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES
+dave::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES
+moon::ipsec status::carol.*STATE_QUICK_R2.*IPsec SA established::YES
+moon::ipsec status::dave.*STATE_QUICK_R2.*IPsec SA established::YES
+carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+dave::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
+moon::tcpdump::IP dave.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > dave.strongswan.org: ESP::YES
+alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: ICMP echo request::YES
+alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: ICMP echo reply::YES
+alice::tcpdump::IP dave1.strongswan.org > alice.strongswan.org: ICMP echo request::YES
+alice::tcpdump::IP alice.strongswan.org > dave1.strongswan.org: ICMP echo reply::YES
diff --git a/testing/tests/xauth-psk-mode-config/hosts/carol/etc/ipsec.conf b/testing/tests/xauth-psk-mode-config/hosts/carol/etc/ipsec.conf
new file mode 100644
index 000000000..ff1628fb0
--- /dev/null
+++ b/testing/tests/xauth-psk-mode-config/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthpsk
+
+conn home
+ left=PH_IP_CAROL
+ leftid=carol@strongswan.org
+ leftsourceip=%modeconfig
+ leftnexthop=%direct
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightid=@moon.strongswan.org
+ rightsubnet=10.1.0.0/16
+ auto=add
diff --git a/testing/tests/xauth-psk-mode-config/hosts/carol/etc/ipsec.secrets b/testing/tests/xauth-psk-mode-config/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 000000000..70ea1dab6
--- /dev/null
+++ b/testing/tests/xauth-psk-mode-config/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: PSK 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL
+
+: XAUTH carol "4iChxLT3"
diff --git a/testing/tests/xauth-psk-mode-config/hosts/dave/etc/ipsec.conf b/testing/tests/xauth-psk-mode-config/hosts/dave/etc/ipsec.conf
new file mode 100644
index 000000000..65c8d534e
--- /dev/null
+++ b/testing/tests/xauth-psk-mode-config/hosts/dave/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthpsk
+
+conn home
+ left=PH_IP_DAVE
+ leftid=dave@strongswan.org
+ leftsourceip=%modeconfig
+ leftnexthop=%direct
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightid=@moon.strongswan.org
+ rightsubnet=10.1.0.0/16
+ auto=add
diff --git a/testing/tests/xauth-psk-mode-config/hosts/dave/etc/ipsec.secrets b/testing/tests/xauth-psk-mode-config/hosts/dave/etc/ipsec.secrets
new file mode 100644
index 000000000..0690d9cde
--- /dev/null
+++ b/testing/tests/xauth-psk-mode-config/hosts/dave/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: PSK 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL
+
+: XAUTH dave "ryftzG4A"
diff --git a/testing/tests/xauth-psk-mode-config/hosts/moon/etc/ipsec.conf b/testing/tests/xauth-psk-mode-config/hosts/moon/etc/ipsec.conf
new file mode 100644
index 000000000..1e543b2fe
--- /dev/null
+++ b/testing/tests/xauth-psk-mode-config/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,29 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthpsk
+ xauth=server
+ left=PH_IP_MOON
+ leftid=@moon.strongswan.org
+ leftnexthop=%direct
+ leftsubnet=10.1.0.0/16
+ leftfirewall=yes
+ right=%any
+ auto=add
+
+conn carol
+ rightid=carol@strongswan.org
+ rightsourceip=PH_IP1_CAROL
+
+conn dave
+ rightid=dave@strongswan.org
+ rightsourceip=PH_IP1_DAVE
diff --git a/testing/tests/xauth-psk-mode-config/hosts/moon/etc/ipsec.secrets b/testing/tests/xauth-psk-mode-config/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 000000000..1ea69f998
--- /dev/null
+++ b/testing/tests/xauth-psk-mode-config/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,7 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+@moon.strongswan.org : PSK 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL
+
+: XAUTH carol "4iChxLT3"
+
+: XAUTH dave "ryftzG4A"
diff --git a/testing/tests/xauth-psk-mode-config/posttest.dat b/testing/tests/xauth-psk-mode-config/posttest.dat
new file mode 100644
index 000000000..530cfc7b9
--- /dev/null
+++ b/testing/tests/xauth-psk-mode-config/posttest.dat
@@ -0,0 +1,9 @@
+moon::iptables -v -n -L
+carol::iptables -v -n -L
+dave::iptables -v -n -L
+moon::ipsec stop
+carol::ipsec stop
+dave::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
+dave::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/xauth-psk-mode-config/pretest.dat b/testing/tests/xauth-psk-mode-config/pretest.dat
new file mode 100644
index 000000000..95a6be131
--- /dev/null
+++ b/testing/tests/xauth-psk-mode-config/pretest.dat
@@ -0,0 +1,12 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+dave::/etc/init.d/iptables start 2> /dev/null
+moon::rm /etc/ipsec.d/cacerts/*
+carol::rm /etc/ipsec.d/cacerts/*
+dave::rm /etc/ipsec.d/cacerts/*
+moon::ipsec start
+carol::ipsec start
+dave::ipsec start
+carol::sleep 2
+carol::ipsec up home
+dave::ipsec up home
diff --git a/testing/tests/xauth-psk-mode-config/test.conf b/testing/tests/xauth-psk-mode-config/test.conf
new file mode 100644
index 000000000..75510b295
--- /dev/null
+++ b/testing/tests/xauth-psk-mode-config/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou dave"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-d.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="alice moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol dave"
diff --git a/testing/tests/xauth-psk/description.txt b/testing/tests/xauth-psk/description.txt
new file mode 100644
index 000000000..0ac2043c2
--- /dev/null
+++ b/testing/tests/xauth-psk/description.txt
@@ -0,0 +1,9 @@
+The roadwarriors <b>carol</b> and <b>dave</b> set up a connection to gateway <b>moon</b>.
+The authentication is based on Pre-Shared Keys (<b>PSK</b>)
+followed by extended authentication (<b>XAUTH</b>) of <b>carol</b> and <b>dave</b>
+based on user names and passwords.
+<p>
+Upon the successful establishment of the IPsec tunnel, leftfirewall=yes automatically
+inserts iptables-based firewall rules that let pass the tunneled traffic.
+In order to test both tunnel and firewall, <b>carol</b> and <b>dave</b> ping the client
+<b>alice</b> behind the gateway <b>moon</b>.
diff --git a/testing/tests/xauth-psk/evaltest.dat b/testing/tests/xauth-psk/evaltest.dat
new file mode 100644
index 000000000..e1dc6b5b0
--- /dev/null
+++ b/testing/tests/xauth-psk/evaltest.dat
@@ -0,0 +1,12 @@
+carol::cat /var/log/auth.log::extended authentication was successful::YES
+dave::cat /var/log/auth.log::extended authentication was successful::YES
+moon::cat /var/log/auth.log::extended authentication was successful::YES
+carol::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES
+dave::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES
+moon::ipsec status::rw.*STATE_QUICK_R2.*IPsec SA established::YES
+carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+dave::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
+moon::tcpdump::IP dave.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > dave.strongswan.org: ESP::YES
diff --git a/testing/tests/xauth-psk/hosts/carol/etc/ipsec.conf b/testing/tests/xauth-psk/hosts/carol/etc/ipsec.conf
new file mode 100644
index 000000000..b9af32c65
--- /dev/null
+++ b/testing/tests/xauth-psk/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,21 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthpsk
+
+conn home
+ left=PH_IP_CAROL
+ leftnexthop=%direct
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightsubnet=10.1.0.0/16
+ auto=add
diff --git a/testing/tests/xauth-psk/hosts/carol/etc/ipsec.secrets b/testing/tests/xauth-psk/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 000000000..70ea1dab6
--- /dev/null
+++ b/testing/tests/xauth-psk/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: PSK 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL
+
+: XAUTH carol "4iChxLT3"
diff --git a/testing/tests/xauth-psk/hosts/dave/etc/ipsec.conf b/testing/tests/xauth-psk/hosts/dave/etc/ipsec.conf
new file mode 100644
index 000000000..f392a3e66
--- /dev/null
+++ b/testing/tests/xauth-psk/hosts/dave/etc/ipsec.conf
@@ -0,0 +1,21 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthpsk
+
+conn home
+ left=PH_IP_DAVE
+ leftnexthop=%direct
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightsubnet=10.1.0.0/16
+ auto=add
diff --git a/testing/tests/xauth-psk/hosts/dave/etc/ipsec.secrets b/testing/tests/xauth-psk/hosts/dave/etc/ipsec.secrets
new file mode 100644
index 000000000..0690d9cde
--- /dev/null
+++ b/testing/tests/xauth-psk/hosts/dave/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: PSK 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL
+
+: XAUTH dave "ryftzG4A"
diff --git a/testing/tests/xauth-psk/hosts/moon/etc/ipsec.conf b/testing/tests/xauth-psk/hosts/moon/etc/ipsec.conf
new file mode 100644
index 000000000..4c423b017
--- /dev/null
+++ b/testing/tests/xauth-psk/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,22 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthpsk
+ xauth=server
+
+conn rw
+ left=PH_IP_MOON
+ leftnexthop=%direct
+ leftsubnet=10.1.0.0/16
+ leftfirewall=yes
+ right=%any
+ auto=add
diff --git a/testing/tests/xauth-psk/hosts/moon/etc/ipsec.secrets b/testing/tests/xauth-psk/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 000000000..047d6c235
--- /dev/null
+++ b/testing/tests/xauth-psk/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,7 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+PH_IP_MOON %any : PSK 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL
+
+: XAUTH carol "4iChxLT3"
+
+: XAUTH dave "ryftzG4A"
diff --git a/testing/tests/xauth-psk/posttest.dat b/testing/tests/xauth-psk/posttest.dat
new file mode 100644
index 000000000..530cfc7b9
--- /dev/null
+++ b/testing/tests/xauth-psk/posttest.dat
@@ -0,0 +1,9 @@
+moon::iptables -v -n -L
+carol::iptables -v -n -L
+dave::iptables -v -n -L
+moon::ipsec stop
+carol::ipsec stop
+dave::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
+dave::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/xauth-psk/pretest.dat b/testing/tests/xauth-psk/pretest.dat
new file mode 100644
index 000000000..95a6be131
--- /dev/null
+++ b/testing/tests/xauth-psk/pretest.dat
@@ -0,0 +1,12 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+dave::/etc/init.d/iptables start 2> /dev/null
+moon::rm /etc/ipsec.d/cacerts/*
+carol::rm /etc/ipsec.d/cacerts/*
+dave::rm /etc/ipsec.d/cacerts/*
+moon::ipsec start
+carol::ipsec start
+dave::ipsec start
+carol::sleep 2
+carol::ipsec up home
+dave::ipsec up home
diff --git a/testing/tests/xauth-psk/test.conf b/testing/tests/xauth-psk/test.conf
new file mode 100644
index 000000000..70416826e
--- /dev/null
+++ b/testing/tests/xauth-psk/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou dave"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-d.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol dave"
diff --git a/testing/tests/xauth-rsa-fail/description.txt b/testing/tests/xauth-rsa-fail/description.txt
new file mode 100644
index 000000000..83e9d2726
--- /dev/null
+++ b/testing/tests/xauth-rsa-fail/description.txt
@@ -0,0 +1,5 @@
+The roadwarrior <b>carol</b> sets up a connection to gateway <b>moon</b>.
+The authentication is based on RSA signatures (<b>RSASIG</b>) using X.509
+certificates followed by extended authentication (<b>XAUTH</b>) based
+on user name and password. Because user <b>carol</b> presents a wrong
+XAUTH password the IKE negotation is aborted and the ISAKMP SA is deleted.
diff --git a/testing/tests/xauth-rsa-fail/evaltest.dat b/testing/tests/xauth-rsa-fail/evaltest.dat
new file mode 100644
index 000000000..0bcef388d
--- /dev/null
+++ b/testing/tests/xauth-rsa-fail/evaltest.dat
@@ -0,0 +1,4 @@
+carol::cat /var/log/auth.log::extended authentication failed::YES
+moon::cat /var/log/auth.log::extended authentication failed::YES
+carol::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::NO
+moon::ipsec status::rw.*STATE_QUICK_R2.*IPsec SA established::NO
diff --git a/testing/tests/xauth-rsa-fail/hosts/carol/etc/ipsec.conf b/testing/tests/xauth-rsa-fail/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..bfee72421
--- /dev/null
+++ b/testing/tests/xauth-rsa-fail/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthrsasig
+
+conn home
+ left=PH_IP_CAROL
+ leftnexthop=%direct
+ leftcert=carolCert.pem
+ leftid=carol@strongswan.org
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightsubnet=10.1.0.0/16
+ rightid=@moon.strongswan.org
+ auto=add
diff --git a/testing/tests/xauth-rsa-fail/hosts/carol/etc/ipsec.secrets b/testing/tests/xauth-rsa-fail/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 000000000..24506be09
--- /dev/null
+++ b/testing/tests/xauth-rsa-fail/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA carolKey.pem "nH5ZQEWtku0RJEZ6"
+
+: XAUTH carol "4iChxLT8"
diff --git a/testing/tests/xauth-rsa-fail/hosts/moon/etc/ipsec.conf b/testing/tests/xauth-rsa-fail/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..f7cf06fae
--- /dev/null
+++ b/testing/tests/xauth-rsa-fail/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthrsasig
+ xauth=server
+
+conn rw
+ left=PH_IP_MOON
+ leftnexthop=%direct
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftsubnet=10.1.0.0/16
+ leftfirewall=yes
+ right=%any
+ auto=add
diff --git a/testing/tests/xauth-rsa-fail/hosts/moon/etc/ipsec.secrets b/testing/tests/xauth-rsa-fail/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 000000000..a18e885f8
--- /dev/null
+++ b/testing/tests/xauth-rsa-fail/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA moonKey.pem
+
+: XAUTH carol "4iChxLT3"
diff --git a/testing/tests/xauth-rsa-fail/posttest.dat b/testing/tests/xauth-rsa-fail/posttest.dat
new file mode 100644
index 000000000..c6d6235f9
--- /dev/null
+++ b/testing/tests/xauth-rsa-fail/posttest.dat
@@ -0,0 +1,2 @@
+moon::ipsec stop
+carol::ipsec stop
diff --git a/testing/tests/xauth-rsa-fail/pretest.dat b/testing/tests/xauth-rsa-fail/pretest.dat
new file mode 100644
index 000000000..1b8fc3b79
--- /dev/null
+++ b/testing/tests/xauth-rsa-fail/pretest.dat
@@ -0,0 +1,4 @@
+carol::ipsec start
+moon::ipsec start
+carol::sleep 2
+carol::ipsec up home
diff --git a/testing/tests/xauth-rsa-fail/test.conf b/testing/tests/xauth-rsa-fail/test.conf
new file mode 100644
index 000000000..5442565f8
--- /dev/null
+++ b/testing/tests/xauth-rsa-fail/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS=""
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol"
diff --git a/testing/tests/xauth-rsa-mode-config/description.txt b/testing/tests/xauth-rsa-mode-config/description.txt
new file mode 100644
index 000000000..aa2b31542
--- /dev/null
+++ b/testing/tests/xauth-rsa-mode-config/description.txt
@@ -0,0 +1,11 @@
+The roadwarriors <b>carol</b> and <b>dave</b> set up a connection to gateway <b>moon</b>.
+The authentication is based on RSA signatures (<b>RSASIG</b>) using X.509 certificates
+followed by extended authentication (<b>XAUTH</b>) of <b>carol</b> and <b>dave</b>
+based on user names and passwords. Next both <b>carol</b> and <b>dave</b> request a
+<b>virtual IP</b> via the IKE Mode Config protocol by using the
+<b>leftsourceip=%modeconfig</b> parameter.
+<p>
+Upon the successful establishment of the IPsec tunnel, leftfirewall=yes automatically
+inserts iptables-based firewall rules that let pass the tunneled traffic.
+In order to test both tunnel and firewall, <b>carol</b> and <b>dave</b> ping the client
+<b>alice</b> behind the gateway <b>moon</b>.
diff --git a/testing/tests/xauth-rsa-mode-config/evaltest.dat b/testing/tests/xauth-rsa-mode-config/evaltest.dat
new file mode 100644
index 000000000..15dd054a0
--- /dev/null
+++ b/testing/tests/xauth-rsa-mode-config/evaltest.dat
@@ -0,0 +1,18 @@
+carol::cat /var/log/auth.log::extended authentication was successful::YES
+dave::cat /var/log/auth.log::extended authentication was successful::YES
+moon::cat /var/log/auth.log::carol.*extended authentication was successful::YES
+moon::cat /var/log/auth.log::dave.*extended authentication was successful::YES
+carol::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES
+dave::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES
+moon::ipsec status::carol.*STATE_QUICK_R2.*IPsec SA established::YES
+moon::ipsec status::dave.*STATE_QUICK_R2.*IPsec SA established::YES
+carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+dave::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
+moon::tcpdump::IP dave.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > dave.strongswan.org: ESP::YES
+alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: ICMP echo request::YES
+alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: ICMP echo reply::YES
+alice::tcpdump::IP dave1.strongswan.org > alice.strongswan.org: ICMP echo request::YES
+alice::tcpdump::IP alice.strongswan.org > dave1.strongswan.org: ICMP echo reply::YES
diff --git a/testing/tests/xauth-rsa-mode-config/hosts/carol/etc/ipsec.conf b/testing/tests/xauth-rsa-mode-config/hosts/carol/etc/ipsec.conf
new file mode 100644
index 000000000..751c2a29d
--- /dev/null
+++ b/testing/tests/xauth-rsa-mode-config/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,25 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthrsasig
+
+conn home
+ left=PH_IP_CAROL
+ leftsourceip=%modeconfig
+ leftnexthop=%direct
+ leftcert=carolCert.pem
+ leftid=carol@strongswan.org
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightsubnet=10.1.0.0/16
+ rightid=@moon.strongswan.org
+ auto=add
diff --git a/testing/tests/xauth-rsa-mode-config/hosts/carol/etc/ipsec.secrets b/testing/tests/xauth-rsa-mode-config/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 000000000..48fd260c1
--- /dev/null
+++ b/testing/tests/xauth-rsa-mode-config/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA carolKey.pem "nH5ZQEWtku0RJEZ6"
+
+: XAUTH carol "4iChxLT3"
diff --git a/testing/tests/xauth-rsa-mode-config/hosts/dave/etc/ipsec.conf b/testing/tests/xauth-rsa-mode-config/hosts/dave/etc/ipsec.conf
new file mode 100644
index 000000000..c97e815df
--- /dev/null
+++ b/testing/tests/xauth-rsa-mode-config/hosts/dave/etc/ipsec.conf
@@ -0,0 +1,25 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthrsasig
+
+conn home
+ left=PH_IP_DAVE
+ leftsourceip=%modeconfig
+ leftnexthop=%direct
+ leftcert=daveCert.pem
+ leftid=dave@strongswan.org
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightsubnet=10.1.0.0/16
+ rightid=@moon.strongswan.org
+ auto=add
diff --git a/testing/tests/xauth-rsa-mode-config/hosts/dave/etc/ipsec.secrets b/testing/tests/xauth-rsa-mode-config/hosts/dave/etc/ipsec.secrets
new file mode 100644
index 000000000..14f088501
--- /dev/null
+++ b/testing/tests/xauth-rsa-mode-config/hosts/dave/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA daveKey.pem
+
+: XAUTH dave "ryftzG4A"
diff --git a/testing/tests/xauth-rsa-mode-config/hosts/moon/etc/ipsec.conf b/testing/tests/xauth-rsa-mode-config/hosts/moon/etc/ipsec.conf
new file mode 100644
index 000000000..e3b2219c4
--- /dev/null
+++ b/testing/tests/xauth-rsa-mode-config/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,30 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug="control"
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthrsasig
+ xauth=server
+ left=PH_IP_MOON
+ leftnexthop=%direct
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftsubnet=10.1.0.0/16
+ leftfirewall=yes
+ right=%any
+ auto=add
+
+conn rw-carol
+ rightid=carol@strongswan.org
+ rightsourceip=PH_IP1_CAROL
+
+conn rw-dave
+ rightid=dave@strongswan.org
+ rightsourceip=PH_IP1_DAVE
diff --git a/testing/tests/xauth-rsa-mode-config/hosts/moon/etc/ipsec.secrets b/testing/tests/xauth-rsa-mode-config/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 000000000..8d41919fc
--- /dev/null
+++ b/testing/tests/xauth-rsa-mode-config/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,7 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA moonKey.pem
+
+: XAUTH carol "4iChxLT3"
+
+: XAUTH dave "ryftzG4A"
diff --git a/testing/tests/xauth-rsa-mode-config/posttest.dat b/testing/tests/xauth-rsa-mode-config/posttest.dat
new file mode 100644
index 000000000..530cfc7b9
--- /dev/null
+++ b/testing/tests/xauth-rsa-mode-config/posttest.dat
@@ -0,0 +1,9 @@
+moon::iptables -v -n -L
+carol::iptables -v -n -L
+dave::iptables -v -n -L
+moon::ipsec stop
+carol::ipsec stop
+dave::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
+dave::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/xauth-rsa-mode-config/pretest.dat b/testing/tests/xauth-rsa-mode-config/pretest.dat
new file mode 100644
index 000000000..78e2d57f8
--- /dev/null
+++ b/testing/tests/xauth-rsa-mode-config/pretest.dat
@@ -0,0 +1,9 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+dave::/etc/init.d/iptables start 2> /dev/null
+moon::ipsec start
+carol::ipsec start
+dave::ipsec start
+carol::sleep 2
+carol::ipsec up home
+dave::ipsec up home
diff --git a/testing/tests/xauth-rsa-mode-config/test.conf b/testing/tests/xauth-rsa-mode-config/test.conf
new file mode 100644
index 000000000..75510b295
--- /dev/null
+++ b/testing/tests/xauth-rsa-mode-config/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou dave"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-d.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="alice moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol dave"
diff --git a/testing/tests/xauth-rsa-nosecret/description.txt b/testing/tests/xauth-rsa-nosecret/description.txt
new file mode 100644
index 000000000..ffbb47c04
--- /dev/null
+++ b/testing/tests/xauth-rsa-nosecret/description.txt
@@ -0,0 +1,6 @@
+The roadwarrior <b>carol</b> sets up a connection to gateway <b>moon</b>.
+The authentication is based on RSA signatures (<b>RSASIG</b>) using X.509
+certificates followed by extended authentication (<b>XAUTH</b>) based
+on user name and password. Because user <b>carol</b> cannot find her
+XAUTH credentials in ipsec.secrets, the IKE negotation is aborted and the
+ISAKMP SA is deleted.
diff --git a/testing/tests/xauth-rsa-nosecret/evaltest.dat b/testing/tests/xauth-rsa-nosecret/evaltest.dat
new file mode 100644
index 000000000..ddbb3ae2d
--- /dev/null
+++ b/testing/tests/xauth-rsa-nosecret/evaltest.dat
@@ -0,0 +1,4 @@
+carol::cat /var/log/auth.log::xauth user credentials not found::YES
+moon::cat /var/log/auth.log::received FAIL status in XAUTH reply::YES
+carol::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::NO
+moon::ipsec status::rw.*STATE_QUICK_R2.*IPsec SA established::NO
diff --git a/testing/tests/xauth-rsa-nosecret/hosts/carol/etc/ipsec.conf b/testing/tests/xauth-rsa-nosecret/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..bfee72421
--- /dev/null
+++ b/testing/tests/xauth-rsa-nosecret/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthrsasig
+
+conn home
+ left=PH_IP_CAROL
+ leftnexthop=%direct
+ leftcert=carolCert.pem
+ leftid=carol@strongswan.org
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightsubnet=10.1.0.0/16
+ rightid=@moon.strongswan.org
+ auto=add
diff --git a/testing/tests/xauth-rsa-nosecret/hosts/carol/etc/ipsec.secrets b/testing/tests/xauth-rsa-nosecret/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 000000000..6a2aea811
--- /dev/null
+++ b/testing/tests/xauth-rsa-nosecret/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA carolKey.pem "nH5ZQEWtku0RJEZ6"
diff --git a/testing/tests/xauth-rsa-nosecret/hosts/moon/etc/ipsec.conf b/testing/tests/xauth-rsa-nosecret/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..f7cf06fae
--- /dev/null
+++ b/testing/tests/xauth-rsa-nosecret/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthrsasig
+ xauth=server
+
+conn rw
+ left=PH_IP_MOON
+ leftnexthop=%direct
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftsubnet=10.1.0.0/16
+ leftfirewall=yes
+ right=%any
+ auto=add
diff --git a/testing/tests/xauth-rsa-nosecret/hosts/moon/etc/ipsec.secrets b/testing/tests/xauth-rsa-nosecret/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 000000000..a18e885f8
--- /dev/null
+++ b/testing/tests/xauth-rsa-nosecret/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA moonKey.pem
+
+: XAUTH carol "4iChxLT3"
diff --git a/testing/tests/xauth-rsa-nosecret/posttest.dat b/testing/tests/xauth-rsa-nosecret/posttest.dat
new file mode 100644
index 000000000..c6d6235f9
--- /dev/null
+++ b/testing/tests/xauth-rsa-nosecret/posttest.dat
@@ -0,0 +1,2 @@
+moon::ipsec stop
+carol::ipsec stop
diff --git a/testing/tests/xauth-rsa-nosecret/pretest.dat b/testing/tests/xauth-rsa-nosecret/pretest.dat
new file mode 100644
index 000000000..f5aa989fe
--- /dev/null
+++ b/testing/tests/xauth-rsa-nosecret/pretest.dat
@@ -0,0 +1,4 @@
+carol::ipsec start
+moon::ipsec start
+carol::sleep 2
+carol::ipsec up home
diff --git a/testing/tests/xauth-rsa-nosecret/test.conf b/testing/tests/xauth-rsa-nosecret/test.conf
new file mode 100644
index 000000000..5442565f8
--- /dev/null
+++ b/testing/tests/xauth-rsa-nosecret/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS=""
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol"
diff --git a/testing/tests/xauth-rsa/description.txt b/testing/tests/xauth-rsa/description.txt
new file mode 100644
index 000000000..0cdaba1c5
--- /dev/null
+++ b/testing/tests/xauth-rsa/description.txt
@@ -0,0 +1,9 @@
+The roadwarriors <b>carol</b> and <b>dave</b> set up a connection to gateway <b>moon</b>.
+The authentication is based on RSA signatures (<b>RSASIG</b>) using X.509 certificates
+followed by extended authentication (<b>XAUTH</b>) of <b>carol</b> and <b>dave</b>
+based on user names and passwords.
+<p>
+Upon the successful establishment of the IPsec tunnel, leftfirewall=yes automatically
+inserts iptables-based firewall rules that let pass the tunneled traffic.
+In order to test both tunnel and firewall, <b>carol</b> and <b>dave</b> ping the client
+<b>alice</b> behind the gateway <b>moon</b>.
diff --git a/testing/tests/xauth-rsa/evaltest.dat b/testing/tests/xauth-rsa/evaltest.dat
new file mode 100644
index 000000000..e1dc6b5b0
--- /dev/null
+++ b/testing/tests/xauth-rsa/evaltest.dat
@@ -0,0 +1,12 @@
+carol::cat /var/log/auth.log::extended authentication was successful::YES
+dave::cat /var/log/auth.log::extended authentication was successful::YES
+moon::cat /var/log/auth.log::extended authentication was successful::YES
+carol::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES
+dave::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES
+moon::ipsec status::rw.*STATE_QUICK_R2.*IPsec SA established::YES
+carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+dave::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
+moon::tcpdump::IP dave.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > dave.strongswan.org: ESP::YES
diff --git a/testing/tests/xauth-rsa/hosts/carol/etc/ipsec.conf b/testing/tests/xauth-rsa/hosts/carol/etc/ipsec.conf
new file mode 100644
index 000000000..bfee72421
--- /dev/null
+++ b/testing/tests/xauth-rsa/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthrsasig
+
+conn home
+ left=PH_IP_CAROL
+ leftnexthop=%direct
+ leftcert=carolCert.pem
+ leftid=carol@strongswan.org
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightsubnet=10.1.0.0/16
+ rightid=@moon.strongswan.org
+ auto=add
diff --git a/testing/tests/xauth-rsa/hosts/carol/etc/ipsec.secrets b/testing/tests/xauth-rsa/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 000000000..48fd260c1
--- /dev/null
+++ b/testing/tests/xauth-rsa/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA carolKey.pem "nH5ZQEWtku0RJEZ6"
+
+: XAUTH carol "4iChxLT3"
diff --git a/testing/tests/xauth-rsa/hosts/dave/etc/ipsec.conf b/testing/tests/xauth-rsa/hosts/dave/etc/ipsec.conf
new file mode 100644
index 000000000..0f34a209a
--- /dev/null
+++ b/testing/tests/xauth-rsa/hosts/dave/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthrsasig
+
+conn home
+ left=PH_IP_DAVE
+ leftnexthop=%direct
+ leftcert=daveCert.pem
+ leftid=dave@strongswan.org
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightsubnet=10.1.0.0/16
+ rightid=@moon.strongswan.org
+ auto=add
diff --git a/testing/tests/xauth-rsa/hosts/dave/etc/ipsec.secrets b/testing/tests/xauth-rsa/hosts/dave/etc/ipsec.secrets
new file mode 100644
index 000000000..14f088501
--- /dev/null
+++ b/testing/tests/xauth-rsa/hosts/dave/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA daveKey.pem
+
+: XAUTH dave "ryftzG4A"
diff --git a/testing/tests/xauth-rsa/hosts/moon/etc/ipsec.conf b/testing/tests/xauth-rsa/hosts/moon/etc/ipsec.conf
new file mode 100644
index 000000000..f7cf06fae
--- /dev/null
+++ b/testing/tests/xauth-rsa/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=xauthrsasig
+ xauth=server
+
+conn rw
+ left=PH_IP_MOON
+ leftnexthop=%direct
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftsubnet=10.1.0.0/16
+ leftfirewall=yes
+ right=%any
+ auto=add
diff --git a/testing/tests/xauth-rsa/hosts/moon/etc/ipsec.secrets b/testing/tests/xauth-rsa/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 000000000..8d41919fc
--- /dev/null
+++ b/testing/tests/xauth-rsa/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,7 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA moonKey.pem
+
+: XAUTH carol "4iChxLT3"
+
+: XAUTH dave "ryftzG4A"
diff --git a/testing/tests/xauth-rsa/posttest.dat b/testing/tests/xauth-rsa/posttest.dat
new file mode 100644
index 000000000..530cfc7b9
--- /dev/null
+++ b/testing/tests/xauth-rsa/posttest.dat
@@ -0,0 +1,9 @@
+moon::iptables -v -n -L
+carol::iptables -v -n -L
+dave::iptables -v -n -L
+moon::ipsec stop
+carol::ipsec stop
+dave::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
+dave::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/xauth-rsa/pretest.dat b/testing/tests/xauth-rsa/pretest.dat
new file mode 100644
index 000000000..78e2d57f8
--- /dev/null
+++ b/testing/tests/xauth-rsa/pretest.dat
@@ -0,0 +1,9 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+dave::/etc/init.d/iptables start 2> /dev/null
+moon::ipsec start
+carol::ipsec start
+dave::ipsec start
+carol::sleep 2
+carol::ipsec up home
+dave::ipsec up home
diff --git a/testing/tests/xauth-rsa/test.conf b/testing/tests/xauth-rsa/test.conf
new file mode 100644
index 000000000..70416826e
--- /dev/null
+++ b/testing/tests/xauth-rsa/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou dave"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-d.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol dave"